Let’s Encrypt

Let’s Encrypt is a free, automated, and open certificate authority utilizing the ACME protocol.

The official client is called Certbot, which allows to request valid X.509 certificates straight from the command line. A minimal client with manual CSR creation is available at acme-tinyAUR. More integrated clients suitable for scripts are e.g. simp_le-gitAUR and letsencrypt-cliAUR.

Note: The official client, which was previously called the Let’s Encrypt client, is now called Certbot.

Certbot

Certbot, previously called the Let’s Encrypt client, is the official reference client. It is written in Python and provides a command-line tool to obtain certificates.

Installation

Install the certbot package.

Plugins are available for automated configuration and installation of the issued certificates in web servers:

Configuration

Please consult the Certbot documentation on how to create and install certificates.

Manual

Note: With this method, you must temporarily stop your web server. You can also run the verification through your already running web server with the #Webroot method.

If there is no plugin for your web server, use the following command:

# certbot certonly --manual

This will automatically verify your domain and create a private key and certificate pair. These are placed in /etc/letsencrypt/live/your.domain/.

You can then manually configure your web server to use the key and certificate in that directory.

Webroot

The webroot method lets the client place a challenge response at yourdomain.tld/.well-known/acme-challenge/. You can use it to get/renew certificates with a running webserver.

# certbot certonly --email email@example.com --webroot -w /path/to/html/ -d your.domain

Make sure the server configuration for the certificates points to /etc/letsencrypt/live/your.domain/.

Note: For apache or nginx, use --apache or --nginx respectively instead of --webroot. If you require the verification through port 80 instead of port 443, use --webroot.
Multiple domains

If you use more than one domain or subdomains, the webroot has to be given for every domain. If no new webroot is given, the previous is taken.

Management of this can be made much easier, if you map all http requests for /.well-known/acme-challenge/ to a single folder, e.g. /var/lib/letsencrypt.

For nginx you can achieve this by creating a file containing this location block then including it in server blocks of sites you want to request certificates for:

/etc/nginx/letsencrypt.conf

location ^~ /.well-known/acme-challenge {
    alias /var/lib/letsencrypt/.well-known/acme-challenge;
    default_type "text/plain";
    try_files $uri =404;
}

Then within the server block:

/etc/nginx/servers/example.com.conf
server {
    ...

    include letsencrypt.conf;
}

For Apache you can achieve this by creating the file httpd-acme.conf:

/etc/httpd/conf/extra/httpd-acme.conf
Alias /.well-known/acme-challenge/ "/var/lib/letsencrypt/.well-known/acme-challenge/"
<Directory "/var/lib/letsencrypt/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>

and including it in httpd.conf:

/etc/httpd/conf/httpd.conf
Include conf/extra/httpd-acme.conf

The chosen path has then to be writable for the chosen letsencrypt client. It also has to be readable by the web server; you can achieve this thereby : chgrp http /var/lib/letsencrypt && chmod g+s /var/lib/letsencrypt.

Automatic renewal

When running certbot certonly, Certbot stores the domains and webroot directories in /etc/letsencrypt/renewal, so the certificates can be renewed later automatically by running certbot renew.

Service

You can fully automate this by creating a systemd service

/etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt renewal

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

When using the standalone method you'll want to stop your webserver before executing the renew request and start your webserver when certbot is finished, luckily certbot provides some hooks that do just that.

Nginx

/etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --pre-hook "/usr/bin/systemctl stop nginx.service" --post-hook "/usr/bin/systemctl start nginx.service" --quiet --agree-tos

Apache

/etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --pre-hook "/usr/bin/systemctl stop httpd.service" --post-hook "/usr/bin/systemctl start httpd.service" --quiet --agree-tos
Automatic renewal timer

Before adding a timer, check that the service is working correctly and is not trying to prompt anything. Then, you can add a timer to renew the certificates daily. Include a randomized delay so that everyone's requests for renewal will be evenly spread over the day to lighten the Let's Encrypt server load.

/etc/systemd/system/certbot.timer
[Unit]
Description=Daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=daily
RandomizedDelaySec=1day
Persistent=true

[Install]
WantedBy=timers.target

Enable and start certbot.timer.

You'll probably want your web server to reload the certificates after each time they're renewed. You can realize that by adding one of these lines to the certbot.service file:

  • Apache: ExecStartPost=/bin/systemctl reload httpd.service
  • nginx: ExecStartPost=/bin/systemctl reload nginx.service

See also