Added on Jun 18th, 2012 and marked as config nginx ssl security

Creating a self-signed certificate

Using a self-signed SSL certificate you will get browser warnings, but if this is not a problem (if you are not using it for customers) then this might be the right choice for you.

First, let’s install the ssl-cert package:

apt-get install ssl-cert

You can now create a self-signed certificate for www.example.com:

make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/www.example.com.crt

Provide the hostname when you are asked for it.

The file that is created (/etc/ssl/private/www.example.com.crt) contains both the self-signed certificate as the private key:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDdO9GpGCBNegRF
gsh6U4K7OgRT76ki9/CelAeoA1tCksHOB29RSst/dcOLjT5/qZGP5vx7TBL32LmY
MgRHkdt/fS1cTmXkrgYIei3GRjvKZ3nLyOccXKl2PyScB2BErT/0yJOhSjFcHyOE
...
1U9fNLDGGaf3TeK7lmNLlyukH0LlxqUCdoOhOWaoWdBBVxl7PEdAXp8SBX+YIefD
i99EDgI5VO9JNe+Ypc5ts0bnSX2Bih956glUwDXjsgQ9uHFrti5RcEswmfXAe8tL
W9Cwg94j4fjUutmwwOgMbr0=
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICtDCCAZwCCQCYN3EFVsfGXDANBgkqhkiG9w0BAQUFADAcMRowGAYDVQQDExFz
c2wuc2xvd21vdGlvbi5ldTAeFw0xMjA2MTgxMDE5MzdaFw0yMjA2MTYxMDE5Mzda
MBwxGjAYBgNVBAMTEXNzbC5zbG93bW90aW9uLmV1MIIBIjANBgkqhkiG9w0BAQEF
...
/+xtmJ4JZZCp1H4RI/K4kMPThodhuGfXvL8/LHQS4iJTjFKT+nSiDYx1wJZBfDOD
NxgU9bl3JaGGnImNAfsLXzRApqGwi5bqLmaZz+qHUT1Lo7Z638q8Fy6aUypuzHJE
dVp1gQKo5DRQw6i9DesU/N/LBZjD/0nd
-----END CERTIFICATE-----

We are going to split his file in two. The part beginning with -----BEGIN PRIVATE KEY----- and ending with -----END PRIVATE KEY----- will be copied to /etc/ssl/private/www.example.com.key. The rest, beginning with -----BEGIN CERTIFICATE----- and ending with -----END CERTIFICATE-----, will be copied to /etc/ssl/certs/www.example.com.pem.

The key must be readable and writable by root only:

chmod 600 /etc/ssl/private/www.example.com.key

Remove the original file:

rm /etc/ssl/private/www.example.com.crt

SSL vhost configuration

Next we create our SSL vhost. It is not necessary to create a new SSL vhost, we can add the SSL directives to the existing configuration:

nano /etc/nginx/sites-available/www.example.com

The configuration file will probably contain a listen directive for port 80 (for IPv4, IPv6 or both). Just add a new line to also listen on port 443. Also specify the location of the certifcate’s key and certificate file:

server {
    listen   80;                            # IPv4
    listen   [::]:80;                       # IPv6

    listen   443 ssl;                       # IPv4 SSL
    listen   [::]:443 ipv6only=on ssl;      # IPv6 SSL

    # Certifcate
    ssl_certificate /etc/ssl/certs/www.example.com.pem;
    ssl_certificate_key /etc/ssl/private/www.example.com.key;

    ...
}

It is also possible to use

listen 443;
ssl on;

instead of listen 443 ssl; (might increase readability).

Creating a Certificate Signing Request (CSR)

To request a trusted certificate from a Certificate Authority (CA) such as Verisign, GeoTrust or Comodo, we must generate a certificate signing request (CSR) from our private key and send it to the CA. A trusted certificate will be created from it with which we replace our self-signed certificate.

The requests will be stored in a separate directory /etc/ssl/csr, so create it:

mkdir /etc/ssl/csr

To create the signing request from the private key we use the following command:

openssl req -new -key /etc/ssl/private/www.example.com.key -out /etc/ssl/csr/www.example.com.csr

Just provide the relevant information on the answers to generate a valid signing request. This information will be shown to the visitors of your website. The most important thing is the Common Name: this must be the domain or hostname of the vhost (www.example.com).

Running multiple SSL vhosts on one IP address with SNI

With SNI (Server Name Indication) it is possible to use more SSL certificates on the same IP address.

If your nginx supports SNI there’s no need to do anything special. Check if your nginx support SNI run nginx -V. If the following line is present, you are good:

TLS SNI support enabled

Just create a new SSL key/certificate and nginx vhost as you did before.