Let's Encrypt¶
To enable HTTPS on your website, you need to get a certificate (a type of file) from a Certificate Authority (CA). Let’s Encrypt is a CA. In order to get a certificate for your website’s domain from Let’s Encrypt, you have to demonstrate control over the domain. With Let’s Encrypt, you do this using software that uses the ACME protocol which typically runs on your web host.
How it works¶
Before issuing a certificate, Let’s Encrypt validates ownership of your domain. The Let’s Encrypt client, running on your host, creates a temporary file (a token) with the required information in it. The Let’s Encrypt validation server then makes an HTTP request to retrieve the file and validates the token, which verifies that the DNS record for your domain resolves to the server running the Let’s Encrypt client.
Installation¶
Install Let's Encrypt¶
sudo apt-get update && sudo apt-get install certbot python3-certbot-nginx
Generate SSL Certificate¶
Securize your website¶
certbot can automatically configure Nginx for SSL/TLS. It looks for and modifies the server block in your Nginx configuration that contains a server_name directive with the domain name you’re requesting a certificate for.
Important
Before proceeding, define the required variable:
BASE_URL: The actual domain name for which you are requesting an SSL/TLS certificate.
# define the domain name for the SSL/TLS certificate
BASE_URL=site.domain.fr
# check that BASE_URL is properly set
[ -z "${BASE_URL}" ] && { echo "Error: BASE_URL is not set"; exit 1; }
# generate SSL/TLS certificates using Certbot with the Nginx plug-in
sudo certbot --nginx -d ${BASE_URL}
# save Nginx configuration file to shorten command-lines
CONFIG=/etc/nginx/sites-available/${BASE_URL}
# check if the Nginx configuration has to be cleaned
clean=$(grep "options-ssl-nginx.conf" ${CONFIG} | wc -l)
# modify the Nginx configuration to enable SSL and HTTP/2
[ "${clean}" != "0" ] && sudo sed -i 's/ server_name/ listen 443 ssl http2;\n listen [::]:443 ssl http2;\n server_name/g' ${CONFIG}
# locate the first line managed by Certbot and remove the previous line
[ "${clean}" != "0" ] && begin=$(( $(sed -n '/listen 443 ssl; # managed by Certbot/=' ${CONFIG}) - 1 ))
[ "${clean}" != "0" ] && end=$(( ${begin} + 1 ))
[ "${clean}" != "0" ] && sudo sed -i "${begin},${end}d" ${CONFIG}
# remove the unneeded SSL options block managed by Certbot
[ "${clean}" != "0" ] && begin=$(sed -n '/options-ssl-nginx.conf/=' ${CONFIG})
[ "${clean}" != "0" ] && end=$(( $(sed -n '/^}/=' ${CONFIG} | tail -n 1) - 1 ))
[ "${clean}" != "0" ] && sudo sed -i "${begin},${end}d" ${CONFIG}
# clean the `ssl_certificate` directives
line=$(( $(sed -n '/ssl_certificate /=' ${CONFIG}) - 1 ))
[ -n "$(sed -n "${line}p" ${CONFIG} | tr -d '\n')" ] && line=$(( ${line} + 1 )) && sudo sed -i "${line}i \\"$'\n' ${CONFIG}
line=$(( $(sed -n '/ssl_certificate_key/=' ${CONFIG}) + 1 ))
[ -z "$(sed -n "${line}p" ${CONFIG} | tr -d '\n')" ] && sudo sed -i "${line}d" ${CONFIG}
sudo sed -i 's/[ ]*ssl_certificate/ ssl_certificate/g' ${CONFIG}
# display the final Nginx configuration file for verification
cat ${CONFIG}
# test the Nginx configuration and restart the service
sudo nginx -t && sudo service nginx restart
Important
Open port 80 and 443 on router and check that everything is fine:
https://www.ssllabs.com/ssltest/analyze.html?d=site.domain.fr.
Improve security¶
sudo sed -i 's/ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";/ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";/g' /etc/letsencrypt/options-ssl-nginx.conf
Tip
These commands disable the old protocols and ciphers.
Renew certificates automatically¶
Let’s Encrypt certificates expire after 90 days. We encourage you to renew your certificates automatically. Here we add a cron job to an existing crontab file to do this.
Check if renewal works
sudo certbot renew --dry-run
sudo certbot renew --force-renewal
Update crontab
Add the certbot command to run daily. In this example, we run the command every day at noon.
The command checks to see if the certificate on the server will expire within the next 30 days, and renews it if so.
The --quiet directive tells certbot not to generate output.
crontab -e
0 12 * * * /usr/bin/certbot renew --quiet