HTTP/SSL Made Easy With FreeBSD + Nginx + Certbot!


Recently at Hypatia Software Organization we decided to enhance the security of our servers by improving our HTTPS (encryption) support. Use of strong encryption enhances the privacy of our members, volunteers, donors, as well as the Hypatia community at large. In the past deploying strong HTTPS to a web-server was a costly and time-consuming process that required buying an X.509 certificate from a Certificate Authority (CA). This has changed with the creation of the Let’s Encrypt CA, a CA that provides cost free X.509 certificates via a public API, as well as Certbot a client that utilizes the this API to turn certificate generation into a simple process that anyone running a web-server can do!

logo-fullNow that the basics are out of the way, lets get down to how to deploy Certbot on your web-server to obtain a cost free X.509 certificate for yourself! In this example we will be using FreeBSD 10.2-RELEASE using Nginx 1.8.1 as a web-server. The process is fairly simple and requires at least basic understanding of the shell.  In the examples we provide we are using ZSH as our shell and the prompt will be denoted by a “%” character.  Before you can get started you will need a valid domain name pointed to the server that you wish to obtain a certificate with. Additionally you will need to install git and python, you can install them with the following command:

% pkg install git python

Once you have the required packages, the rest is easy. First lets clone the Certbot repository from Github:

% git clone

Now all that’s left to do is obtain our Certificate, Certbot will automatically install any system dependencies and create a Python Virtual Environment to manage any Python packages it requires. In this example we will be requesting a certificate for the following domains:, This process will take several steps that will be noted with comments (Text after the “#” character):

# Change directories to the freshly cloned certbot repository
 % cd certbot
 # Stop Nginx (nothing can be using port 443 when Certbot runs)
 % service nginx stop
 # Obtain our certificate!
 % ./letsencrypt-auto --debug certonly --standalone -d -d
 # Start our web-server back up:
 % service nginx start

And that’s it! You will now have a certificate in /etc/letsencrypt/live/, where is the first domain listed in the above letsencrypt-auto command.

One more suggested security enchantment you can implement for your users is generating your own strong and unique Diffie-Hellman (DH) Key which is used for exchanging cryptographic keys between the client (web-browser) and server. This can easily be done with the following commands which will yield a 4096-bit DH key:

% cd /usr/local/etc/ssl/
% openssl dhparam -out dhparams.pem 4096

Now that you have a new X.509 certificate I’m sure you would like to deploy it to your web-server. Here is our basic Nginx configuration. We store it in a separate file and include it in our /usr/local/etc/nginx/nginx.conf file. By doing this it makes it easy to include the same settings and headers in all of our HTTPS virtual hosts. While this could be written a bit more clean we find it works very well. To include the common file, you will need to add the line “include ssl_common.conf;” to your configuration file, it should look something like this:

http {
      server {
              listen 443 ssl;
              include ssl_common.conf;

Here is the contents of our /usr/local/etc/nginx/ssl_common.conf file:

# Thanks to for providing a great reference! Please check out their site
# to make sure your SSL Configuration is up to date with current standards! Be aware that in this
# example we use a slightly liberal cipherlist to allow for older browsers on older devices, Eg.
# IE8, android 2.4, etc
# Enable Perfect Forward Secrecy (PFS)
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;
# Disable SSLv2 and SSLv3 (BEAST and POODLE attacks)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Enable our strong DH Key
ssl_dhparam /usr/local/etc/ssl/dhparams.pem;
# Cipher-list for PFS.
ssl_ecdh_curve secp384r1;
# Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Requires nginx >= 1.5.9
ssl_stapling on;
# Requires nginx >= 1.3.7
ssl_stapling_verify on;
# Requires nginx => 1.3.7
resolver valid=300s;
resolver_timeout 5s;
# HSTS Support
add_header Strict-Transport-Security "max-age=63072000;includeSubdomains; preload";
# These headers can break applications, be careful!
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff

After making these changes you must restart your web-server:

% service nginx restart

Now you should have HTTPS running with a certificate from the Let’s Encrypt CA! If you would like to test your server for configuration errors, I strongly recommend using to test your server configuration. If you follow this guide and checked for any changes, you should get an A+ on SSLabs’ test. Good luck and happy hacking!a-plus

Further reading

Leave a Reply

Your email address will not be published. Required fields are marked *