Skip to content

Instantly share code, notes, and snippets.

@padde
Last active July 10, 2018 15:07
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save padde/a2fa38a5686af5ba27e6 to your computer and use it in GitHub Desktop.
Save padde/a2fa38a5686af5ba27e6 to your computer and use it in GitHub Desktop.
Let's Encrypt with Nginx

Let's Encrypt with Nginx

Here's how I set up a tiny Nginx/Rails server that uses HTTPS via a Let's Encrypt issued certificate.

https://letsencrypt.paddd.de/

Server

I use the smallest DigitalOcean droplet (512 MB) here, which is built from the "Ubuntu Ruby on Rails on 14.04" image provided by them.

DNS Configuration

  • Add A Record for with your public IPv4 address
  • Add AAAA Record for with your public IPv6 address
  • Add the www. counterparts as well

Basic Server Setup

The specific image I am using ships with an outdated Python version, which we need to update:

Let's Encrypt

Install Let's Encrypt Client

Let's Encrypt will be available as apt package, but as it is still in beta, we need to fetch it from Github for now

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

Obtain a Certificate

This is where the magic happens!

service nginx stop
./letsencrypt-auto certonly --rsa-key-size 4096 -d <YOURDOMAIN> -d www.<YOURDOMAIN>

Nginx configuration

Nginx support for auto-configuration is not there yet, so we're doing it manually. First, add re-usable ssl config options by creating /etc/nginx/ssl.conf with the following contents:

# Don't use the insecure SSLv2 and SSLv3 protocols
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

# Prefer these cipher suites, with support for older IE versions
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

# Session handling
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
keepalive_timeout 70;

# Diffie-Hellman Ephemeral Parameters, see below for how to generate those
# ssl_dhparam /etc/ssl/certs/dhparam.pem;

# HTTP Strict Transport Security
# Tells browsers to exclusively use HTTPS for future requests
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';

# HSTS Preloading
# Use this instead if you want to ship browsers with the info that your entire
# site is HTTPS only. Submit your domain at https://hstspreload.appspot.com
# add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

Edit /etc/nginx/sites-enabled/rails and replace

listen 80;
server_name _;

with

listen [::]:443 ipv6only=off;
server_name <YOURDOMAIN> www.<YOURDOMAIN>;

ssl on;
include /etc/nginx/ssl.conf;
ssl_certificate /etc/letsencrypt/live/<YOURDOMAIN>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<YOURDOMAIN>/privkey.pem;

you can also redirect all HTTP requests to HTTPS (and www to non-www) with

server {
    listen [::]:80 ipv6only=off;
    server_name <YOURDOMAIN> www.<YOURDOMAIN>;
    return 301 https://$server_name$request_uri;
}

server {
    listen [::]:443 ipv6only=off;
    
    server_name <YOURDOMAIN> www.<YOURDOMAIN>;
    
    if ($host = www.$server_name) {
        return 301 https://$server_name$request_uri;
    }
        
    # ...
}

Then start nginx back up

service nginx start

Get an A+ rating by generating custom DH parameters. This may take some hours to generate, since we are using a length of 4096 bit.

cd /etc/ssl/certs/
openssl dhparam -out dhparam.pem 4096

and uncomment the following line /etc/nginx/ssl.conf

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Make sure to restart your nginx server after that

service nginx restart

You can find more info on configuring SSL/TLS with Nginx on the following sites:

You can check your SSL rating at:

Now point your browser to https://<YOURDOMAIN>, sit back and relax!

@tuannh99
Copy link

tuannh99 commented Feb 9, 2016

Nice config.

I also recommend everyone to generate and update your SSL configuration following Mozilla's generator:
https://mozilla.github.io/server-side-tls/ssl-config-generator/

It provides ready-to-use configuration for your webserver of choice, and follows best practice.

It provides ready-to-use configuration for your webserver of choice, and follows best practice.

Thank @padde.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment