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.
-
Many thanks to Bjørn Johansen for his article: Optimizing HTTPS on Nginx. ↩