3.2 KiB
Let's Encrypt for Prosody (manual dns-01) — proven recipe (2026-08-28, ICQ/nixg.ru)
Goal: trusted cert for the XMPP domain served on c2s 5222 / s2s 5269. Federation rejects self-signed certs ("bad certificate" in Prosody logs from external servers).
Why dns-01
- http-01 needs a web root on the XMPP domain — impossible when the apex A-record points at a static landing page (81.177.135.175) instead of your server.
- dns-01 only requires adding a TXT record in the DNS panel. Works for any domain whose DNS you control.
Prereqs
sudo apt-get install -y certbot(Ubuntu 24.04 → certbot 2.9.0; comes from apt, no snap needed).- If apt is wedged by a broken package (transitional chromium-browser blocked dpkg in this session), repair first:
sudo dpkg --configure -athensudo apt-get install -f. - CAA must permit Let's Encrypt:
dig nixg.ru CAA +short→0 issue "letsencrypt.org".
Issue
sudo certbot certonly --manual --preferred-challenges dns \
-d nixg.ru -d xmpp.nixg.ru \
--email <you>@<mail> --agree-tos --no-eff-email \
--manual-auth-hook /bin/true --manual-cleanup-hook /bin/true
Key trick: --manual-auth-hook /bin/true --manual-cleanup-hook /bin/true make certbot skip interactive prompts — usable from a non-interactive shell. Run it ONCE: it prints the TXT values, you deploy them in the panel, then run the SAME command again: certbot re-checks the still-deployed TXT records and completes issuance. (Plain --manual without the hooks reads stdin and dies with EOFError from a non-interactive terminal.)
TXT records (one per -d name)
_acme-challenge.nixg.ru TXT <value1>
_acme-challenge.xmpp.nixg.ru TXT <value2>
- Values differ per cert; certbot prints each under "Please deploy a DNS TXT record under the name: ...".
- Wait ~1–2 min, then verify from OUTSIDE the local resolver cache — both must resolve:
dig @1.1.1.1 _acme-challenge.nixg.ru TXT +shortanddig @8.8.8.8 _acme-challenge.nixg.ru TXT +short
Install for Prosody
sudo cp -L /etc/letsencrypt/live/nixg.ru/fullchain.pem certs/nixg.ru.crt
sudo cp -L /etc/letsencrypt/live/nixg.ru/privkey.pem certs/nixg.ru.key
docker compose restart prosody
Prosody 0.11 reads certs/<domain>.crt / .key. Log line to confirm: <domain>:tls info Certificates loaded.
Verify — do NOT trust openssl -starttls
openssl s_client -starttls xmpp is broken for Prosody 0.11: "no peer certificate available", Cipher NONE even when TLS is fine (false negative). Use scripts/starttls_probe.py (see references/tls-starttls-testing.md).
Verified-good external result: TLS 1.3 TLS_AES_256_GCM_SHA384, issuer Let's Encrypt, SAN nixg.ru+xmpp.nixg.ru on BOTH 5222 and 5269.
Renewal — MANUAL and easy to forget
- LE certs live 90 days. With
--manualdns-01 the certbot systemd timer CANNOT renew (it cannot create TXT records on its own). - Renewal: run
sudo certbot renew --manual-auth-hook /bin/true --manual-cleanup-hook /bin/true(or repeat the certonly command) → add the NEW TXT values in the panel → re-run → copy fresh certs tocerts/→ restart prosody. - Schedule a reminder ~6 weeks before expiry (Hermes cron job works; 2026-10-15 for the 2026-11-26 expiry).