--- title: TLS documentation --- There are two current approaches to maintaining TLS certificates: 1. [uacme](https://github.com/ndilieto/uacme) 2. [tlstunnel](https://sr.ht/~emersion/tlstunnel/) Presently the latter is only used for pages.sr.ht. ## uacme 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. ### Set up 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.sr.ht/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. ### Monitoring TLS certificate expiration and renewal is monitored by metrics.sr.ht: [![](https://metrics.sr.ht/chart.svg?title=Days%20until%20certificate%20expiration&query=(certificate_expiration%20-%20time())/60/60/24&since=336h&label={{.instance}}&height=3.5&min=0)](https://metrics.sr.ht/graph?g0.expr=(certificate_expiration%20-%20time())&g0.tab=0&g0.stacked=0&g0.show_exemplars=0&g0.range_input=2w) The acme update script pushes the expiration date to push.metrics.sr.ht whenever the cronjob runs. If any certificate's expiration date falls below 1 week, the "SSL expiration" alarm is raised. ## tlstunnel tlstunnel automatically adds zero-configuration TLS to arbitrary TCP sockets using SNI and the PROXY protocol. It is currently used for pages.sr.ht. ### Monitoring Presently none; see https://todo.sr.ht/~emersion/tlstunnel/24