Introduction
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: acme_certificate[staging] (/etc/letsencrypt/resources/certificate.rb 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 https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430 for details.
You’ll need to update the certbot packet
NO_PUBKEY Issue
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 or sudo dnf remove certbot or 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
https://www.<domain>.com/.well-known/acme-challenge/sofLnv6tIMZV8bcpH4SCVwOjVwTAAS3uyArzaADPr00
[52.209.90.201]: "<html>\r\n<head><title>403
Forbidden</title></head>\r\n<body
bgcolor=\"white\">\r\n<center><h1>403
Forbidden</h1></center>\r\n<hr><center>"
Adjust location, e.g. Nginx:
location ~ /.well-known { allow all; }
Don’t forget to restart nginx.