Get an A+ with Qualys SSL Labs nginx and Let's Encrypt

Follow this guide to configure your nginx HTTP server with a free Let's Encrypt certificate and get an A+ on Qualys SSL Labs' test.

Get an A+ with Qualys SSL Labs nginx and Let's Encrypt
Date published
Last modificationApr 22, 2018

This guide has been tested on debian 9 (stretch) and applied to this website.

Check your DNS records

Let's Encrypt needs to verify if you are the owner of the domain name you want a certificate for. To do so, Let's Encrypt will verify the DNS Zone of your domain name matches the IP of the server were you are trying to install the certificate from.

  1. Go to dnschecker.org.
  2. Enter your domain name for the "A" record
  3. Verify if the IP (version 4) of your DNS Zone matches your server IP
  4. Verify as well the record for the IP version 6 (record "AAAA"). If the IP v4 and v6 are not pointing to the same server, it's not going to work. (If you don't have or don't want to use IPv6, skip that)

Connect with SSH to your server

Follow the procedure of your provider. Log in as root.

Install Let's Encrypt

Let's Encrypt offers a tool called certbot that will help us install the certificate.

apt-get install certbot

nginx with HTTP

We will create the following snippet that we can include in any website hosted by our nginx :

nano /etc/nginx/snippets/http-letsencrypt.conf
location ~ /.well-known {
        allow all;
        root /var/www/letsencrypt;
}

location / {
    return 301 https://$server_name$request_uri;
}

The first location is for the ACME challenge

The second location is for redirecting any request from http to https.

Create the folder /var/www/letsencrypt :

mkdir /var/www/letsencrypt
chown www-data:www-data /var/www/letsencrypt
chmod 775 /var/www/letsencrypt

Create or configure your website on nginx

Create or edit the configuration of your new website :

nano /etc/nginx/sites-available/example
server {
    listen       80;
    listen [::]:80;
    server_name  example.com www.example.com;

    include /etc/nginx/snippets/http-letsencrypt.conf;
}

If you are creating a new website make it available :

ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/example

Reload nginx :

systemctl reload nginx

ACME Challenge

Let's Encrypt with certbot will try to certify that you own the domain name and it is connected to the server where you are from.

The ACME challenge will create on your server a file that Let's Encrypt will try too reach from their servers.

If your nginx is configured for http, let's try to issue the certificate with certbot.

First try

When you are ready, try certbot without issuing a certificate (change example.com with your domain) :

certbot certonly --webroot -w /var/www/letsencrypt -d example.com --dry-run

Issue real certificate

certbot certonly --webroot -w /var/www/letsencrypt -d example.com

If everything is fine your certificate is ready to be used.

Renew automatically

Create the file :

nano /root/letsencrypt.sh
#!/bin/bash
systemctl reload nginx

Make it executable :

chmod +x /root/letsencrypt.sh

Add a cron :

cron -e

Add the following line :

0 0 28 * * certbot renew --noninteractive --renew-hook /root/letsencrypt.sh

It will be executed the 28th of each month at midnight.

nginx with HTTPS

dhparams

First we will generate the diffie-hellman parameters. It's a method to exchange keys in cryptography.

openssl dhparam -out /etc/nginx/ssl/dhparams.pem 4096

Create the file https-letsencrypt.conf

nano /etc/nginx/snippets/http-letsencrypt.conf
ssl on;

ssl_session_timeout 24h;
ssl_session_cache shared:SSL:10m;

ssl_dhparam /etc/nginx/ssl/dhparams.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
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-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;

add_header Strict-Transport-Security max-age=31536000;

Edit your the configuration file of your website :

nano /etc/nginx/sites-available/example
server {
    listen       80;
    listen [::]:80;
    server_name  example.com www.example.com;

    include /etc/nginx/snippets/http-letsencrypt.conf;
}


server {
        listen 443;
        listen [::]:443;

        include /etc/nginx/snippets/https-letsencrypt.conf;

        server_name example.com www.example.com;

        ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

        root /var/www/example.com/public;

        index index.php index.html index.htm;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
}

Don't forget to change every "example.com" with your domain name or folder name. You have to change this code for the specificity of your website.

Reload nginx :

systemctl reload nginx

Test with Qualys SSL Labs

  1. Go to www.ssllabs.com/ssltest
  2. Enter your domain name
  3. See if you get an A+

New Boss' Apps got an A+ at Qualys SSL Labs

This article has been inspired by :


That would be lovely if you would consider sharing on the social media or adding a link on your website.