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.
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.
- Go to dnschecker.org.
- Enter your domain name for the "A" record
- Verify if the IP (version 4) of your DNS Zone matches your server IP
- 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
- Go to www.ssllabs.com/ssltest
- Enter your domain name
- See if you get an A+
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.