Let’s Encrypt, automated, but please not as root
I made the switch today to Let’s Encrypt for all the certificates used by services hosted at siosm.fr.
The official setup instructions are well written and simple to follow but not safe enough for my taste. The Let’s Ecrypt page on the Arch Wiki also has most of the information required to get a working setup but does not care for security either.
So here is a non root, confined setup for certbot
, the official Let’s Encrypt client.
Although this was done on Arch Linux, this is probably generic enough to work on any systemd
enabled distribution.
Update: I have improved this post to avoid using a path unit to trigger service restart upon certificate update. Apart from the fact that the configuration now involves fewer units, this also solves a minor issue. The previous setup could have been turned into a potential denial of service against systemd and the services using the certificates.
certbot
is available in the official repositories:
Create a non root user and group for certbot
:
Give certbot
ownership to the directories it is going to use:
Create a configuration file:
/etc/letsencrypt/cli.ini
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Register with the specified e-mail address
email = root@example.com
# Generate certificates for the specified domains. Required the first time you
# run certbot.
# Not necessary for renewal requests and thus must be commented out then.
domains = example.com, stuff.example.com
# Use a text interface instead of ncurses
text = True
# Run without ever asking for user input
non-interactive = True
# Enables OCSP Stapling
staple-ocsp = True
# Use the webroot authenticator
authenticator = webroot
webroot-path = /var/lib/letsencrypt
# Touch a specific file each time we get a new certificate
# (see certbot-renewed.service)
renew-hook = date --iso=min > renewed
Make sure permissions are OK:
Configure your HTTP server (nginx
example here):
Run certbot
manually the first time to make sure everything is OK:
Then comment out the domains
variable in /etc/letsencrypt/cli.ini
.
Configure your services to now use the new certificates available in /etc/letsencrypt/live/example.com/
. Use the certbot
group to give specific users access to this folder:
Use the following systemd units to regularly check for certificates renewal:
/etc/systemd/system/certbot.timer
:
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Weekly check for Let's Encrypt's certificates renewal
[Timer]
# The official documentation suggests running certbot two times per day but I
# find once a week to be reasonable.
OnCalendar=Sun *-*-* 04:00:00
# Use this line instead of you prefer running the check daily.
# OnCalendar=*-*-* 04:00:00
Persistent=true
[Install]
WantedBy=timers.target
/etc/systemd/system/certbot.service
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Unit]
Description=Let's Encrypt certificate renewal
[Service]
Type=oneshot
User=certbot
Group=certbot
UMask=0027
PermissionsStartOnly=yes
ExecStart=/usr/bin/certbot renew
ExecStartPost=/usr/bin/systemctl start --no-block certbot-renewed
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=yes
ProtectHome=yes
CapabilityBoundingSet=
AmbientCapabilities=
And this one to automatically restart selected services if necessary:
/etc/systemd/system/certbot-renewed.service
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Unit]
Description=Restart selected daemons when Let's Encrypt certificates are renewed
ConditionFileNotEmpty=/var/lib/letsencrypt/renewed
[Service]
Type=oneshot
User=certbot
Group=certbot
UMask=0027
PermissionsStartOnly=yes
ExecStart=/usr/bin/rm -- /var/lib/letsencrypt/renewed
ExecStartPost=/usr/bin/systemctl restart --no-block nginx
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=yes
ProtectHome=yes
CapabilityBoundingSet=
AmbientCapabilities=
Enjoy your non root Let’s Encrypt fully automated setup!
Comments
You can also contact me directly if you have feedback.