This past week I finally got around to setting up SSL certificates using Let’s Encrypt. Let’s Encrypt is an open certificate authority that provides free SSL/TLS certificates. It’s goal is to make creating, renewing and using SSL certs painless.
And it most certainly is. I was expecting a lot more hassle to set up all this, but it was really easy to do.
Certbot is a Let’s Encrypt client that helps setting up a certificate by obtaining and installing it on your servers. There are many more clients out there, but certbot is the recommended one to use.
I simply installed certbot using
but if your OS has no package for it yet, there’s always the manual way.
Creating a certificate
Certbot has a number of plugins that can be used to create and install a certificate on a server. I chose the
webroot plugin which only gets the certificate for me and leaves the webserver configuration up to me.
sudo certbot --text --renew-by-default --agree-tos --webroot \
--email email@example.com \
--domains domain.tld,www.domain.tld \
--webroot-path /path/to/site/public \
This will create the certificate and it’s private key in the
The next step is to configure nginx by enabling SSL, providing the paths to the certificate and the private key, and which protocols and ciphers to use. I added these to the
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
After restarting nginx, you should be able to load up your site through
https. Just remember to allow traffic on the 443 port:
sudo firewall-cmd -add-service=https --permanent
sudo firewall-cmd reload
To further harden the Diffie-Helman key exchange, create new parameters for it using
sudo mkdir /etc/nginx/ssl
sudo openssl dhparam -out dhparams.pem 2048
I told nginx to use it by adding it to the same
server block where I set up the SSL configuration:
I also did some SSL optimizations and enabled Strict Transport Security:
add_header Strict-Transport-Security max-age=31536000;
This blog post explains HTTP Strict Transport Security nicely.
All this and my website gets an A+ rating on the Qualys SSL Server Test.
Enable OCSP stapling
Thanks to Goran Jurić for pointing out to enable OCSP stapling. I did so by adding this to the nginx
According to the nginx documentation the
ssl_trusted_certificate directive is needed only when the
ssl_certificate file does not contain intermediate certificates, but the
fullchain.pem created by Let’s Encrypt does contain them, so I’m skipping that.
To test whether OCSP stapling is enabled, reload nginx, and from a local terminal run the following:
openssl s_client -connect domain.tld:443 -status
The output should have something like:
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
Version: 1 (0x0)
Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3