Let’s Encrypt Free SSL Setup – Nginx (Ubuntu 18.04)

Let’s Encrypt Free SSL Setup – Nginx (Ubuntu 18.04)


This quick tutorial will show you how to set up a free SSL certificate from Let’s Encrypt on an Ubuntu 18.04 server, running Nginx as a web server.

SSL (Secure Sockets Layer) is the standard security technology for establishing an encrypted link between a web server and a browser. This link ensures that all data passed between the web server and browsers remain private and integral.

Let’s Encrypt is a free, automated, and open Certificate Authority.

Step 1: Installing Let’s Encrypt Client

Let’s Encrypt certificates are fetched via client software (Certbot) running on your server.

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

Step 2: Nginx configuration

Appropriate server block has to be present in Nginx configuration, in order for Certbot to find and configure SSL (specifically server_name):

. . .
server_name example.com www.example.com;
. . .

Don’t forget to check Nginx configuration Syntax:

sudo nginx -t

Also, you’ll need to reload Nginx:

sudo systemctl reload nginx

Step 3: Allowing HTTPS Through the Firewall (probably not needed)

The Uncomplicated Firewall (ufw) is a frontend for iptables and is particularly well-suited for host-based firewalls. By default, ufw is probably inactive. Therefore, we’ll check the status:

sudo ufw status

If active, you can let HTTPS traffic in like this:

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

Step 4: Obtaining Free SSL Certificate

Run certbot command in order to obtain a certificate:

sudo certbot --nginx -d example.com -d www.example.com

-d specifies the names we’d like the certificate to be valid for

Step 5 — Verifying Certbot Auto-Renewal

Let’s Encrypt’s certificates are only valid for 90 days. This will encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a renew script to /etc/cron.d. This script runs twice a day and will automatically renew any certificate that’s within thirty days of expiration.

sudo certbot renew –dry-run

Finally, If no errors, everything is ready.

Add another domain (Expand)

For additional VHosts, simply type:

certbot certonly --webroot -w /var/www/vhost/domain.com/ --expand -d domain.com,www.domain.com

List Let’s Encrypt Certificates

Simply by typing:

$ certbot certificates

Renew specific Let’s encrypt domain

Occasionally you’ll need to renew just specific domain. Use:

$ certbot renew --cert-name <certificate_name>

Deploy Let’s encrypt hook

You might end up needing specific operation to be run on cert renewal. To automate this you can rely on hooks.

  • --deploy-hook : command to be run once for each successfully issued cert
  • --pre-hook : command to run before obtaining any certs
  • --post-hook : command to run after attempting to obtain certs

For e.g. there was an issue before with syncing Prosody (xmpp) and Let’s encrypt certs (permission issue) so this come in handy:

$ certbot renew --deploy-hook "prosodyctl --root cert import /etc/letsencrypt/live"

You can get more details on hooks in certbot documentation.

Renew ACMEv2 Issue

Another issue that might occur while trying to renew:

$ cerbot renew --dry-run
letsencrypt_certificate[elenx.net] (letsencrypt::http_authorization
 line 3) had an error: Acme::Client::Error::Unauthorized:
 line 20) had an error: Acme::Client::Error::Unauthorized: Account
 creation on ACMEv1 is disabled. Please upgrade your ACME client to a
 version that supports ACMEv2 / RFC 8555. See
 for details.

You’ll need to update the certbot packet


You might also end up with:

Err:7 http://ppa.launchpad.net/certbot/certbot/ubuntu disco InRelease
   The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8C47BE8E75BCA694
 Reading package lists… Done
 W: GPG error: http://ppa.launchpad.net/certbot/certbot/ubuntu disco InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8C47BE8E75BCA695
 E: The repository 'http://ppa.launchpad.net/certbot/certbot/ubuntu disco InRelease' is not signed.
 N: Updating from such a repository can't be done securely, and is therefore disabled by default.
 N: See apt-secure(8) manpage for repository creation and user configuration details.

Not being able to update packages (apt-get update). Try:

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8C47BE8E75BCA695 (Use your key)

and run update again

The client lacks sufficient authorization

Outdated V1 API Error:

Attempting to renew cert (domain.com) from /etc/letsencrypt/renewal/domain.com.conf produced an unexpected error: urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Error creating new authz :: Validations for new domains are disabled in the V1 API (https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430). Skipping

Solution, update certbot. Check here.

sudo apt-get remove certbot
sudo dnf remove certbot
sudo yum remove certbot

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Let’s encrypt 403 or Unauthorized

Most likely Apache/Nginx doesn’t allow access to Let’s encrypt .well-known folder. You migh end up with something like:

Domain: www.<domain>.com
Type:   unauthorized
Detail: Invalid response from
[]: "<html>\r\n<head><title>403

Adjust location, e.g. Nginx:

location ~ /.well-known {
      allow all;

Don’t forget to restart nginx.