tutorial

Monitoring Prosody XMPP Server with Vigilmon

Prosody is a lightweight, open-source XMPP (Jabber) server written in Lua. Here's how to monitor its client and server ports, BOSH/WebSocket endpoints, SSL certificates, and service uptime with Vigilmon.

Prosody is a lightweight, open-source XMPP (Jabber) server written in Lua, widely used for self-hosted instant messaging, IoT device communication, and federated chat systems. XMPP is a real-time protocol — when Prosody goes down, messages stop flowing immediately, but the failure can be invisible if no one is actively trying to connect. Vigilmon gives you continuous visibility into Prosody's client connection port, server-to-server federation port, BOSH and WebSocket HTTP endpoints, TLS certificates, and overall service health so you catch outages before your users or devices notice.

What You'll Set Up

  • TCP monitor for the XMPP client port (5222)
  • TCP monitor for the server-to-server federation port (5269)
  • HTTP monitor for the BOSH or WebSocket endpoint
  • SSL certificate expiry alerts for XMPP TLS
  • Heartbeat monitoring for Prosody service uptime

Prerequisites

  • Prosody 0.12+ running on a Linux server
  • Ports 5222, 5269, and optionally 5280/5281 (BOSH/WebSocket) accessible from the internet
  • A free Vigilmon account

Step 1: Monitor the XMPP Client Port (5222 TCP)

XMPP clients (Conversations, Gajim, Dino, etc.) connect to Prosody on TCP port 5222 using STARTTLS. A TCP monitor on this port confirms Prosody is listening and accepting client connections.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to TCP Port.
  3. Set Host to your Prosody server's hostname or IP address.
  4. Set Port to 5222.
  5. Set Check interval to 1 minute.
  6. Click Save.

A successful TCP connection means the Prosody process is running and accepting connections on the client port. A connection refused or timeout means the process has crashed, the port is firewalled, or the system is down.

Verify the port is open from the command line:

nc -zv your-xmpp-server.example.com 5222
# Connection to your-xmpp-server.example.com 5222 port [tcp/*] succeeded!

Step 2: Monitor the Server-to-Server Federation Port (5269 TCP)

XMPP federation — the ability for users on one server to communicate with users on another — uses TCP port 5269. If port 5269 goes down, your users can still connect to your server but cannot exchange messages with contacts on other XMPP servers (Gmail XMPP, Jabber.org, etc.).

Add a TCP monitor for the federation port:

  1. Click Add MonitorTCP Port.
  2. Host: your Prosody server hostname.
  3. Port: 5269.
  4. Check interval: 1 minute.
  5. Click Save.

Check whether Prosody is configured to listen on 5269:

-- /etc/prosody/prosody.cfg.lua
Component "conference.example.com" "muc"
-- s2s (server-to-server) is enabled by default
-- s2s_require_encryption = true

Verify:

ss -tlnp | grep 5269
# LISTEN  0  128  0.0.0.0:5269  0.0.0.0:*  users:(("lua5.4",pid=1234,fd=7))

Step 3: Monitor the BOSH / WebSocket HTTP Endpoint

Prosody supports two HTTP-based XMPP transports for web clients: BOSH (Bidirectional-streams Over Synchronous HTTP) and WebSocket. Both are served by the mod_bosh and mod_websocket modules on Prosody's built-in HTTP server, typically on port 5280 (plain HTTP) or 5281 (HTTPS).

Enable the modules in prosody.cfg.lua if not already active:

modules_enabled = {
  "bosh",
  "websocket",
  -- other modules...
}

-- HTTP ports
http_ports = { 5280 }
https_ports = { 5281 }

Add Vigilmon monitors for the BOSH endpoint:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://your-xmpp-server.example.com:5281/http-bind
  3. Check interval: 1 minute
  4. Expected HTTP status: 200
  5. Click Save.

The /http-bind path responds to GET requests with an XML error (which is correct BOSH behavior) and returns HTTP 200:

curl -s https://your-xmpp-server.example.com:5281/http-bind
# <body type='terminate' condition='bad-request'
#   xmlns='http://jabber.org/protocol/httpbind'/>

That 400 bad-request XML body inside a 200 OK HTTP response confirms the BOSH endpoint is live. Vigilmon only checks the HTTP status code, so 200 is the right expected value.

For WebSocket, test with:

curl -s -o /dev/null -w "%{http_code}" \
  -H "Upgrade: websocket" \
  -H "Connection: Upgrade" \
  https://your-xmpp-server.example.com:5281/xmpp-websocket
