Skip to main content

Secure Nginx with Let's Encrypt

Install

On Ubuntu systems, the Certbot team maintains a PPA. Once you add it to your list of repositories all you'll need to do is apt-get the following packages.

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot 

Get Started

To obtain a cert using a built-in “standalone” webserver (you may need to temporarily stop your existing webserver, if any):

  • to use port 80:
$ certbot certonly --standalone --preferred-challenges http
  • to use port 443:
$ certbot certonly --standalone --preferred-challenges tls-sni

Note: In the website (www.example.com) configuration file (/etc/nginx/sites-enabled/example), you need to add the following lines:

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

Automating renewal

Let's Encrypt's certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. We'll need to set up a regularly run command to check for expiring certificates and renew them automatically.

To run the renewal check daily, we will use cron, a standard system service for running periodic jobs. We tell cron what to do by opening and editing a file called a crontab.

$ sudo crontab -e

Your text editor will open the default crontab which is a text file with some help text in it. Paste in the following line at the end of the file, then save and close it:

30 3 * * 0 /usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"

The 30 3 * * 0 part of this line means "run the following command at 3:30 am, every Sunday". You may choose any time.

The renew command for Certbot will check all certificates installed on the system and update any that are set to expire in less than thirty days. --quiet tells Certbot not to output information nor wait for user input. --renew-hook "/bin/systemctl reload nginx" will reload Nginx to pick up the new certificate files, but only if a renewal has actually happened.

If you have certificates obtained using the standalone plugin, you might need to stop the webserver before renewing so standalone can bind to the necessary ports, and then restart it after the plugin is finished, therefore, paste the line below instead:

30 3 * * 0 /usr/bin/certbot renew --quiet --pre-hook "service nginx stop" --post-hook "service nginx start"

Crontab Parameters

  • m - Minute - 0 through 59
  • h - Hour - 0 through 23
  • dom - Day of Month - 0 through 31
  • mon - Month - 0 through 12
  • dow - Day of Week - 0 through 7 (0 and 7 are both Sunday)
  • * - The Asterisk is used as a wild card.