Spaghetti Programming

Securing Nginx with SSL

SSL

These are some notes on setting up https in Nginx, but they should be nearly identical for other web servers like Apache, etc.

General SSL Certificate Creation

If you want to get a real SSL certificate that doesn't sound all kinds of alarms when users visit your site then you will have to use a certificate provided by a certificate authority (CA). The CA will need a certificate signing request (CSR) to issue you a certificate and this CSR must also be signed by your key. We can use this command to generate a new key and the signing request at the same time:

openssl req -out certificate_signing_request.csr -new -newkey rsa:4096 -nodes -keyout key_file.key

Once you have the key and the CSR you can begin the ordering process with your CA. They will need to know the contents of the CSR file generated from the previous command (certificate_signing_request.csr in the above example).

If you are ok with your site throwing up warnings when someone accesses it via https, then you don't need to pay for a certificate from a CA and can instead sign the certificate yourself. This is known as a self signed certificate. This command will generate a new key and a self signed certificate:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout key_file.key -out certificate.crt

Checking Keys and Certificates

Once you generate the certificate file (certificate.crt), or obtain one from a certificate authority, you can check its contents with the following command:

openssl x509 -in certificate.crt -text -noout

To verify the contents of your key file (not so useful, but included for completeness):

openssl rsa -in key_file.key -check

Generate New Signing Request from Existing Key

If you have a single web server that hosts multiple SSL enabled sites, you can generate a new certificate signing request from an existing key:

openssl req -out new_certificate_signing_request.csr -key key_file.key -new

Configuring Nginx Virtual Host to use SSL

nginx

The certificate authority will send you the certificate as well as any intermediate certificates needed. Nginx wants the intermediate certificates in the same file as the certificate for your server. Take the contents of the SSL certificate file from your CA and save them in certificate.crt. The order of the intermediate certificates matters!

Your server must present its own certificate first and then walk up the chain of trust until it reaches the root certificate authority. This means that your certificate needs to be at the top of the file followed by the certificate that issued it. The second certificate should be followed by the certificate that issued that one and so on until the root is reached. To check the order of the certificate hierarchy when you are given a zip file of certificates you can use the openssl command to check the issuer and the subject of each certificate.

 for i in *.crt; do echo $i; openssl x509 -text -noout -in $i 2>&1| \
 egrep -i "issuer:|subject:" ; done

This will give some output like:

 AddTrustExternalCARoot.crt
    Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
    Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
 COMODORSAAddTrustCA.crt
    Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
    Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority
 COMODORSADomainValidationSecureServerCA.crt
    Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority
    Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Domain Validation Secure Server CA
 STAR_spaghettiprogramming_com.crt
    Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Domain Validation Secure Server CA
    Subject: OU=Domain Control Validated, OU=EssentialSSL Wildcard, CN=spaghettiprogramming.com

These happen to be in the correct order when the files are sorted by their name, but that may not always be the case. You can see the relationship between issuer and subject through the chain of trust and in this example simply concatenating the files in reverse order of this output will produce the correct certificate file for nginx.

If you are using a self signed certificate then there is no need to use any intermediate certs and you can simply use the self signed certificate as is.

A sample Nginx virtual host file for an SSL enabled site might look something like this:

server {
  listen   443 ;
  server_name  *.domain.com;
  ssl on;
  ssl_certificate /opt/nginx/ssl/domain.com/certificate.crt;
  ssl_certificate_key /opt/nginx/ssl/domain.com/key_file.key;
  access_log  /var/log/nginx/domain.access.log;
  root /var/www/domain/current/public;
  client_max_body_size 20M;
  passenger_enabled on;
}