# 426 (Upgrade Required) — indicates the endpoint exists and is responding

You can add a monitor for the WebSocket path with expected status 426 or add the /xmpp-websocket path to the HTTP monitor with a keyword check for xmpp.


Step 4: SSL Certificate Alerts for XMPP TLS

Prosody uses TLS certificates for three distinct purposes:

  • Client-to-server (port 5222 STARTTLS)
  • Server-to-server (port 5269 STARTTLS)
  • HTTPS for BOSH/WebSocket (port 5281)

All three use the same certificate if configured via a single ssl block in prosody.cfg.lua. Monitor the HTTPS endpoint's certificate with Vigilmon to catch expiry:

  1. Click Add MonitorHTTP / HTTPS (or open the existing BOSH monitor).
  2. Enable Monitor SSL certificate.
  3. Set Alert when certificate expires in less than 21 days.
  4. Click Save.

Check your current certificate expiry:

openssl s_client -connect your-xmpp-server.example.com:5281 -servername your-xmpp-server.example.com \
  </dev/null 2>/dev/null | openssl x509 -noout -dates
# notBefore=Jan  1 00:00:00 2026 GMT
# notAfter=Apr  1 00:00:00 2026 GMT

Prosody supports automatic certificate reloading. After renewal (e.g., via Certbot), reload without restarting:

# Reload Prosody to pick up new certificates
prosodyctl reload
# or
systemctl reload prosody

A 21-day alert window gives you time to renew the certificate and reload Prosody before XMPP clients start getting TLS errors.


Step 5: Heartbeat Monitoring for Prosody Service Uptime

TCP port checks confirm Prosody is listening, but they do not guarantee that the XMPP session layer is functioning correctly. Use a cron heartbeat to send a periodic signal from the server itself — if Prosody is restarted by systemd, crashes, or enters a zombie state, the heartbeat stops.

Set up the heartbeat in Vigilmon:

  1. Click Add MonitorCron Heartbeat.
  2. Set the expected ping interval to 5 minutes.
  3. Copy the heartbeat URL: https://vigilmon.online/heartbeat/abc123.

On your Prosody server, create a systemd timer (or cron job) that checks Prosody's running state and pings Vigilmon:

# /usr/local/bin/prosody-heartbeat.sh
#!/bin/bash
if prosodyctl status 2>&1 | grep -q "Prosody is running"; then
  curl -sf https://vigilmon.online/heartbeat/abc123
fi
chmod +x /usr/local/bin/prosody-heartbeat.sh

Create a systemd timer to run it every 5 minutes:

# /etc/systemd/system/prosody-heartbeat.service
[Unit]
Description=Prosody heartbeat ping to Vigilmon

[Service]
Type=oneshot
ExecStart=/usr/local/bin/prosody-heartbeat.sh
# /etc/systemd/system/prosody-heartbeat.timer
[Unit]
Description=Run Prosody heartbeat every 5 minutes

[Timer]
OnBootSec=1min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target
systemctl enable --now prosody-heartbeat.timer

If prosodyctl status reports Prosody is not running (stopped, failed, or in a restart loop), the heartbeat script skips the curl call. Vigilmon alerts after 5 minutes of missed pings.


Step 6: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or a webhook.
  2. Set Consecutive failures before alert to 2 on the TCP port monitors — a brief Prosody restart on certificate reload can cause a single probe failure.
  3. Set Consecutive failures to 1 on the SSL certificate monitor — expiry does not self-heal.
  4. Set Consecutive failures to 1 on the heartbeat monitor — a single missed heartbeat window means Prosody has been down for at least 5 minutes.

Summary

| Monitor | Target | What It Catches | |---|---|---| | TCP port 5222 | Client connection port | Prosody crash, client port firewalled | | TCP port 5269 | S2S federation port | Federation broken, firewall change | | HTTP — BOSH | /http-bind on port 5281 | BOSH/WebSocket unavailable for web clients | | SSL certificate | HTTPS hostname on port 5281 | Certificate expiry, TLS failure | | Cron heartbeat | Heartbeat URL via shell script | Prosody stopped, systemd restart loop |

Prosody is a quiet server — it runs in the background handling real-time messages without producing visible output unless something goes wrong. With Vigilmon watching the client port, federation port, BOSH endpoint, TLS certificates, and a service heartbeat, you get immediate notification when any layer of your XMPP infrastructure fails — before users start reporting that their messages are not going through.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →