Certbot

Certbot
is
Electronic Frontier Foundation
's
ACME
client, which is written in Python and provides conveniences like automatic web server configuration and a built-in webserver for the HTTP challenge. Certbot is recommended by
Let's Encrypt
.
Installation
Install
the
certbot
package.
Plugins are available for automated configuration and installation of the issued certificates in web servers:
The
Nginx
plugin can be installed with the
certbot-nginx
package.
The
Apache HTTP Server
plugin can be installed with the
certbot-apache
package.
Configuration
Consult the
Certbot documentation
for more information about creation and usage of certificates.
Plugins
Warning
Configuration files may be rewritten to add settings and paths for Certbot certificates when using a plugin. Creating a
backup
first is recommended.
Nginx
The plugin
certbot-nginx
provides an automatic configuration for
nginx
. This plugin will try to detect the configuration setup for each domain. The plugin adds extra configuration recommended for security, settings for certificate use, and paths to Certbot certificates. See
#Managing Nginx server blocks
for examples.
First time setup of
server-blocks
:
# certbot --nginx
To renew certificates:
# certbot renew
To change certificates without modifying nginx configuration files:
# certbot --nginx certonly
See
Certbot-Nginx on Arch Linux
for more information and
#Automatic renewal
to keep installed certificates valid.
Managing Nginx server blocks
The following example may be used in all
server blocks
when managing these files manually:
/etc/nginx/sites-available/example
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2; # Listen on IPv6
  ssl_certificate /etc/letsencrypt/live/
domain
/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/
domain
/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ..
}
See
nginx#TLS
for more information.
It is also possible to create a separated configuration file and include it in each server block:
/etc/nginx/conf/001-certbot.conf
ssl_certificate /etc/letsencrypt/live/
domain
/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/
domain
/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf;
/etc/nginx/sites-available/example
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2; # Listen on IPv6
  include conf/001-certbot.conf;
  ..
}
Apache
The plugin
certbot-apache
provides an automatic configuration for the
Apache HTTP Server
. This plugin will try to detect the configuration setup for each domain. The plugin adds extra configuration recommended for security, settings for certificate use, and paths to Certbot certificates. See
#Managing Apache virtual hosts
for examples.
First time setup of
virtual hosts
:
# certbot --apache
To renew certificates:
# certbot renew
To change certificates without modifying Apache configuration files:
# certbot --apache certonly
See
Certbot-Apache on Arch Linux
for more information and
#Automatic renewal
to keep installed certificates valid.
Managing Apache virtual hosts
The following example may be used in all
virtual hosts
when managing these files manually:
/etc/httpd/conf/extra/001-certbot.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/'domain'/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/'domain'/privkey.pem

</VirtualHost>
</IfModule>
When the VirtualHost above is automatically generated by certbot-apache, it looks like sometimes the 'Include' line may appear after the two 'SSLCertificate' lines. When this is the case, accessing the virtualHost from a browser using http wont work with an error SSL_PROTOCOL_ERROR. If this happens, simply put the Include line above the two SSLCertificates lines and restart httpd.
/etc/httpd/conf/httpd.conf
<IfModule mod_ssl.c>
  Listen 443
  </IfModule>

  Include conf/extra/001-certbot.conf
  ..
