-- Prosody configuration for a small home XMPP server -- From the homebrewserver.club guide: -- https://homebrewserver.club/configuring-a-modern-xmpp-server.html -- -- Written for Prosody 13.0. Checked with "prosodyctl check config" on -- Prosody 13.0.7 (packages.prosody.im) on Debian 13 in a container, -- 5 November 2026. -- -- Before you use it: -- 1. Replace every "example.org" with your own domain. -- 2. Replace the admin address with the account you will create for yourself. -- 3. If you set up audio/video calls, put the same long random secret here -- (turn_external_secret) and in coturn's static-auth-secret. If you do not -- run a TURN server yet, leave "turn_external" commented out. -- 4. Copy the file to /etc/prosody/prosody.cfg.lua and run: -- sudo prosodyctl check config -- -- Settings before the first VirtualHost line apply to the whole server. -- Settings after a VirtualHost or Component line apply only to that host. ---------- Server-wide settings ---------- -- Accounts with admin rights. Create the account itself with -- "prosodyctl adduser admin@example.org". admins = { "admin@example.org" } -- Modules loaded for every VirtualHost. -- Full list and documentation: https://prosody.im/doc/modules modules_enabled = { -- Needed for a working server "disco"; -- Service discovery (XEP-0030) "roster"; -- Contact lists "saslauth"; -- Logging in "tls"; -- Encrypted connections -- Needed by modern mobile and desktop clients "blocklist"; -- Blocking other users (XEP-0191) "bookmarks"; -- Synced list of group chats (XEP-0402) "carbons"; -- Copy messages to all your devices (XEP-0280) "mam"; -- Server-side message archive (XEP-0313) "smacks"; -- Stream management: survive flaky mobile connections (XEP-0198) "csi_simple"; -- Hold back unimportant traffic while the phone is idle (XEP-0352) "cloud_notify"; -- Push notifications to sleeping phones (XEP-0357) "pep"; -- Personal eventing: avatars, OMEMO keys (XEP-0163) "private"; -- Older private storage some clients still use (XEP-0049) "vcard4"; -- Profiles stored in PEP (XEP-0292) "vcard_legacy"; -- Converts between old vCard and PEP avatars (XEP-0398) "server_contact_info"; -- Publishes the abuse/admin contact (XEP-0157) -- Accounts and invitations "register"; -- Password changes and registration "invites"; -- Invitation links "invites_adhoc"; -- Create invites from an XMPP client "invites_register"; -- Register with an invite only -- Server-to-server and housekeeping "dialback"; -- Fallback verification of other servers "limits"; -- Bandwidth limits per connection "ping"; -- Answer XMPP pings "time"; -- Answer time requests "uptime"; -- Answer uptime requests "version"; -- Answer version requests "account_activity"; -- Record when each account was last used -- Administration "admin_adhoc"; -- Admin commands from an XMPP client "admin_shell"; -- "prosodyctl shell" on the server -- Audio/video calls: hands out TURN credentials (XEP-0215). -- Enable it once coturn runs, see -- https://homebrewserver.club/server-support-for-audio-video-calls.html --"turn_external"; } -- Require valid certificates from other servers. s2s_secure_auth = true -- Rate limits per connection (values from Prosody's default config). limits = { c2s = { rate = "10kb/s"; }; s2sin = { rate = "30kb/s"; }; } -- Store passwords as salted hashes. authentication = "internal_hashed" -- Data in flat files under /var/lib/prosody. Fine for a few dozen users. storage = "internal" -- Message archive (mod_mam). Clients fetch missed messages from here. -- Keep messages for 2 weeks, then delete them. archive_expires_after = "2w" -- Archive one-to-one chats for every user unless they opt out (the default). default_archive_policy = true -- Ports. 5222 (clients) and 5269 (other servers) are the defaults and use -- STARTTLS. Port 5223 accepts direct TLS (XEP-0368), which gets through -- some restrictive networks more easily. c2s_direct_tls_ports = { 5223 } -- HTTPS for file sharing. Prosody serves HTTPS on 5281 by default. -- Plain HTTP (5280) only listens on localhost. https_ports = { 5281 } -- Contact addresses shown to other servers and users (XEP-0157). contact_info = { admin = { "xmpp:admin@example.org", "mailto:admin@example.org" }; abuse = { "xmpp:admin@example.org", "mailto:admin@example.org" }; } -- Audio/video calls (mod_turn_external). Must match coturn's settings. -- The host must be the public name of the TURN server, never 127.0.0.1. turn_external_host = "turn.example.org" turn_external_port = 3478 turn_external_secret = "replace-with-a-long-random-secret" -- Invitations: invite links are valid for 7 days. invite_expiry = 86400 * 7 -- Debian keeps the PID file here; systemd uses it. pidfile = "/run/prosody/prosody.pid" -- Log to files. Change "info" to "debug" while troubleshooting. log = { info = "/var/log/prosody/prosody.log"; error = "/var/log/prosody/prosody.err"; } -- Certificates are loaded from /etc/prosody/certs. Import Let's Encrypt -- certificates with: sudo prosodyctl --root cert import /etc/letsencrypt/live certificates = "certs" ---------- Virtual host ---------- VirtualHost "example.org" -- Registration is allowed, but mod_invites_register only accepts -- people who have an invite link from you or an existing user. allow_registration = true ---------- Components ---------- -- Group chats (XEP-0045) on conference.example.org, with a message -- archive per room so phones can catch up (XEP-0313). Component "conference.example.org" "muc" modules_enabled = { "muc_mam" } -- Only accounts on example.org may create rooms. restrict_room_creation = "local" -- Rooms keep their history for the same time as personal archives. muc_log_expires_after = "2w" -- File sharing (XEP-0363). Clients upload photos and files here over HTTPS. Component "upload.example.org" "http_file_share" -- Lets the users of example.org use this component. parent_host = "example.org" -- Largest single file: 100 MiB. http_file_share_size_limit = 100 * 1024 * 1024 -- Each user may upload up to 1 GiB per day. http_file_share_daily_quota = 1024 * 1024 * 1024 -- Stop accepting uploads when the store reaches 10 GiB. http_file_share_global_quota = 10 * 1024 * 1024 * 1024 -- Delete uploaded files after 2 weeks. http_file_share_expires_after = "2w" ---------- End of configuration ---------- -- Do not add settings below this line: they would apply only to the last -- Component above.