mirror of
https://gitverse.ru/kpa39l/xmpp-server-prosody.git
synced 2026-09-29 09:45:02 +00:00
Initial commit: Hermes skill xmpp-server-prosody
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
---
|
||||
name: xmpp-server-prosody
|
||||
title: "XMPP Server Deployment (Prosody)"
|
||||
description: "Deploy federated XMPP (Prosody in Docker) behind a proxy."
|
||||
---
|
||||
|
||||
# XMPP Server Deployment (Prosody)
|
||||
|
||||
Deploy a self-hosted federated XMPP messenger (family/team) with **Prosody** in Docker, exposed through a public VPS reverse proxy. Produced from the ICQ project (chat.nixg.ru) on the bigbox/vps02 infrastructure.
|
||||
|
||||
## When to use
|
||||
- User wants a self-hosted messenger (family, team) with iOS/Android clients and **federation** (talking to the whole XMPP network).
|
||||
- Choosing XMPP: it is the federated standard (like email). **Do not** attempt to "clone Telegram/MTProto" — it is closed, centralised, non-federated. XMPP is the right answer when federation matters.
|
||||
- Snikket vs Prosody: Snikket server is easier but assumes direct 443 access and is finicky behind a reverse proxy. **Prosody** is the right choice when going through a Caddy/reverse-proxy + WireGuard setup.
|
||||
|
||||
## Architecture (this environment)
|
||||
|
||||
```
|
||||
[Clients: Monal/Snikket/Conversations iOS+Android]
|
||||
│ c2s 5222 (TLS)
|
||||
▼
|
||||
[bigbox] Prosody Docker (/opt/icq) — no public IP
|
||||
│ s2s 5269 (federation) · http 5280 (websocket/BOSH)
|
||||
▼
|
||||
[vps02] Caddy (host-network, reverse_proxy 10.8.0.2:5280) + iptables DNAT 5222/5269 → 10.8.0.2
|
||||
▲
|
||||
└─ WireGuard wg0 (10.8.0.x)
|
||||
```
|
||||
|
||||
## DNS records (critical for federation)
|
||||
|
||||
```
|
||||
A chat.nixg.ru → public IP of vps02
|
||||
SRV _xmpp-client._tcp.chat.nixg.ru → chat.nixg.ru:5222 (priority 0, weight 5)
|
||||
SRV _xmpp-server._tcp.chat.nixg.ru → chat.nixg.ru:5269 (priority 0, weight 5)
|
||||
A conference.chat.nixg.ru → public IP (MUC component host)
|
||||
```
|
||||
|
||||
- **Without SRV records, other servers cannot find you → federation silently fails.** For a standard XMPP domain hosted at a subdomain, prosodyctl suggests using SRV to redirect; that is fine.
|
||||
- A-record alone works for clients hardcoded to the domain, but SRV is what the federated network uses.
|
||||
|
||||
## docker-compose.yml
|
||||
|
||||
```yaml
|
||||
services:
|
||||
prosody:
|
||||
image: prosody/prosody:latest
|
||||
container_name: icq-prosody
|
||||
restart: unless-stopped
|
||||
hostname: chat.nixg.ru
|
||||
volumes:
|
||||
- ./data:/var/lib/prosody
|
||||
- ./config:/etc/prosody
|
||||
- ./certs:/etc/prosody/certs
|
||||
- ./modules:/etc/prosody/modules
|
||||
- ./logs:/var/log/prosody
|
||||
ports:
|
||||
- "5222:5222" # c2s clients
|
||||
- "5269:5269" # s2s federation
|
||||
- "5280:5280" # BOSH/websocket (behind Caddy)
|
||||
# - "5281:5281" # https — SKIP unless you have a cert wired
|
||||
```
|
||||
|
||||
Remove the obsolete `version:` attribute (Compose v2 warns).
|
||||
|
||||
## prosody.cfg.lua pitfall checklist
|
||||
|
||||
- **`modules_enabled` must NOT contain `muc`** — MUC is a Component (`Component "conference.chat.nixg.ru" "muc"`). Loading `muc` as a module errors out.
|
||||
- **`muc_mam`** loads only on a MUC component, not on the host.
|
||||
- **`log` block must be in the GLOBAL section**, above any VirtualHost/Component, or `prosodyctl check config` complains.
|
||||
- **Community modules NOT in the stock image** (prosody/prosody:latest): `http_upload`, `smacks`, `s2s_bidi`, `xmpp_component`. They come from the prosody-modules community repo — either install them or leave them out. HTTP Upload (XEP-0363, needed for bot file delivery) requires installing `mod_http_upload` manually.
|
||||
- **`prosodyctl register <user> <domain> <pass>`** works inside the container; do NOT use `-it` (fails "cannot attach stdin"). Data dir is URL-encoded: `/var/lib/prosody/chat%2enixg%2eru/accounts/`.
|
||||
- **https 5281 bind error** ("No certificate present") is benign — the stock image tries to bind it by default. Disable by not mapping the port; it does not break c2s/s2s/http.
|
||||
- **Prosody 13.0 != 0.11 for external components**: `component_ports` was REMOVED (listener is hardcoded 5347); a module-less `Component "jid"` block is required to raise the listener; `component_interfaces` must be in the GLOBAL section; `log = {...}` may only appear ONCE in the config. mod_privilege (XEP-0356) needs the TIP version (promise API) and must be enabled on BOTH the component block and the VirtualHost. Full recipe + gotchas: `references/prosody-13-parallel-stand.md`.
|
||||
- Validate: `docker exec icq-prosody prosodyctl check config` → "All checks passed".
|
||||
- `allow_registration = true` enables in-band registration — flip off after family accounts are created.
|
||||
|
||||
## Exposing through vps02 (Caddy + WireGuard + iptables)
|
||||
|
||||
Caddy on vps02 runs `network_mode: host` with a plain Caddyfile. Add:
|
||||
|
||||
```
|
||||
chat.nixg.ru {
|
||||
reverse_proxy 10.8.0.2:5280 {
|
||||
header_up Host {host}
|
||||
header_up X-Forwarded-Proto https
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Caddy auto-issues Let's Encrypt TLS. Reload: `docker exec caddy caddy reload --config /etc/caddy/Caddyfile`.
|
||||
|
||||
For non-HTTP ports (5222 c2s, 5269 s2s) Caddy cannot proxy them — use iptables DNAT on vps02. Existing pattern (mirrors the 8443 rule already present):
|
||||
|
||||
```bash
|
||||
sudo iptables -t nat -A PREROUTING -p tcp --dport 5222 -j DNAT --to-destination 10.8.0.2:5222
|
||||
sudo iptables -t nat -A PREROUTING -p tcp --dport 5269 -j DNAT --to-destination 10.8.0.2:5269
|
||||
sudo iptables -I INPUT -p tcp --dport 5222 -j ACCEPT
|
||||
sudo iptables -I INPUT -p tcp --dport 5269 -j ACCEPT
|
||||
sudo iptables -I FORWARD 1 -d 10.8.0.2 -p tcp --dport 5222 -j ACCEPT
|
||||
sudo iptables -I FORWARD 1 -d 10.8.0.2 -p tcp --dport 5269 -j ACCEPT
|
||||
sudo iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 5222 -j MASQUERADE
|
||||
sudo iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 5269 -j MASQUERADE
|
||||
# persist:
|
||||
sudo sh -c "iptables-save > /etc/iptables/rules.v4"
|
||||
```
|
||||
|
||||
- **FORWARD policy is DROP** by default on vps02 — you MUST add FORWARD ACCEPT rules (the 8443 precedent has them). DNAT alone is not enough.
|
||||
- Save via `sudo sh -c "iptables-save > /etc/iptables/rules.v4"` — plain `sudo iptables-save > file` fails (redirect runs as your user, not root). `netfilter-persistent` service is enabled.
|
||||
|
||||
## Testing the external path — hairpin NAT trap
|
||||
|
||||
- **Do NOT test a host's public ports from the same host** (or from a host that routes back into it). `ip route get <pub-ip>` shows `<local>` → traffic never leaves the box, DNAT never fires. `Connection refused` from such tests is a FALSE NEGATIVE.
|
||||
- Validate the path instead:
|
||||
- From vps02 → `10.8.0.2:5222` over WG (real path, with tcpdump on bigbox wg0 shows the TCP handshake).
|
||||
- From an EXTERNAL host (phone on mobile data, another VPS): `nc -vz chat.nixg.ru 5222`.
|
||||
- If both internal paths work but an external probe fails, suspect the **provider's cloud firewall panel** (Timeweb etc.) — ports 5222/5269 are commonly closed there by default. Ask the user to open them in the provider panel.
|
||||
- 443 via Caddy IS externally testable from anywhere; a working 443 + working WG path to 5222 usually means only the provider firewall is in the way.
|
||||
|
||||
## Bots (slixmpp) and file delivery
|
||||
|
||||
- An XMPP bot is just a second user account (JID) — no separate Bot API. Python `slixmpp` is the live, mature library.
|
||||
- To send files (e.g. a book-download bot), the server needs HTTP Upload (XEP-0363) — community module `mod_http_upload` (not in stock image). The client sends the file to the upload component; the recipient gets a link.
|
||||
- Bot pattern: user messages `book@chat.nixg.ru` → bot queries an OPDS catalog (Flibusta et al.) → downloads epub/fb2 → uploads via HTTP Upload → sends link.
|
||||
|
||||
## References
|
||||
- `references/vps02-bigbox-wg-access.md` — exact vps02/bigbox network topology, Caddyfile, iptables persistence and hairpin-test evidence.
|
||||
Reference in New Issue
Block a user