0x4a42.net

Hello World.

Using Certbot without root privileges

This post will briefly describe my setup for Let’s Encrypt. I use the official client Certbot, formerly known as letsencrypt, but I don’t use any of its webserver autoconfiguration features and don’t run it as root. The domain validation always uses the webroot method. Some tiny details are specific to Debian, but should be fairly easy to adapt to other distributions.

It all starts with installing Certbot and creating a dedicated user and group:

apt install certbot
adduser --system --home /home/certbot --group --disabled-password certbot

If you are running Debian, the next thing you want to do is to update the cronjob the certbot package installed in /etc/cron.d/certbot. Just change the user and add MAILTO=root on top to receive the output via e-mail if something breaks.

In the usual setup for the root user, Certboot looks at /etc/letsencrypt for its configuration, but it also tries to read ~/.config/letsencrypt/cli.conf. Note that these paths still use the letsencrypt name, even though the software got renamed. As of today, even the most recent version from Git doesn’t look at any files with certbot in their names.

As I have created a dedicated user for Certbot, I don’t mind if the config directory isn’t hidden and also I think it’s nice if my certificates aren’t hidden somewhere in ~/.config/letsencrypt, thus I’ll just symlink ~/.config/letsencrypt to ~/etc:

sudo -u certbot mkdir /home/certbot/{.config,etc}
sudo -u certbot ln -s ../etc /home/certbot/.config/letsencrypt

Next, place the following file at /home/certbot/etc/cli.ini:

# E-mail address for your account
email = your-email-address@example.org

# Always use the text interface instead of the ncurses interface
text = True

# Automatically agree to the ACME Subscriber Agreement. You should read it
# but we all know you probably won't, but don't blame me in that case!
agree-tos = True

config-dir = /home/certbot/etc
work-dir = /home/certbot/var/lib
logs-dir = /home/certbot/var/log

authenticator = webroot
webroot-path = /home/certbot/var/www

The file makes sure that all directories used by Certbot are within the home directory of our user. Just make sure to create them:

sudo -u certbot mkdir -p /home/certbot/var/{lib,log,www}

And set appropriate permissions for all the directories created so far:

chmod 711 /home/certbot{,/var}
chmod 700 /home/certbot/{etc,var/lib,var/log}
chmod 755 /home/certbot/var/www

The last thing we have to do is to configure our webserver to proxy requests for /.well-known/acme-challenge/ to the webroot directory in our home. For nginx, I’ve added the following to each server block I want to obtain certificates for:

location /.well-known/acme-challenge/ {
    alias /home/certbot/var/www/.well-known/acme-challenge/;
}

For Apache, the following line should do on a global level of your configuration:

Alias /.well-known/acme-challenge/ \
    /home/certbot/var/www/.well-known/acme-challenge/
<Directory "/home/certbot/var/www/">
    Require all granted
</Directory>

Now it’s time to get the first certificate using this setup:

sudo -u certbot certbot certonly -d example.org