Prosody

Prosody is a lightweight XMPP server you can self-host.

Install packages

apt update && apt upgrade # udpate the system apt install prosody prosody-modules # prosody and modules apt install postgresql # database management system apt install lua-dbi-postgresql # helps lua handle postgresql apt install lua-sec luarocks # optional for 3rd parties modules

Configuration file

Change config file according to your needs here : /etc/prosody/prosody.cfg.lua Here is an example :

-- Prosody Config File -- /etc/prosody/prosody.cfg.lua > admins = { "username@example.org" } plugin_paths = { "/usr/local/lib/prosody/modules" } modules_enabled = { "disco"; -- Service discovery "roster"; -- Allow users to have a roster. Recommended ;) "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. "tls"; -- Add support for secure TLS on c2s/s2s connections "blocklist"; -- Allow users to block communications with other users "bookmarks"; -- Synchronise the list of open rooms between clients "carbons"; -- Keep multiple online clients in sync "dialback"; -- Support for verifying remote servers using DNS "limits"; -- Enable bandwidth limiting for XMPP connections "pep"; -- Allow users to store public and private data in their account "private"; -- Legacy account storage mechanism (XEP-0049) "smacks"; -- Stream management and resumption (XEP-0198) "vcard4"; -- User profiles (stored in PEP) "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard "csi_simple"; -- Simple but effective traffic optimizations for mobile devices "invites"; -- Create and manage invites "invites_adhoc"; -- Allow admins/users to create invitations via their client "invites_register"; -- Allows invited users to create accounts "ping"; -- Replies to XMPP pings with pongs "register"; -- Allow users to register on this server using a client and change passwords "time"; -- Let others know the time here on this server "uptime"; -- Report how long server has been running "version"; -- Replies to server version requests "mam"; -- Store recent messages to allow multi-device synchronization "turn_external"; -- Provide external STUN/TURN service for e.g. audio/video calls "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands "admin_shell"; -- Allow secure administration via 'prosodyctl shell' "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. "announce"; -- Send announcement to all online users "motd"; -- Send a message to users when they log in } modules_disabled = { } pidfile = "/run/prosody/prosody.pid"; s2s_secure_auth = true limits = { c2s = { rate = "10kb/s"; }; s2sin = { rate = "30kb/s"; }; } authentication = "internal_hashed" storage = "sql" sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "PASSWORD", # we will set this database in a few minutes host = "localhost" } -- turn_external_host = "turn.example.org" -- turn_external_secret = "TURNPASSWORD" -- turn_external_port = 5349 # useful if TURN uses another port than default log = { info = "/mnt/drive/xmpp/prosody/prosody.log"; error = "/mnt/drive/xmpp/prosody/prosody.err"; { levels = { "error" }; to = "syslog"; }; } certificates = "certs" VirtualHost "example.org" Component "conference.example.org" "muc" modules_enabled = { "muc_mam", "vcard_muc" } Component "upload.example.org" "http_file_share" Component "proxy.example.org" "proxy65" Include "conf.d/*.cfg.lua"

Components like {conference,upload,proxy}.example.org are services your XMPP server is going to offer. You can disable them. Here is what they are for :

  • conference.example.org: Allow Multi-User Chat
  • upload.example.org: Allow file-sharing between users (images, videos, etc.)
  • proxy.example.org: Facilitates files transfer behind NAT
  • TLS certificates

    TLS certificates are needed for your domain and the components. Generate them with certbot:

    certbot -d example.org certbot -d proxy.example.org certbot -d upload.example.org certbot -d conference.example.org

    Then import them in Prosody:

    prosodyctl --root cert import /etc/letsencrypt/live prosodyctl check # Check if everything is fine

    Create PostgreSQL database

    User accounts and other informations are going to be stored in a PostgreSQL database.

    sudo -i # be sure to be root sudo su - postgres # log as postgres user createuser --pwprompt prosody psql -c 'CREATE DATABASE prosody OWNER prosody;' exit # back to root systemctl restart postgresql netstat -tunlp | grep 5432 # check postgresql listens on port 5432 systemctl enable postgresql # is it useful to enable postgresql? I did.

    Side note

    I had some troubles getting the PostgreSQL database up, due to permission errors. Using sudo su - postgres and executing postgres command from its own user; instead of su -c "command" postgresql when setting things up helped (I guess).

    Open ports

    Open 5222 (standard XMPP port), 5281 (file uploads) and 5269 (federation, HTTPS) on your router to redirect to your machine. Also open those ports on the firewall if you have one.

    ufw allow 5222 5281 5269 # assuming your firewall is ufw

    Start the services

    systemctl restart postgresql systemctl restart prosody

    Everything should be ready.

    Create a test account

    Create an ephemeral unprivileged account that we will delete after testing the server :

    prosodyctl adduser test@example.org

    Connect from a client

    On Android phones there is Snikket or Conversation (free on F-Droid). On Linux you can use profanity (lightweight TUI client with good level of logs).

    apt install profanity tail -f ~/.local/share/profanity/logs/profanity.log # in another terminal : profanity -l DEBUG # logs level debug

    Now in profanity use /connect test@example.org and type your password to see if everything is fine. If there are errors or difficulties during connection, you'll see that in the logs.

    Check for compliance

    To check for compliance to XMPP standards, visit https://compliance.conversations.im and provide the login informations of your test account (remember it must be a non-privileged user of your server!).

    Services offered by your server will be evaluated and returned a true/false functionning state. It is up to you to look into it and tweak your instance to change that.

    Add/remove users

    prosodyctl adduser username@example.org # add new user prosodyctl deluser username@example.org # remove user prosodyctl passwd username@example.org # change password for user

    Install other modules

    prosodyctl install --server=https://modules.prosody.im/rocks/ mod_cloud_notify

    Send announce to online users

    Admins can send announce to online users by messaging example.org/announce/online. In profanity :

    /msg example.org/announce/online
    chessgitxmppbookswallet