Jingle A/V (XEP-0166/0167/0176) needs a STUN/TURN server for NAT traversal. Add coturn and advertise it to clients via XEP-0215. - coturn container, host networking (a relay needs its full UDP port range reachable, and Docker NAT hides the peer addresses coturn needs). - mod_turn_external in Prosody to advertise the service and mint time-limited credentials from a shared secret. - Advertise UDP and TCP transports plus turns: on 5349, so clients on UDP-blocking networks can still connect. - Deny relaying to private ranges, so this is not an open proxy into internal services. TURN host is guschin.info rather than turn.guschin.info because only the former is in the certificate SANs and turns: clients validate the name. TURN_HOST/TURN_SECRET go in .env, which is gitignored and set per deployment; TURN_SECRET must match static-auth-secret in turnserver.conf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
145 lines
4.6 KiB
Markdown
145 lines
4.6 KiB
Markdown
# Prosody XMPP Server
|
|
|
|
Dockerized Prosody XMPP server with MySQL backend.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker and Docker Compose
|
|
- External MySQL network: `mysqlgit_mysql_network`
|
|
- Environment variables configuration (see Configuration section)
|
|
|
|
## Configuration
|
|
|
|
This setup uses environment variables for configuration. Create a `.env` file in the project root with:
|
|
|
|
```env
|
|
# XMPP Configuration
|
|
XMPP_DOMAIN=xmpp.guschin.info
|
|
XMPP_USER=mish
|
|
XMPP_PASSWORD=your_password
|
|
|
|
# MySQL Configuration
|
|
MYSQL_HOST=mysql
|
|
MYSQL_USER=prosody
|
|
MYSQL_PASSWORD=your_mysql_password
|
|
MYSQL_DATABASE=prosody
|
|
```
|
|
|
|
## Starting the Server
|
|
|
|
Run from the project directory:
|
|
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
This will:
|
|
- Build and start the Prosody container
|
|
- Connect to external MySQL network (`mysqlgit_mysql_network`)
|
|
- Wait for MySQL to be ready
|
|
- Generate self-signed SSL/TLS certificates (if not present)
|
|
- Configure Prosody with MySQL backend
|
|
|
|
## Access Points
|
|
|
|
| Service | Port | Description |
|
|
|---------|------|-------------|
|
|
| C2S (Client to Server) | 5222 | XMPP client connections |
|
|
| S2S (Server to Server) | 5269 | XMPP federation |
|
|
| Component Protocol | 5347 | External components |
|
|
| HTTP/BOSH/WebSocket | 5280 | Web-based connections |
|
|
| HTTPS | 5281 | Secure web connections |
|
|
| STUN/TURN | 3478 (UDP+TCP) | NAT traversal for audio/video calls |
|
|
| STUN/TURN over TLS | 5349 (UDP+TCP) | Encrypted TURN (`turns:`) |
|
|
| TURN relay range | 49160-49200 (UDP) | Media relay ports |
|
|
|
|
## Features
|
|
|
|
- **Virtual Host**: `xmpp.guschin.info`
|
|
- **Multi-User Chat (MUC)**: `muc.xmpp.guschin.info`
|
|
- **Storage**: MySQL backend with SQL storage
|
|
- **Admin User**: `admin@guschin.info`
|
|
- **Health Checks**: Automatic container health monitoring
|
|
- **Memory Limit**: 200M
|
|
- **Auto-restart**: Container restarts unless stopped
|
|
|
|
## Enabled Modules
|
|
|
|
Core modules: roster, saslauth, tls, dialback, disco, carbons, pep, private, blocking, vcard, version, uptime, time, ping, register, last_activity, admin_adhoc, muc_mam
|
|
|
|
## Data Persistence
|
|
|
|
Volumes are mounted to persist data:
|
|
- `./data/prosody` → `/var/lib/prosody`
|
|
- `./logs/prosody` → `/var/log/prosody`
|
|
- `./data/prosody/configuration` → `/etc/prosody/conf.d`
|
|
|
|
## Connecting Clients
|
|
|
|
Use any XMPP client with:
|
|
- **Server**: xmpp.guschin.info
|
|
- **Port**: 5222
|
|
- **Username**: your configured user
|
|
- **Domain**: xmpp.guschin.info
|
|
|
|
## Audio/Video Calls (Jingle)
|
|
|
|
Voice and video calls use Jingle (XEP-0166/0167/0176). Prosody only carries the
|
|
signalling; media flows directly between clients, falling back to a TURN relay
|
|
when NAT prevents a direct path.
|
|
|
|
Two pieces make this work:
|
|
|
|
- **coturn** (`coturn` container) — the STUN/TURN server. Runs with host
|
|
networking because a relay needs its whole UDP port range reachable.
|
|
- **`mod_turn_external`** in Prosody — advertises coturn to clients over
|
|
XEP-0215 and issues time-limited TURN credentials.
|
|
|
|
### Configuration
|
|
|
|
`TURN_SECRET` in `.env` must match `static-auth-secret` in
|
|
[coturn/turnserver.conf](coturn/turnserver.conf). `.env` is gitignored, so
|
|
these values are set per-deployment and not committed:
|
|
|
|
```env
|
|
TURN_HOST=guschin.info
|
|
TURN_SECRET=<same value as static-auth-secret>
|
|
```
|
|
|
|
`TURN_HOST` is `guschin.info`, not `turn.guschin.info`: `turns:` (TLS) clients
|
|
validate the hostname against the certificate, and only `guschin.info` is in
|
|
the current cert's SANs. To use `turn.guschin.info` instead, reissue the
|
|
certificate with that name added and update both `TURN_HOST` and the
|
|
`external-ip`/`cert` settings accordingly.
|
|
|
|
`external-ip` in `turnserver.conf` is the server's public address. **Update it
|
|
if the server IP changes**, otherwise coturn advertises relay candidates that
|
|
peers cannot reach.
|
|
|
|
### Verifying
|
|
|
|
Check that Prosody advertises the service and coturn answers:
|
|
|
|
```bash
|
|
docker logs coturn # should show listeners on 3478/5349
|
|
docker exec prosody-xmpp prosodyctl check config
|
|
```
|
|
|
|
From a client, place a call between two accounts. Clients that support Jingle
|
|
audio/video include Conversations (Android), Dino, Gajim, and Monal (iOS).
|
|
Note that Jingle A/V is client-to-client — both parties need a client that
|
|
supports it.
|
|
|
|
### Firewall
|
|
|
|
Ports 3478 and 5349 (both UDP and TCP) plus the UDP relay range 49160-49200
|
|
must be reachable from the internet. The host has no local firewall
|
|
(`iptables` INPUT policy is ACCEPT), but any provider-level firewall needs
|
|
these opened.
|
|
|
|
## Notes
|
|
|
|
- TLS encryption is not required by default (configurable in [prosody.cfg.lua](data/prosody/configuration/prosody.cfg.lua))
|
|
- Self-signed certificates are auto-generated on first run
|
|
- The container depends on an external MySQL network named `mysqlgit_mysql_network`
|