Setting Up HTTPS with Nginx

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

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:

  • Country code
  • State
  • City
  • Organization name
  • Common name (FQDN)

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:

  • The certificate you purchased
  • The provider’s standard certificate chain that establishes trust for the certificate

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

Share this? Copy link

Feedback? Email me!

Hi! 👋 I’m Matt Brictson, a software engineer in San Francisco. This site is my excuse to practice UI design, fuss over CSS, and share my interest in open source. I blog about Rails, design patterns, and other development topics.

Recent articles

RSS
View all posts →

Open source projects

mattbrictson/nextgen

Generate your next Rails app interactively!

11
Updated 1 day ago

mattbrictson/tomo

A friendly CLI for deploying Rails apps ✨

360
Updated 1 day ago

More on GitHub →