These tutorials are written by Freedom Lab members in their free time. If you find them helpful, please consider supporting our work.

TutorialsSelf-Hosted XMPP Server

Self-Hosted XMPP Server

Self-hosting Privacy Linux

Run your own XMPP server for private, federated messaging.

This guide covers installing and configuring Prosody on a Debian/Ubuntu VPS with TLS encryption.

Prerequisites

Secure SSH Access

After logging in, update your system:

sudo apt update && sudo apt upgrade -y

Edit the SSH configuration:

sudo vim /etc/ssh/sshd_config

Change the following settings (uncomment if needed):

Port 22222
PasswordAuthentication no
UsePAM no

Restart SSH:

sudo systemctl restart sshd

Setup Firewall

Install and configure UFW:

sudo apt install ufw -y
sudo ufw allow 22222/tcp
sudo ufw enable

Install Prosody

Install the XMPP server:

sudo apt install prosody -y

Configure Prosody

Edit the configuration file:

sudo vim /etc/prosody/prosody.cfg.lua

Make the following changes:

  1. Disable registration module — Comment out the register module to remove the registration feature entirely:
    --"register"; -- Allow users to register on this server using a client and change passwords
  2. Set your domain — Comment out VirtualHost "localhost" and add your domain:
    --VirtualHost "localhost"
    VirtualHost "example.com"
  3. Enable MAM (required for OMEMO multi-device sync) — Uncomment this line:
    "mam"; -- Store recent messages to allow multi-device synchronization
  4. Disable public registration globally — Add this at the end of the file as an extra safeguard (you can still create users via CLI):
    allow_registration = false

Restart Prosody:

sudo systemctl restart prosody

Setup TLS Certificate

OMEMO encrypts message content, but without TLS your credentials and metadata are sent in plaintext.

Open ports for Certbot verification:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Install Certbot:

sudo apt install certbot -y

Generate the certificate (replace with your domain):

sudo certbot certonly --standalone -d example.com

Import the certificate into Prosody:

sudo prosodyctl --root cert import /etc/letsencrypt/live/example.com

Restart Prosody:

sudo systemctl restart prosody

Open XMPP Ports

Open the required ports:

sudo ufw allow 5222/tcp
sudo ufw allow 5269/tcp

Create User Account

Create your XMPP account (replace with your username and domain):

sudo prosodyctl adduser username@example.com

Connect with a Client

Use an XMPP client like Gajim with OMEMO support:

sudo apt install gajim gajim-omemo -y

When connecting:

Verify TLS

Confirm TLS is working by checking the logs after connecting:

sudo tail -n 50 /var/log/prosody/prosody.log | grep TLS

You should see:

Stream encrypted (TLSv1.3 with TLS_AES_256_GCM_SHA384)