Dec 06,
2016

Secure Connections

With the occasion of the redesign I had the motivation to install the Let's Encrypt certificates and to enable the HTTPS on the web server.

Doing so, I've found out that in a default Debian Jessie install nginx is configured to accept 1024 bits Diffie-Hellman's keys, and those are considered weak keys (the interested reader can search for Logjam attack for the analysis). I think there are old web browser that have a limit of 1024 bit as maximum keys' size and are still used.

To increase the security it's suggested to generate a new prime number of adequate size for the Diffie-Hellman key exchange, store it in a file:

$ openssl dhparam -out dhparams.pem 2048

and adding a line in the nginx configuration:

ssl_dhparam /path/to/the/dhparams.pem

pointing to the above newly created file.

After the little digression, I'm sure I'm not alone saying that certificates management it has always been an hassle, especially interacting with the relative CA. Let's Encrypt provides certificates with a 3 months expiration date, but conveniently they have deployed an infrastructure that enables the fully automation of the authentication of the site administrator and the certificates' renewal using specialized clients, for example the EFF certbot.

Root? How about nope?

It will be all fine and dandy, with packages available for Debian Jessie that in my case completed the configuration without issues, with the small detail that a process is running daily as root and is accepting input from the Interweb, something that I'm somewhat uncomfortable with.

To amend this and run the certbot script as an unprivileged user, I created the three required directories (config, logs and work) in the user's home, copied over the /etc/letsencrypt/config content in the new directory and changed the files ownership. Some paths needed to be modified in the configuration file under config/renewal, basically they all must point to the certificates' new location in the user's home. In the same file, under the renewalparams section, I changed the authentication method and set the path to use for the authentication:

# Options used in the renewal process
[renewalparams]
authenticator = webroot
webroot-map = {"domain.name.here":"/web/root/here"}
account = 4cc0un71dh3r3

When testing, if all is working, the following command:

$ certbot renew --dry-run \
--config-dir ~/letsencrypt/config \
--logs-dir   ~/letsencrypt/logs  \
--work-dir   ~/letsencrypt/work

should report "all good".

To automate it I stopped and disabled the two systemd unit files provided by the certbot packages, certbot.service and certbot.timer, and created two new units in the /etc/systemd/system directory, certbot-non-root.timer:

[Unit]
Description=Run certbot daily

[Timer]
OnCalendar=*-*-* 06:00:00
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target

and certbot-non-root.service:

[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
User=username
Group=usergroup
PrivateTmp=yes
PermissionsStartOnly=yes
NoNewPrivileges=yes
ExecStart=/usr/bin/certbot -q renew \
 --config-dir /home/username/letsencrypt/config \
 --logs-dir   /home/username/letsencrypt/logs \
 --work-dir   /home/username/letsencrypt/work
ExecStartPre=/bin/sh -c 'sleep $(shuf -i 1-3600 -n 1)'
ExecStartPost=/bin/systemctl reload --no-block nginx.service

[Install]
WantedBy=multi-user.target

Two things about the timer unit file:

  • The systemd version in Debian Jessie doesn't seem to support the RandomizedDelaySec directive. There is an error in the logs but it's not fatal so I've left it there1, but for the time being I've added in the service file an equivalent random delay using the ExecStartPre line.

  • It needs to be enabled and started; I forgot the second part and I was quite puzzled when I didn't found traces of it in the logs.

I suppose the reload of the web server in the ExecStartPost line should be enough to read the certificates when they are updated, but I didn't have it tested yet, I'll probably add an update with a note.


  1. Debian Stretch is slated to be released in Q1 2017 and I'm an optimistic. ↩︎