Files
xmpp-server-prosody/references/letsencrypt-dns01-prosody.md
2026-09-06 13:51:11 +00:00

3.2 KiB
Raw Permalink Blame History

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 -a then sudo 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 +short and dig @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 --manual dns-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 to certs/ → restart prosody.
  • Schedule a reminder ~6 weeks before expiry (Hermes cron job works; 2026-10-15 for the 2026-11-26 expiry).