iac/ansible/roles/xmpp_cert_sync/files/xmpp-cert-install
Sergei Poljanski cf142c6e3b
Some checks failed
deploy / ansible (push) Failing after 59s
xmpp_cert_sync: push asxp.io and xmpp.asxp.io as separate files
Traefik never requests a certificate for a name it already holds one
for, so the XMPP certificate came out without asxp.io, the XMPP domain
itself. ejabberd picks the matching certificate file per domain, so push
two: the site's asxp.io certificate and xmpp.asxp.io + conference.
The receiver takes the name from the SSH command (asxp.io or a
subdomain), checks the certificate matches it, and retires the
hand-made server.pem once both files are in place.

A second probe on 5223 sends SNI asxp.io, as clients do, and the
outdated-certificate alert compares each served certificate with its
source in acme.json.

Assisted-by: Claude:opus-5-5
2026-11-13 08:26:08 +04:00

33 lines
1.5 KiB
Bash

#!/bin/sh
# Managed by Ansible (role xmpp_cert_sync). Forced command of the
# xmpp_cert_sync key from asxpio-ops: read a certificate chain + key on
# stdin, check it, install it as certs/<name>.pem for ejabberd (which
# picks the matching file per domain) and reload.
set -eu
umask 022
name=${SSH_ORIGINAL_COMMAND:-}
case "$name" in
asxp.io|*.asxp.io) ;;
*) echo "refusing certificate name '$name'" >&2; exit 1 ;;
esac
case "$name" in *[!a-z0-9.-]*) echo "bad name" >&2; exit 1 ;; esac
dir=/opt/xmpp/state/certs
tmp=$(mktemp "$dir/.incoming.XXXXXX")
trap 'rm -f "$tmp"' EXIT
head -c 65536 > "$tmp"
# Valid for at least another day, for this name, with its matching key
openssl x509 -in "$tmp" -noout -checkend 86400 >/dev/null
openssl x509 -in "$tmp" -noout -checkhost "$name" | grep -q "does match"
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/$name.pem"
trap - EXIT
# The hand-made certificate from before the push; kept outside the glob
if [ -f "$dir/server.pem" ] && [ -f "$dir/asxp.io.pem" ] && [ -f "$dir/xmpp.asxp.io.pem" ]; then
mkdir -p /opt/xmpp/state/certs-retired
mv "$dir/server.pem" "/opt/xmpp/state/certs-retired/server.pem.$(date +%Y%m%d)"
fi
docker compose -f /opt/xmpp/docker-compose.yml exec -T ejabberd ejabberdctl reload_config
logger -t xmpp-cert-install "installed $name.pem, $(openssl x509 -in "$dir/$name.pem" -noout -enddate)"