There are two current approaches to maintaining TLS certificates:
Presently the latter is only used for pages.sr.ht.
The configuration we use for uacme is a fucking nightmare, but it does work and is pretty reliable. In the future it might be nice to switch to tlstunnel for everything or at least put some more work into the uacme setup.
We have a bunch of shell commands that sets up uacme on a server:
doas apk add uacme openssl moreutils
doas useradd -md /var/lib/acme -s /sbin/nologin acme
doas mkdir -p /etc/ssl/uacme/private /var/www/.well-known/acme-challenge
doas chown acme:acme /etc/ssl/uacme /etc/ssl/uacme/private
doas chmod g+rX /etc/ssl/uacme /etc/ssl/uacme/private
doas chown acme:acme /var/www/.well-known/acme-challenge
doas touch /var/log/acme.log
doas chown acme:acme /var/log/acme.log
doas vim /usr/local/bin/acme-update-certs
Contents of acme-update-certs, edit as necessary:
#!/bin/sh
exec >>/var/log/acme.log 2>&1
date
stats() {
cert="/etc/ssl/uacme/$1/cert.pem"
if ! [ -e "$cert" ]
then
return
fi
expiration=$(date -d"$(openssl x509 -enddate -noout -in "$cert" \
| cut -d= -f2)" -D'%b %d %H:%M:%S %Y GMT' +'%s')
printf '# TYPE certificate_expiration gauge\n'
printf '# HELP certificate_expiration Timestamp when SSL certificate will expire\n'
printf 'certificate_expiration{instance="%s"} %s\n' "$1" "$expiration"
}
acme() {
site=$1
shift
/usr/bin/uacme -v -h /usr/share/uacme/uacme.sh issue $site $* || true
stats $site | curl --data-binary @- https://push.metrics.srht.network/metrics/job/$site
}
acme DOMAIN SUBDOMAIN...
doas nginx -s reload
doas chmod +x /usr/local/bin/acme-update-certs
doas usermod -aG acme nginx
doas -u acme uacme new sir@cmpwn.com
doas -u acme crontab -e
Contents of crontab:
MAILTO=sir@cmpwn.com
0 0 * * * chronic /usr/local/bin/acme-update-certs
Then update the nginx configuration, commenting out the includes for port443.conf and *-ssl.conf.
doas -u acme /usr/local/bin/acme-update-certs
cat /var/log/acme.log
Verify that acme.log looks okay, then uncomment the relevant parts of the nginx configuration.
doas chmod -R g+rX /etc/ssl/uacme /etc/ssl/uacme/private
doas nginx -s reload
# verify TLS configuration
Note: wildcard certificates are possible with uacme, but it's a bloody nightmare so if you want this it's best to go with tlstunnel instead.
TLS certificate expiration and renewal is monitored by metrics.srht.network:
The acme update script pushes the expiration date to push.metrics.srht.network whenever the cronjob runs. If any certificate's expiration date falls below 1 week, the "SSL expiration" alarm is raised.
tlstunnel automatically adds zero-configuration TLS to arbitrary TCP sockets using SNI and the PROXY protocol. It is currently used for pages.sr.ht.
Presently none; see https://todo.sr.ht/~emersion/tlstunnel/24
commit 96d1f5b90650f055dfc866f4d341b03bf9d20c40 Author: Rens Oliemans <hallo@rensoliemans.nl> Date: 2025-01-15T15:05:17+01:00 git.sr.ht/index: fix hut link