Let’s Encrypt + Nginx: Three Months Into Beta

Revisiting the Experimental Nginx Plugin

Nginx Plugin During Early Beta

When Let’s Encrypt started their closed beta, their documentation warned that their Nginx plugin was experimental. Using it as the authenticator to obtain certificates seemed to work, but using it as the installer would almost certainly guarantee that your Nginx configuration would become a jumbled mess. But that automated installation isn’t useful for everyone, especially with the myriad of ways Nginx configuration files can be structured. What was really important was that Let’s Encrypt was successfully issuing free trusted SSL certificates through their automated system.

letsencrypt 0.4.0.dev0

Three months later, solidly into public beta and with certificates in need of renewal, I decided to give the Nginx plugin another try. Since letsencrypt-auto doesn’t include the Nginx plugin, I ended up running the client in developer mode.

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto-source/letsencrypt-auto --os-packages-only

Activating the virtual env will allow you to run the client with just letsencrypt. One annoyance was that unlike the letsencrypt-auto wrapper that will ask for elevated privileges when needed, the client itself would just error and stop when attempting to write to directories like /var/log/letsencrypt or /etc/letsencrypt.

sudo -s
source ./venv/bin/activate

Your prompt should now be prefixed by (venv)


Nginx 1.9.10 with Default Site Configuration

To keep things simple, I started with a fresh install of Nginx (1.9.10) and used the single server block provided by /etc/nginx/conf.d/default.conf. To have the Nginx plugin act as both authenticator and installer just include --nginx.

letsencrypt --nginx -d rudeotter.com --email jb@rudeotter.com--agree-tos

If successful, you’ll be asked whether you’d like to make your site HTTPS only or if it should be available via HTTP as well. I chose Secure.

│ Please choose whether HTTPS access is required or optional.          │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │    Easy    Allow both HTTP and HTTPS access to these sites       │ │
│ │    Secure  Make all requests redirect to secure HTTPS access     │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│                     <  OK  >           < Cancel >                    │
 - If you lose your account credentials, you can recover through
   e-mails sent to jb@rudeotter.com.
 - Congratulations! Your certificate and chain have been saved at
   Your cert will expire on 2016-05-07. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Optionally Check the Certificate and Key

The certificate was successfully created (almost) effortlessly and placed in /etc/letsencrypt/live/yourdomain/. The certificate and key can be checked from the command line.

openssl x509 -in cert.pem -text -noout
openssl rsa -in privkey.pem -check

Installation Results

The installation, however, didn’t really do what I expected. Rather than modify the server block configuration in default.conf, it added a server block to nginx.conf. This works just fine but you may want to move blocks to your site-specific file and do some additional customization anyway.

    server {
        server_name rudeotter.com;
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/rudeotter.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/rudeotter.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_trusted_certificate /etc/letsencrypt/live/rudeotter.com/chain.pem;
        ssl_stapling on;
        ssl_stapling_verify on;

        if ($scheme != "https") {
            return 301 https://$host$request_uri;

This configuration scores an A on the Qualys SSL Server Test after generating DH parameters and specifying their location in ssl_dhparam. My preference is to stick with Mozilla’s SSL Config Generator.

Skipping Installation: Generate Certificates Only

The Nginx plugin worked perfectly for me as my authenticator and didn’t require temporarily stopping Nginx to use the standalone. That alone is enough to make me use it for creating and renewing my certificates. Luckily, it’s really easy to use the plugin for certificate generation only.

letsencrypt certonly --nginx -d rudeotter.com --email jb@rudeotter.com--agree-tos

Nginx SSL Configuration using Let’s Encrypt Certificates

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/letsencrypt/live/rudeotter.com/fullchain.pem;;
    ssl_certificate_key /etc/letsencrypt/live/rudeotter.com/privkey.pem;;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_dhparam /etc/nginx/dhparam.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security max-age=15768000;

    ssl_stapling on;
    ssl_stapling_verify on; 

    ssl_trusted_certificate /etc/letsencrypt/live/rudeotter.com/chain.pem;

    resolver valid=86400;
    resolver_timeout 10;

Leave a Reply

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