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, clients suitable for scripts are simp_le-gitAUR and letsencrypt-cliAUR.
Installation
Plugins are available for automated configuration and installation of the issued certificates in web servers:
- The experimental plugin for Nginx is provided with the certbot-nginx package.
- Although a package certbot-apache exists, automated installation using the Apache HTTP Server is currently only supported on Debian and derivatives.
Configuration
Consult the Certbot documentation for more information about creation and usage of certificates.
Webroot
When using the webroot method the Certbot client places a challenge response inside /path/to/domain.tld/html/.well-known/acme-challenge/
which is used for validation.
The use of this method is recommend over a manual install; it offers automatically renewal and easier certificate management.
Obtain certificate(s)
Request a certificate for domain.tld
using /path/to/domain.tld/html/
as public accessible path:
# certbot certonly --email email@example.com --webroot -w /path/to/domain.tld/html/ -d domain.tld
To add a (sub)domain, include all registered domains used on the current setup:
# certbot certonly --email email@example.com --webroot -w /path/to/sub.domain.tld/html/ -d domain.tld,sub.domain.tld
To renew (all) the current certificate(s):
# certbot renew
See #Automatic renewal as alternative approach.
Manual
If there is no plugin for your web server, use the following command:
# certbot certonly --manual
When preferring to use DNS challenge (TXT record) use:
# certbot certonly --manual --preferred-challenges dns
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.
Advanced Configuration
Webserver Configuration
Instead of using plugins for automatic configuration, it may be preferred to enable SSL for a server manually.
nginx
An example of the server domain.tld
using the signed SSL-certificate of Let's Encrypt:
/etc/nginx/servers-available/domain.tld
# redirect to https server { listen 80; listen [::]:80; server_name domain.tld; return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_prefer_server_ciphers on; add_header Strict-Transport-Security max-age=15768000; ssl_stapling on; ssl_stapling_verify on; server_name domain.tld; .. } # A subdomain uses the same SSL-certifcate: server { listen 443 ssl http2; listen [::]:443 ssl http2; ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem; .. server_name sub.domain.tld; .. } # ACME challenge location ^~ /.well-known { allow all; alias /var/lib/letsencrypt/.well-known/; default_type "text/plain"; try_files $uri =404; }
Multiple domains
Management of can be made easier by mapping all HTTP-requests for /.well-known/acme-challenge/
to a single folder, e.g. /var/lib/letsencrypt
.
The path has then to be writable for the Let's Encrypt client and the web server (e.g. nginx or Apache running as user http):
# mkdir -p /var/lib/letsencrypt/.well-known # chgrp http /var/lib/letsencrypt # chmod g+s /var/lib/letsencrypt
nginx
Create a file containing the location block and include this inside a server block:
/etc/nginx/conf.d/letsencrypt.conf
location ^~ /.well-known { allow all; alias /var/lib/letsencrypt/.well-known/; default_type "text/plain"; try_files $uri =404; }
Example of a server configuration:
/etc/nginx/servers-available/domain.conf
server { server_name domain.tld .. include conf.d/letsencrypt.conf; }
Apache
Create the file /etc/httpd/conf/extra/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>
Including this in /etc/httpd/conf/httpd.conf
:
/etc/httpd/conf/httpd.conf
Include conf/extra/httpd-acme.conf
Automatic renewal
systemd
Create a systemd certbot.service
:
/etc/systemd/system/certbot.service
[Unit] Description=Let's Encrypt renewal [Service] Type=oneshot ExecStart=/usr/bin/certbot renew --quiet --agree-tos
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
Add a timer to check for certificate renewal twice a day and 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 [1]:
/etc/systemd/system/certbot.timer
[Unit] Description=Twice daily renewal of Let's Encrypt's certificates [Timer] OnCalendar=0/12:00:00 RandomizedDelaySec=1h Persistent=true [Install] WantedBy=timers.target
Enable and start certbot.timer
.
Alternative services
When using the standalone method you should stop your webserver before executing the renew request, and start your webserver when Certbot is finished. Certbot provides hooks to automatically stop and restart a web server.
nginx
/etc/systemd/system/certbot.service
[Unit] Description=Let's Encrypt renewal [Service] Type=oneshot ExecStart=/usr/bin/certbot renew --post-hook "/usr/bin/systemctl restart nginx.service" --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