Running a secure web site provides a better experience for anyone using your site. These days (2018), search engines also favor web sites that use SSL/HTTPS, so utilizing SSL is an important aspect of SEO. But buying a new SSL certificate every couple of years can get expensive, particularly if you run multiple web sites or if you want to buy a wildcard certificate to protect all your subdomains like mail.mywebsite.com and blog.mywebsite.com.
Fortunately, the Let’s Encrypt project is offering free SSL certificates so you don’t have to buy new certificates every year or two. Even better, the Let’s Encrypt certbot utility largely automates certificate management — including renewal — so you can focus on updating your web site rather than configuring it.
Let’s get started! We’re using Ubuntu 16.04 with Nginx.
Step 1: Install the certbot utility
root@ubuntu:/# apt-get install software-properties-common root@ubuntu:/# add-apt-repository ppa:certbot/certbot root@ubuntu:/# apt-get update root@ubuntu:/# apt-get install certbot python-certbot-nginx root@ubuntu:/# certbot --version certbot 0.22.2
Step 2: Ensure certbot’s settings file is correct
root@ubuntu:/# vi /etc/letsencrypt/cli.ini
# Ensure the RSA key size is 4096 rsa-key-size = 4096
Step 3: Grab a new certificate for your web site
root@ubuntu:/# certbot --nginx certonly -d www.mywebsite.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Obtaining a new certificate Performing the following challenges: tls-sni-01 challenge for www.mywebsite.com Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/www.mywebsite.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/www.mywebsite.com/privkey.pem Your cert will expire on 2018-07-17. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le root@ubuntu:/# certbot certificates Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Found the following certs: Certificate Name: www.mywebsite.com Domains: www.mywebsite.com Expiry Date: 2018-07-17 18:18:57+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/www.mywebsite.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/www.mywebsite.com/privkey.pem
Note: If you omit the ‘certonly’ option, certbot will download your certificate and then add the new key and certificate paths to your web site’s configuration file (/etc/nginx/sites-available/www.mywebsite.com). If you use the certonly option, as above, certbot will download your new cert but leave your site config untouched. This is the method I prefer.
Step 4: Set up your web site in Nginx
Now you need to make your new private key and certificate available to Nginx. To do this, edit your web site’s configuration file (/etc/nginx/sites-available/www.mywebsite.com) and set up a server block with your SSL settings. Be sure to include the paths to your new key and certificate provided by certbot above. Note that the ssl_ciphers and ssl_dhparam entries here are designed to get you an A on the SSL Labs web server test.
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name mywebsite.com; ssl_certificate /etc/letsencrypt/live/www.mywebsite.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.mywebsite.com/privkey.pem; 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_dhparam /etc/ssl/certs/dhparams.pem; }
To force a redirect from http to https, you can place a server block like this at the top of your config file:
server { listen 80; listen [::]:80; server_name www.mywebsite.com; return 301 https://www.mywebsite.com$request_uri; }
Step 5: Set up autorenewal
By default, certbot will run every day to check for certificates that need renewal. When a renewal happens, you want Nginx to restart, so simply edit /etc/letsencrypt/cli.ini again and add this line to the end:
renew-hook = systemctl restart nginx
Let’s Encrypt certificates are “only” valid for 90 days, but since you don’t have to renew them manually anymore, who cares?
The full official documentation of certbot is available at Read the Docs.