Are you tired of the government spying on you all the time, with proprietary messaging applications like Telegram and Whatsapp?
Fear no more, this tutorial will explain how to setup an ejabberd XMPP server with a basic configuration, along with enabling federation, in order to allow you to stay in touch with others online without any glowies looking over your shoulder.
This tutorial is also in video format, which you can find here.
Table Of Contents
DNS setup
To start, ensure you have the following DNS entries present on your domain registrar’s management interface:
liberatedsystems.co.uk A x.x.x.x
conference.liberatedsystems.co.uk A x.x.x.x
upload.liberatedsystems.co.uk A x.x.x.x
proxy.liberatedsystems.co.uk A x.x.x.x
pubsub.liberatedsystems.co.uk A x.x.x.x
Of course, ensure you replace liberatedsystems.co.uk with your own domain, and x.x.x.x with your server’s IP address.
Prerequisite packages
I am assuming that you are performing this install on an Arch-based server, and are therefore using the packages from the official repositories.
You should ensure you have the following packages installed:
Certbot
MariaDB (and running)
nginx (and running)
Installing ejabberd
Pretty damn easy to be honest, just run the below command to install ejabberd.
doas/sudo pacman -S ejabberd
Of course choosing sudo or doas depending on which you have installed.
Creating nginx domains
Next, we must add the various domains you created DNS entries for to nginx, so that certbot can request and automatically renew certificates for these domains.
Main domain
If you have not yet done so, install the below nginx configuration file for
your main domain in /etc/nginx/sites-available/liberatedsystems.co.uk
:
server {
server_name liberatedsystems.co.uk;
listen 80;
return 404;
}
Again, substitute liberatedsystems.co.uk for your domain. All this config file does is listen for requests and return 404 if any are received. You may wish to edit this later if you’d like to host a main site.
Subdomains
Next, you should also install the above config file in the following locations:
/etc/nginx/sites-available/conference.liberatedsystems.co.uk
/etc/nginx/sites-available/upload.liberatedsystems.co.uk
/etc/nginx/sites-available/proxy.liberatedsystems.co.uk
/etc/nginx/sites-available/pubsub.liberatedsystems.co.uk
Ensure that besides substituting the domain for your own, you also add the subdomain to the server_name variable for each config.
Creating symlinks
Now, ensure that you create symlinks in the sites-enabled
folder pointing to
the config files in the sites-available
folder, for example:
doas/sudo ln -s /etc/nginx/sites-available/liberatedsystems.co.uk /etc/nginx/sites-enabled/liberatedsystems.co.uk
Once more, ensure you do this for each config file in the directory,
substituting liberatedsystems.co.uk
with the relevant domain. If you don’t,
you might end up having as bad of a time as Top Gear in
Argentina.
Restart nginx
After all that, just run the following to restart nginx and get it to load the config files:
doas/sudo systemctl restart nginx
Editing certbot-renew.service
Now we must edit the certbot-renew.service
file from the certbot package, as
by default the TLS certificates are stored separately and are owned by root
,
which is not what ejabberd
needs.
Therefore, we will run the following:
doas/sudo systemctl edit certbot-renew.service
Once you have entered your text editor, paste the following above the “edits below will be discarded” line:
[Unit]
Description=Renew certificates acquired via Certbot
Documentation=https://eff-certbot.readthedocs.io/en/stable/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
ExecStop=/bin/bash -c '/bin/cat /etc/letsencrypt/live/liberatedsystems.co.uk/privkey.pem /etc/letsencrypt/live/liberatedsystems.co.uk/fullchain.pem > /var/lib/ejabberd/liberatedsystems.co.uk.pem && /bin/chown jabber:jabber /var/lib/ejabberd/liberatedsystems.co.uk.pem'
PrivateTmp=true
Remember to replace the domain with your own. This ensures that each time the
service runs, the certificates are combined into one file, which is owned by
jabber
, the user which ejabberd
runs as.
After writing to the file and saving it, run the following to reparse the service file:
doas/sudo systemctl daemon-reload
Running certbot
Now run certbot to retrieve your TLS certificates:
doas/sudo certbot
When prompted, press enter to request certs for all domains, and after a short
wait you should be done! Ensure you run the following to generate the
certificate for ejabberd
and enable auto-renewal:
doas/sudo systemctl start certbot-renew
doas/sudo systemctl start certbot-renew.timer
doas/sudo systemctl enable certbot-renew.timer
Now if you run ls /var/lib/ejabberd
, you should see a file called
yourdomain.co.uk.pem
. If you do, you’ve successfully generated your
certificate!
Configuring ejabberd
We will now begin to configure ejabberd, so open the configuration file at
/etc/ejabberd/ejabberd.yml
in your text editor.
Hosts
Within the hosts section, replace localhost
with your domain.
Certificates
Add the following to your config file, beneath the commented certfiles
section:
acme:
auto: false
certfiles:
- /var/lib/ejabberd/liberatedsystems.co.uk.pem
Remember to replace the domain with yours. This snippet disables ejabberd’s built-in certificate renewal, and tells it to instead use the one we requested using certbot earlier.
SQL database
Create an ejabberd user and database in your SQL console:
doas/sudo mysql
create user ejabberd@localhost identified by "password";
create database ejabberd;
grant all privileges on ejabberd.* to ejabberd@localhost;
flush privileges;
\q
Consider choosing a different password than “password” for the user.
Add this section to your /etc/ejabberd/ejabberd.yml
config file:
sql_type: mysql
sql_server: "localhost"
sql_database: "ejabberd"
sql_username: "ejabberd"
sql_password: "password"
Also ensure that you uncomment the db_type: sql
line in the mod_mam
section. If you chose a different password than “password”, ensure you change it
here too. Both of these changes ensure that ejabberd uses your SQL server for
storage, since the default database is restricted to 2GB in size, which
depending on your deployment may be too small, particularly if you’re sharing
many images of the Waco
Siege.
Client to server TLS config
We will now alter ejabberd’s TLS parameters to processone’s recommendations for security to minimise the risk of compromise, as your server’s traffic will likely pass through government harvesting facilities at some point.
Within the listen
block, in the section with the port: 5222
configuration,
insert the following:
protocol_options:
- no_sslv2
- no_sslv3
- no_tlsv1
- no_tlsv1_1
ciphers: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
starttls: true
tls_compression: false
dhfile: /etc/ssl/dh2048.pem
This disables old SSL and TLS versions for client to server communication, along with insecure ciphers, and uses a dhfile for increased security.
Within the listen
block, in the section with the port: 5223
configuration,
insert the following:
protocol_options:
- no_sslv2
- no_sslv3
- no_tlsv1
- no_tlsv1_1
ciphers: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
tls_compression: false
dhfile: /etc/ssl/dh2048.pem
This does much the same, but for the encrypted port for client to server communication.
Server to server TLS config
Locate the s2s_use_starttls: optional
line in your config file and delete it.
After, paste the following:
s2s_use_starttls: required
s2s_dhfile: /etc/ssl/dh2048.pem
s2s_ciphers: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
This configures the server to force STARTTLS in federation, along with a dhfile and disables insecure ciphers.
Within the listen
block, in the section with the port: 5269
configuration, insert the following:
protocol_options:
- no_sslv2
- no_sslv3
- no_tlsv1
- no_tlsv1_1
This disables older SSL and TLS versions when communicating in federation.
Generate dhfile
To generate a dhfile for secure TLS communication, run the following:
doas/sudo openssl dhparam -out /etc/ssl/dh2048.pem 2048
This operation may take some time.
Verify config
Run the following to start ejabberd (and enable it on boot) to check if your config works:
doas/sudo systemctl start ejabberd
doas/sudo systemctl enable ejabberd
If this was successful, congratulations! Allow us to move on.
Register admin user
Let’s now register our first user:
set +o history
doas/sudo -u jabber ejabberdctl register jacob.eva liberatedsystems.co.uk password
set -o history
The set commands are to turn off your command history, so that the password isn’t stored on your server in plaintext. Ensure to change “jacob.eva” for your desired username, the domain for yours, and pick a better password than “password” (please lol).
Next, just add the following to your config file at /etc/ejabberd/ejabberd.yml
:
acl:
admin:
user: jacob.eva@liberatedsystems.co.uk
Once again, replace “jacob.eva” with your username, and the domain with your own.
Finally, restart ejabberd:
doas/sudo systemctl restart ejabberdctl
Connecting
Fire up your favourite XMPP client and connect to your server using your JID (username@domain.com) and the password you set!
If you’re able to login, excellent, your server works! If not, review your configuration.
Create a MUC (multi user chat) room and test sending messages. Ensure it is set to public, so you can join it on another account later on to test federation.
Federation
In order to enable federation, add the following DNS SRV records to your domain via your domain registrar:
_xmpp-client._tcp.liberatedsystems.co.uk SRV 5 0 5222 liberatedsystems.co.uk
_xmpps-client._tcp.liberatedsystems.co.uk SRV 5 0 5223 liberatedsystems.co.uk
_xmpp-server._tcp.liberatedsystems.co.uk SRV 5 0 5269 liberatedsystems.co.uk
_xmpps-server._tcp.liberatedsystems.co.uk SRV 5 0 5270 liberatedsystems.co.uk
But of course, substitute our domain for yours.
Testing (optional)
If you have an account on another XMPP server, use that to join the MUC, or just create another on another server.
If you are able to send and receive messages in the same MUC across the different accounts, congratulations, federation works!
Closing
We will be making more XMPP tutorials in the future goy, so keep your eye out. TECHNOLOGY FOR FREEDOM.