xmpp_cert_sync: renew the XMPP certificate through Traefik
All checks were successful
deploy / ansible (push) Successful in 7m22s
All checks were successful
deploy / ansible (push) Successful in 7m22s
The ejabberd certificate (asxp.io, conference., xmpp.) was issued by hand and expires 2027-01-28 with nothing renewing it. Traefik now obtains it alongside the sites' certificates, through a router that only exists to request it, and a systemd path unit on ops pushes it to services whenever acme.json changes, with a daily run as fallback. The push uses its own SSH key, accepted from ops' VPC address only and forced to xmpp-cert-install, which checks the certificate is valid for another day and matches its key before replacing server.pem and reloading ejabberd. Two alerts: the sync hasn't succeeded for two days, or ejabberd serves an older certificate than Traefik holds for six hours. The existing expiry alert already covers port 5223. Assisted-by: Claude:opus-5-5
This commit is contained in:
parent
4865efd078
commit
5e009c4a47
11 changed files with 217 additions and 1 deletions
20
ansible/roles/xmpp_cert_sync/files/xmpp-cert-install
Normal file
20
ansible/roles/xmpp_cert_sync/files/xmpp-cert-install
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
# Managed by Ansible (role xmpp_cert_sync). Forced command of the
|
||||
# xmpp_cert_sync key from asxpio-ops: read certificate chain + key on
|
||||
# stdin, check it, install it for ejabberd and reload.
|
||||
set -eu
|
||||
umask 022
|
||||
dir=/opt/xmpp/state/certs
|
||||
tmp=$(mktemp "$dir/.server.pem.XXXXXX")
|
||||
trap 'rm -f "$tmp"' EXIT
|
||||
head -c 65536 > "$tmp"
|
||||
# A certificate valid for at least another day, with its matching key
|
||||
openssl x509 -in "$tmp" -noout -checkend 86400 >/dev/null
|
||||
cert_pub=$(openssl x509 -in "$tmp" -noout -pubkey | sha256sum)
|
||||
key_pub=$(openssl pkey -in "$tmp" -pubout | sha256sum)
|
||||
[ "$cert_pub" = "$key_pub" ] || { echo "key does not match certificate" >&2; exit 1; }
|
||||
chmod 0644 "$tmp"
|
||||
mv "$tmp" "$dir/server.pem"
|
||||
trap - EXIT
|
||||
docker compose -f /opt/xmpp/docker-compose.yml exec -T ejabberd ejabberdctl reload_config
|
||||
logger -t xmpp-cert-install "installed $(openssl x509 -in "$dir/server.pem" -noout -enddate)"
|
||||
8
ansible/roles/xmpp_cert_sync/files/xmpp-cert-sync.path
Normal file
8
ansible/roles/xmpp_cert_sync/files/xmpp-cert-sync.path
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[Unit]
|
||||
Description=Watch Traefik's acme.json for a renewed XMPP certificate
|
||||
|
||||
[Path]
|
||||
PathChanged=/opt/traefik/letsencrypt/acme.json
|
||||
|
||||
[Install]
|
||||
WantedBy=paths.target
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=Push the XMPP certificate from Traefik to ejabberd
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/xmpp-cert-sync
|
||||
9
ansible/roles/xmpp_cert_sync/files/xmpp-cert-sync.timer
Normal file
9
ansible/roles/xmpp_cert_sync/files/xmpp-cert-sync.timer
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Daily XMPP certificate check (fallback for the path unit)
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 05:40:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Loading…
Add table
Add a link
Reference in a new issue