See
Apache HTTP Server#TLS
for more information.
PKCS#12
The plugin
python-certbot-pkcs12
AUR
provides an automatic installation with PKCS#12 certificates archive, which is mostly used by
Kestrel
The following command install PKCS#12 archive to your destination only:
# certbot install -i pkcs12 --pkcs12-location
/etc/locationToPlaceFile
.pfx
To integrate with other commands:
# certbot
some_options
--installer pkcs12 --pkcs12-location
/path/to/your/pkcs12
.p12
This integrates installer option with your previous operation by writing options into certbot configuration, and should be auto applied when renewal:
# certbot renew
Webroot
Note
The Webroot method requires
HTTP on port 80
for Certbot to validate.
The Server Name must match that of its corresponding DNS.
Permissions may need to be altered on the host to allow read-access to
http://
domain.tld
/.well-known
.
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 recommended over a manual install; it offers automatic renewal and easier certificate management. However the usage of
#Plugins
may be the preferred since it allows automatic configuration and installation.
Mapping ACME-challenge requests
The factual accuracy of this article or section is disputed.
Reason:
In the
webroot
way, the
/var/lib/letsencrypt
path is dictated by
certbot
. Manual creation is not necessary, that applies to
#Manual
. (Discuss in
Talk:Certbot
)
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 Cerbot and the web server (e.g.
nginx
or
Apache HTTP Server
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/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  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 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
Obtain certificate(s)
This article or section needs expansion.
Reason:
detail lacking to successfully accomplish task being taught (Discuss in
Talk:Certbot#accuracy_flag
)
Request a certificate for
domain.tld
using
/var/lib/letsencrypt/
as public accessible path:
# certbot certonly --email
email@example.com
--webroot -w
/var/lib/letsencrypt/
-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
/var/lib/letsencrypt/
-d
domain.tld,sub.domain.tld
To renew (all) the current certificate(s):
# certbot renew
Note
Do not forget to include the Let's Encrypt configuration file inside all related server blocks, those handling HTTP traffic as well as those handling HTTPS traffic, especially when using - as recommended - HSTS (HTTP Strict Transport Security). This can lead one to obtain certificate(s) smoothly, and once the setup is done, to be blocked for the renewal.
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/archive/
your.domain
/
and symlinked from
/etc/letsencrypt/live/
your.domain
/
.
You can then manually configure your web server to reference the private key, certificate and full certificate chain in the symlinked directory.
Note
Running this command multiple times, or renewing certificates will create multiple sets of files with a trailing number in
/etc/letsencrypt/archive/
your.domain
/
.  Certbot automatically updates the symlinks in
/etc/letsencrypt/live/
your.domain
/
to point to the latest instances of files so there is no need to update your webserver to point to the new key material.
DNS challenge
For servers which are not exposed to public internet,
DNS-01 challenge
can be used to verify domain ownership
Install
the certbot plugin for your dns provider
certbot-dns-*
. Below example shows for cloudflare using
certbot-dns-cloudflare
.
Create a Credential file
/etc/certbot-cloudflare.creds.ini
dns_cloudflare_api_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Get certificate.
# chmod 600 /etc/certbot-cloudflare.creds.ini
# certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/certbot-cloudflare.creds.ini -d domain.tld
certbot-renew.service
will renew automatically using the above credential file
#Automatic renewal
. 
See
docs
for obtaining api token and other options.
Advanced configuration
Automatic renewal
systemd
certbot comes with a
systemd
certbot-renew.service
, which attempts to renew certificates that expire in less than 30 days. If all certificates are not due for renewal, this service does nothing.
If you do not use a plugin to manage the web server configuration automatically, the web server has to be reloaded manually to reload the certificates each time they are renewed. This can be done by adding
--post-hook "systemctl reload nginx.service"
to the
ExecStart
command
[1]
. Of course use
httpd.service
instead of
nginx.service
if appropriate. Additional services can be added to the
systemctl
command as needed, e.g.
systemctl reload httpd dovecot postfix
.
Note
Before enabling the
certbot-renew.timer
, check that the service is working correctly and is not trying to prompt anything. Note that the service may take up to 480 seconds to complete since a delay is added to calling certbot non-interactively since
v0.29.0
.
Enable
and
start
certbot-renew.timer
to check for certificate renewal twice a day, including a randomized delay so that everyone's requests for renewal will be spread over the day to lighten the Let's Encrypt server load
[2]
.
Automatic renewal for wildcard certificates
The process is fairly simple. To issue a wildcard certificate, you have to do it via a DNS challenge request,
using the ACMEv2 protocol
.
While issuing a certificate manually is easy, it is not straight forward for automation. The DNS challenge represents a TXT record, given by certbot, which has to be set manually in the domain zone file.
You will need to update the zone file upon every renew. To avoid doing that manually, you may use
RFC 2136
for which certbot has a plugin packaged in
certbot-dns-rfc2136
. You will also need to configure your DNS server to allow dynamic updates for TXT records.
Configure BIND for rfc2136
Generate a TSIG secret key:
$ tsig-keygen -a HMAC-SHA512
example-key
and add it in the configuration file:
/etc/named.conf
...
zone "
domain.ltd
" IN {
        ...
        // this is for certbot
        update-policy {
                grant
example-key
name _acme-challenge.
domain.ltd
. txt;
        };
        ...
};

key "
example-key
" {
        algorithm hmac-sha512;
        secret "
a_secret_key
";
};
...
Restart
named.service
.
Configure certbot for rfc2136
Install
certbot-dns-rfc2136
, then create a configuration file for it.
/etc/letsencrypt/rfc2136.ini
dns_rfc2136_server =
IP.ADD.RE.SS
dns_rfc2136_name =
example-key
dns_rfc2136_secret =
INSERT_KEY_WITHOUT_QUOTES
dns_rfc2136_algorithm = HMAC-SHA512
Since the file contains a copy of the secret key, secure it with
chmod
by removing the group and others permissions.
Test what we did:
# certbot certonly --dns-rfc2136 --force-renewal --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini --server
https://acme-v02.api.letsencrypt.org/directory
--email
example@domain.ltd
--agree-tos --no-eff-email -d '
domain.ltd'
-d '
*.domain.ltd'
If you pass the validation successfully and receive certificates, then you are good to go with automating certbot. Otherwise, something went wrong and you need to debug your setup. It basically boils down to running
certbot renew
from now on, see
#Automatic renewal
.
See also
Acme.sh
alternative ACME client supporting Let's Encrypt
Transport Layer Security#ACME clients
EFF's Certbot documentation
Let's Encrypt – List of ACME clients