🥇 Install SSL certificate on nginx with spdy and PFS

How-to: Install SSL certificate, nginx with spdy and Perfect Forward Secrecy (PFS) on Debian Wheezy

In this guide we will show you how to setup an SSL certificate for use with the Nginx web server on Debian Wheezy and enable Forward Secrecy for better security.

The concept of Perfect Forward Secrecy (PFS) is the property that ensures that a session key derived from a set of long-term public and private keys will not be compromised if one of the (long-term) private keys is compromised in the future. Online systems such as IPSEC can negotiate new keys for every communication and if a key is compromised only the specific session it protected will be revealed.

Step 1 – Prerequisite
To get a more recent version of the nginx web server we use the nginx.org repository:

Add the nginx repository to /etc/apt/sources.list:

1
2
deb http://nginx.org/packages/mainline/debian/ wheezy nginx
deb-src http://nginx.org/packages/mainline/debian/ wheezy nginx
deb http://nginx.org/packages/mainline/debian/ wheezy nginx
deb-src http://nginx.org/packages/mainline/debian/ wheezy nginx

Install the GnuPG key:

1
2
wget http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
wget http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key

Update apt-get:

1
apt-get update
apt-get update

Step 1.1 – Signature Error
If you receive a signature error like W: GPG error: http://nginx.org squeeze Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY ABF5BD827BD9BF62, import the key as follows:

1
2
gpg --keyserver keyserver.ubuntu.com --recv-key ABF5BD827BD9BF62
gpg -a --export ABF5BD827BD9BF62 | apt-key add -
gpg --keyserver keyserver.ubuntu.com --recv-key ABF5BD827BD9BF62
gpg -a --export ABF5BD827BD9BF62 | apt-key add -

Step 2 – Install nginx
We do that with:

1
sudo apt-get install nginx
sudo apt-get install nginx

You should now have a working nginx web server (you may add additional modules like PHP later)

Step 3 – Create Private Key and CSR
Enter the following commands (change www.example.net to your domain name !):

1
2
sudo openssl genrsa -out /etc/ssl/private/www.example.net.key 2048
sudo openssl req -new -key /etc/ssl/private/www.example.net.key -out /etc/ssl/private/www.example.net.csr
sudo openssl genrsa -out /etc/ssl/private/www.example.net.key 2048
sudo openssl req -new -key /etc/ssl/private/www.example.net.key -out /etc/ssl/private/www.example.net.csr

The first command generates a 2048 bit private key and the second creates the certificate signing request (CSR) which we use to get our trusted SSL certificate from one of the major Certificate Authorities (Comodo, GeoTrust, Thawte or Symantec)

For the CSR, some questions are asked – please note that Common Name is the host name that should be used in the certificate (e.g. www.example.net)

We used the directory /etc/ssl/private and www.example.net as the host name – you may amend this for your installation.

You can also skip this step and create a private key and corresponding CSR using this online tool: Online CSR Tool

Step 4 – Buy a trusted SSL certificate
With the CSR created in step 3 you are now ready to apply for a trusted SSL certificate: Buy a Cheap SSL Certificate

Step 5 – Save your SSL certificate
Save the SSL certificate to /etc/ssl/certs/www.example.net.crt – do not forget to append the intermediate certificates of the certificate authority to that file.

Your file should look like this:

1
2
3
4
5
6
7
8
9
-----BEGIN CERTIFICATE-----
YOUR SERVER CERTIFICATE COMES HERE
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
CA INTERMEDIATE CERTIFICATE COMES HERE
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
CA ROOT CERTIFICATE COMES HERE
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
YOUR SERVER CERTIFICATE COMES HERE
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
CA INTERMEDIATE CERTIFICATE COMES HERE
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
CA ROOT CERTIFICATE COMES HERE
-----END CERTIFICATE-----

Step 6 – Configure nginx
Add the following to your nginx configuration, e.g. /etc/nginx/sites-available/default:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
 
    listen       192.168.1.123:443 ssl spdy;
    server_name  www.example.net;
    root         /var/www/www.example.net;
 
    ssl on;
    ssl_certificate /etc/ssl/certs/www.example.net.crt;
    ssl_certificate_key /etc/ssl/private/www.example.net.key;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1 SSLv3;
       }
server {

    listen       192.168.1.123:443 ssl spdy;
    server_name  www.example.net;
    root         /var/www/www.example.net;

    ssl on;
    ssl_certificate /etc/ssl/certs/www.example.net.crt;
    ssl_certificate_key /etc/ssl/private/www.example.net.key;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1 SSLv3;
       }

The following directives have been used:

listen – IP address/port used (we also added ssl and spdy directive)
server_name – name of your host, e.g. www.example.net
root – root directory of your host
ssl on – Turns SSL encryption on
ssl_certificate – Path to your ssl certificate (including intermediate certificates)
ssl_certificate_key – Path to your private key file
ssl-ciphers – we use a strong cipher suite that is also backward compatible back to Windows XP/IE6
ssl_prefer_server_ciphers on – specifies that server ciphers should be preferred over client ciphers
ssl_protocols – SSL protocols that the server shall accept (you may want to use TLSv1.2 TLSv1.1 TLSv1 only)

After restarting your nginx web server it should now accept SSL connections using a strong cipher suite and Perfect Forward Secrecy for increased security.

Questions ? Please contact our support team: Open Support Ticket