diff options
Diffstat (limited to 'ops/tls.md')
-rw-r--r-- | ops/tls.md | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/ops/tls.md b/ops/tls.md new file mode 100644 index 0000000..d036d05 --- /dev/null +++ b/ops/tls.md @@ -0,0 +1,116 @@ +--- +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 |