Tutorials
goetia
Software
0x53.net

ACME

When using certificate authorities instead of self signed certificates for TLS, the certificates expire and must be reissued periodically. For e.g. Let's Encrypt certificates, this is done through an ACME client.

To issue and renew a certificate for a specific domain, one has to prove to be the actual owner of the domain. For that, the following process has to be gone through:

  1. The ACME client contacts the certificate authorities server and requests a new certificate.
  2. The ACME client receives some temporary data and puts it somewhere on the machine it runs on.
  3. This same machine publishes the temporary data through a webserver using the HTTP protocol.
  4. The certificate authorities server tries to access the temporary data through the domain the certificate is for.
  5. It compares it to the data sent initially.
  6. If it matches, it provides the ACME client with a new certificate.

Thus, two components are needed: an ACME client and a webserver. For the following example, acme-tiny is used as the ACME client, while tipidee in combination with s6-networking is used as the webserver.

The following examples assumes the use of Let's Encrypt. Thus the subdirectories used are named letsencrypt. This can of course be changed.

ACME daemon

First of all, the directory where the keys and certificates live is to be created. For that, create the directory /etc/ssl/letsencrypt: Make sure that only root and tls can write to /etc/ssl/letsencrypt/ and only users inside the tls group can read files in there. The result should look like this:

drwxr-x--- - tls tls /etc/ssl/letsencrypt
			

Finally, create the following longrun source directory in the src/web/renew-lets-encrypt-srv subdirectory of the system configuration directory.

renew-lets-encrypt-srv
├── dependencies.d
│   ├── mount         # empty/arbitrary
│   └── networking    # empty/arbitrary
├── producer-for      # renew-lets-encrypt-log
├── run               # see below
└── type              # longrun
			

Add the following run script:

#!/bin/execlineb -P

fdmove -c 2 1

s6-setuidgid tls

snooze -d 1

execline-umask 026
if {
	redirfd -w 1 /etc/ssl/letsencrypt/signed_chain.crt.new
	acme-tiny
		--account-key /etc/ssl/letsencrypt/account.key
		--csr /etc/ssl/letsencrypt/domain.csr
		--acme-dir /home/www/@PAGENAME1@/.well-known/acme-challenge/
		--disable-check
}
if {
	mv
		/etc/ssl/letsencrypt/signed_chain.crt.new
		/etc/ssl/letsencrypt/signed_chain.crt
}

# for qmail:
if {
	redirfd -w 1 /var/qmail/control/servercert.pem
	cat
		/etc/ssl/letsencrypt/signed_chain.crt
		/etc/ssl/letsencrypt/domain.key
}
if { chown qmaild /var/qmail/control/servercert.pem }
chmod 700 /var/qmail/control/servercert.pem
			

This script drops privileges to the user tls. It then invokes snooze to wait until the first day of every month. It applies a proper umask and runs the acme daemon makeing sure the resulting certificate ends up at /etc/ssl/letsencrypt/signed_chain.crt with proper permissions.

Additionally, it creates a certificate file for qmail to use.

Webserver files

The webserver will run in HTTP mode and serve the files the ACME client put at /home/www/@PAGENAME1@/.well-known/acme-challenge. Make sure that the user www is in the group tls, so that the webserver can read the files to serve them.

First of all, one needs to create the directory where the ACME client will put the data received from the certificate authority. For this, create the directory /home/www/@PAGENAME1@: A symlink indicating domain and port is required for tipidee, replace @YOURIP@ with the name of the IP address of the server, the certificate is for. The entire directory structure should again belong to the user tls and be readable only by other users in the group tls:

drwxr-x--- - www www  /home/www
lrwxrwxrwx - www www  ├── @DOMAINNAME1@:80 -> @PAGENAME1@
drwxr-x--- - tls tls  └── @PAGENAME1@
drwxr-x--- - tls tls      └── .well-known
drwxr-x--- - tls tls          └── acme-challenge
			

Finally, set up a tipidee http webserver as described in the http webserver tutorial, to server the challange files.