Sven and the Art of Computer Maintenance

Sven and the Art of Computer Maintenance

28 Dec 2018

Let's Encrypt certificates in Arch Linux

In this post a brief overview is given for requesting and automated renewal of (free!) Let’s Encrypt SSL/TLS certificates in Arch Linux and Arch Linux ARM. Such certificates can be useful for web, mail and a plethora of different web services that can be secured with SSL/TLS.

This guide solely covers requesting and maintaining SSL/TLS certificates, and not the configuration of software that uses these certificates. Note that the method used in this guide is one of many. I opted to use Certbot without a certificate installer since it is the least complex solution, without requiring Certbot to run its own web server and without dynamically changing configuration files of other web server software.

Other ways to satisfy one of the challenges are also available, but are not covered.

Prerequisites

  • Ensure that the host requesting the Let’s Encrypt certificate is reachable on the desired Internet (sub)domains on TCP port 80. A port forwarding or configuration of a reverse proxy server might be necessary.
  • Make a list of all domain names that should be supported by a single certificate. Most often if a certificate for a web server on a domain is used, it contains two names: the domain itself (kiljan.org) and the www subdomain (www.kiljan.org).

Prepare a web server

In this step nginx is installed using a minimal configuration. This step does not have to be followed if a web server running on TCP port 80 is already available. However, in that case the existing web server should serve local path /usr/local/share/webapps/letsencrypt/ to web path /.well-known/acme-challenge/.

For a bare minimum web server, run:

sudo pacman -S nginx
sudo mkdir -p /usr/local/share/webapps/letsencrypt/

Edit /etc/nginx/nginx.conf. Minimal configuration:

events {
}

http {
    server {
        listen 80;

        location /.well-known/acme-challenge/ {
            root /usr/local/share/webapps/letsencrypt/;
        }
    }
}

Now start the web server:

sudo systemctl enable nginx
sudo systemctl start nginx

If you want to integrate the above nginx configuration with an nginx configuration that already supports SSL/TLS, you can use this for inspiration:

(...)

http {
    server {
        listen 80;

        # Enforce HTTPS
        location / {
            return 301 https://$server_name$request_uri;
        }

        # Let's Encrypt ACME challenge support over HTTP
        location /.well-known/acme-challenge/ {
            root /usr/local/share/webapps/letsencrypt/;
        }
(...)
}

(...)

Install and use Certbot

Install Certbot:

sudo pacman -S certbot

Using Certbot to request a certificate is quite straightforward:

sudo certbot certonly --dry-run --email <email> \
  --webroot --webroot-path /usr/local/share/webapps/letsencrypt/ \
  -d <(sub)domain> [ -d <(sub)domain> ... ]

Replace <email> with an email address on which Let’s Encrypt can contact you. Any (mandatory) email addresses given to the Certbot command will not be included in any certificate.

Replace <(sub)domain> with the actual domain name for which you are requesting a certificate. Note that -d <(sub)domain> can be given multiple times, once for each (sub)domain for which the certificate should be valid. An example of a useful combination of names to have in a single certificate would be -d kiljan.org -d www.kiljan.org.

Finally, Agree with the license agreement (for using the Let’s Encrypt staging server).

The above runs a dry run (test) to see if certificates can be requested successfully. If successful, actual SSL/TLS certificates can be requested by removing --dry-run:

sudo certbot certonly --email <email> \
  --webroot --webroot-path /usr/local/share/webapps/letsencrypt/ \
  -d <(sub)domain> [ -d <(sub)domain> ... ]

Agree with the license agreement again (this time for using the Let’s Encrypt production server). Finally, decide if you want to share the provided email address with the Electronic Frontier Foundation. The answer does not have any influence on the certificate.

If the certificate request was successful, Certbot will return local paths to where the certificate and private key are located, and a date on which the certificate will expire. The locations in particular are important, since these are required to configure server software to offer SSL/TLS security. For future reference:

  • Certificate and chain: /etc/letsencrypt/live/<(sub)domain>/fullchain.pem
  • Private key: /etc/letsencrypt/live/<(sub)domain>/privkey.pem
  • Expiration date: three months after issueing date

Where <(sub)domain> is the first (sub)domain name in the certificate.

Some interesting options to add to the certbot command line when initially requesting a certificate:

  • --agree-tos --no-eff-email automatically accept the license agreement, and automatically negatively answer the question whether the given email address can be shared with EFF.
  • --reuse-key will ensure that upon renewal, the same keypair is used instead of generating a new one. This can be useful for a number of reasons, such as making DNS Certification Authority Authorization management easier.
  • --key-type rsa --rsa-key-size 4096 generates a stronger than usual RSA keypair. 2048 bit is currently considered the minimum for decent security.
  • --key-type ecdsa --elliptic-curve secp384r1 will use an elliptic curve keypair instead of an RSA keypair. Available curves are noted in RFC 8446

To see all options, run: certbot --help all

Automated certificate renewal

Create the file /etc/systemd/system/certbot.service:

[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos

Create the file /etc/systemd/system/certbot.timer:

[Unit]
Description=Twice daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=23/11:00:00
RandomizedDelaySec=2h
Persistent=true

[Install]
WantedBy=timers.target

Now run:

sudo systemctl enable --now certbot.timer
sudo systemctl list-timers

Everyday between 00:00-01:00 and between 12:00-13:00 all Let’s Encrypt certificates will be updated if necessary, as well as on reboot if a timer event was missed while the system was offline.

Change email address

If you ever need to update the email address on which Let’s Encrypt can contact you, run:

sudo certbot register --update-registration --email <new email>

Where <new email> is the new email address.