
Modern messaging: Running your own XMPP server
Since a years we know, or might suspect, our chats are listend on, our uploaded files are sold for advertising or what purpose ever and the chance our social messengers leak our private data is incredibly high. It is about time to work against this.
Since 3 years the European Commission works on a plan to automatically monitor all chat, email and messenger conversations.12 If this is going to pass, and I strongly hope it will not, the European Union is moving into a direction we know from states suppressing freedom of speech.
I went for setting up my own XMPP server, as this does not have any big resource requirements and still support clustering (for high-availabilty purposes), encryption via OMEMO, file sharing and has support for platforms and operating systems. Also the ecosystem with clients and multiple use cases evolved over the years to provide rock-solid software and solutions for multi-user chats or event audio and video calls.
Info
All steps and settings are bundled in a repository containing Ansible roles: https://codeberg.org/codedge/chat
All code snippets written below work in either Debian os Raspberry Pi OS.
Setting up your own XMPP server
The connection from your client to the XMPP server is encrypted and we need certificates for our server. First thing to do is setting up our domains and point it to the IP - both IPv4 and IPv6 is supported and we can specify both later in our configuration.
I assume the server is going to be run under xmpp.example.com
and you all the following domains have been set up.
Type | Name | Content | Notes |
---|---|---|---|
A | xmpp.example.com | IP addr | your main xmpp server address |
A | conference.xmpp.example.com | IP addr | needed for MUC (Multi User Chat) |
A | proxy.xmpp.example.com | IP addr | needed for SOCKS5 proxy support |
A | pubsub.xmpp.example.com | IP addr | needed for publish/subscribe support |
A | upload.xmpp.example.com | IP addr | needed for file uploads |
A | stun.xmpp.example.com | IP addr | needed for audio&video calling |
A | turn.xmpp.example.com | IP addr | needed for audio&video calling |
Fill in the IPv6 addresses accordingly.
ejabberd is a robust server software, that is included in most Linux distributions.
Install from Process One repository
I discovered ProcessOne, the company behind ejabberd, also provides a Debian repository.
|
|
Install from Github
To get the most recent one, I use the packages offered in their code repository.
Installing version 25.07 just download the asset from the release:
|
|
Make sure the fowolling ports are opened in your firewall, taken from ejabberd firewall settings.
- 5222: Jabber/XMPP client connections, plain or STARTTLS
- 5223: Jabber client connections, using the old SSL method
- 5269: Jabber/XMPP incoming server connections
- 5280/5443: HTTP/HTTPS for Web Admin and many more
- 7777: SOCKS5 file transfer proxy
- 3478/5349: STUN+TURN/STUNS+TURNS service
Port 1883
, used for MQTT, is also mentioned in the ejabberd docs, but we do not use this in our setup. So this port stays closed.
Depending how you installed ejabberd the config file is either at /etc/ejabberd/conf/ejabberd.yml
or /opt/ejabberd/conf/ejabberd.yml
.
General configuration
The configuration is a balance of 70:30 between having a privacy-focused setup for your users and meeting most of the suggestions of the XMPP complicance test. That means, settings that protect the provacy of the users are higher rated despite not passing the test.
Therefore notable privacy and security settings are:
- XMPP over HTTP is disabled (mod_bosh)
- Discover then a user last accessed a server is disabled (mod_last)
- Delete uploaded files on a regular base (see upload config)
- Register account via a web page is disabled (mod_register_web)
- In-band registration can be enabled, default off, captcha secured (mod_register, see registration config)
Info
The configuration file is in YAML format. Keep an eye for indentation.
Let’s start digging into the configuration.
Set the domain of your server
|
|
Set the database type
Instead of using the default mnesia
type, we opt for sql
, better said sqlite
.
|
|
Generate DH params
Generate a fresh set of params for the DH key exchange. In your terminal run
|
|
and link the new file in the ejabberd configuration.
|
|
Ensure TLS for server-to-server connections
Use TLS for server-to-server (s2s) connections.
|
|
The listners
The listeners aka request_handlers
inside the config especially for /admin
, /captcha
, /upload
and /ws
are important.
All of them listen on port 5443
. Only one request handler is attached to port 5280
, the /.well-known/acme-challenge
.
|
|
Enable file uploads
Enabling file uploads is done with mod_http_upload
.
First, create a folder where the uploads should be stored.
|
|
Now update the ejabberd configuration like this:
|
|
The allowed file upload size is defined in the max_size
param and is set to 10MB.
Make sure, to delete uploaded files in a reasonable amount of time via cronjob. This is an example of a cronjob, that deletes files that are older than 1 week.
|
|
Registration
Registration in ejabberd is done via mod_register
and can be enabled with these entries in the config file:
|
|
If you want to enable registration for your server make sure you enable a captcha for it. Otherwise you will get a lot of spam and fake registrations.
ejabberd provides a working captcha script,
that you can copy to your server and link in your configuration. You will need imaggemagick
and gstools
installed
on you system. In the ejabberd.yml
config file
Add TLS
ejabberd can provision TLS certificates on its own. No need to install certbot. To not expose ejabberd directly to
the internet, nginx
is put in front of the XMPP server. Instead of using nginx, every other web server (caddy, …)
or proxy can be used as well.
Here is a sample config for nginx:
|
|
Choose your client
Clients I can recommend are Profanity, an easy to use command-line client, and Monal for MacOS and iOS. A good overview of client can be found on the offical XMPP website.
Citizen-led initiative collecting information about Chat Controle https://fightchatcontrol.eu ↩︎
Explanation by Patrick Breyer, former member of the European Parliament https://www.patrick-breyer.de/en/posts/chat-control/ ↩︎