Setting Up HTTPS with Nginx

My workflow for purchasing an SSL certificate and installing it in Nginx.

This article is out of date. My new recommendations for setting up HTTPS with Nginx can be found here: A Better Way to Purchase and Install SSL Certificates.

I firmly believe all apps should be served with HTTPS, and Nginx on top of Ubuntu 14.04 LTS is my web server of choice. Here’s my workflow for purchasing and installing the necessary certificate. Most of these steps are also automated as part of my capistrano-mb project.

1 Generate the key and CSR on the server

# as root
cd /etc/ssl
openssl req -new -newkey rsa:2048 -nodes -keyout myapp.key -out myapp.csr

The openssl command will ask for the following CSR data:

The most important piece of information is the common name: this must exactly match the hostname you’re securing via SSL. For example: www.myapp.com.

The SSL certificate provider (see step 2, below) will automatically secure the hostname both with and without the www. prefix, which is a nice bonus. For this to work, the www. version of the domain name must be used when generating the CSR.

2 Purchase the SSL certificate

Next, use the CSR to purchase and generate a certificate. I recommend rapidsslonline.com, which offers one-year certificates for $17.95 USD.

The provider will ask you to prove that you own the domain name in question by sending a confirmation email to admin@<domain> or to the administrative contact listed in the WHOIS entry.

3 Install the certificate

Once you’ve confirmed the email, the certificate provider sends two files:

Paste the contents of both files (the purchased certificate first, followed by the chain) into /etc/ssl/myapp.crt. Lock the files down so only root can read them:

chmod 600 /etc/ssl/myapp.*

Finally, set up Nginx1 to use the certificate along with the key generated in step 1:

server {
  listen 443 default deferred;
  server_name _;

  ssl on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:!ADH:!AECDH:!MD5;
  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_certificate /etc/ssl/myapp.crt;
  ssl_certificate_key /etc/ssl/myapp.key;

  # the rest of your server config...
}

Restarting Nginx completes the installation.

# as root
service nginx restart

Troubleshooting

The version of Nginx I use is not very forthcoming with an explanation when misconfigured. In the case that service nginx restart doesn’t seem to do anything (it should print “OK”), or you otherwise see odd behavior, check the logs:

tail /var/log/nginx/error.log

What’s next?

This article just scratches the surface of setting up SSL and Nginx. If you are following along by setting up your own HTTPS site, try testing it using the Qualys SSL Labs SSL Server Test. This will give you some pointers on how to further improve the security of your app.

For an all-in-one Rails application template that includes capistrano recipes for setting up HTTPS with Nginx, check out my rails-template project.


  1. Many thanks to Bjørn Johansen for his article: Optimizing HTTPS on Nginx