aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ops/tls.md116
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