Here's how I set up a tiny Nginx/Rails server that uses HTTPS via a Let's Encrypt issued certificate.
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.
- Add A Record for with your public IPv4 address
- Add AAAA Record for with your public IPv6 address
- Add the www. counterparts as well
- Add swap
- Enable IPv6
- Ensure packages are up to date
apt-get update
The specific image I am using ships with an outdated Python version, which we need to update:
- Upgrade setuptools with
apt-get upgrade python-setuptools
- Then follow these setup instructions
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
This is where the magic happens!
service nginx stop
./letsencrypt-auto certonly --rsa-key-size 4096 -d <YOURDOMAIN> -d www.<YOURDOMAIN>
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:
- https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
- https://gist.github.com/StefanWallin/5690c76aee1f783c3d57
You can check your SSL rating at:
Now point your browser to https://<YOURDOMAIN>, sit back and relax!