Liberated Embedded Systems



Jacob “Fed Hunter” Eva, known for his excellent fedposting skills and hatred of socialists, is the head agilepilled scrumcell director of Liberated Embedded Systems. In his free time, he targets 5G TV licensing vans with high-energy EMF waves to disable their scanning functionality, preventing them from stealing peoples’ income for the BBC. Thank you, Jacob.

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: A x.x.x.x A x.x.x.x A x.x.x.x A x.x.x.x A x.x.x.x

Of course, ensure you replace 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:

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/

server {

    listen 80;
    return 404;

Again, substitute 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.


Next, you should also install the above config file in the following locations:


Ensure that besides substituting the domain for your own, you also add the subdomain to the server_name variable for each config.

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/ /etc/nginx/sites-enabled/

Once more, ensure you do this for each config file in the directory, substituting 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:

Description=Renew certificates acquired via Certbot

ExecStart=/usr/bin/certbot -q renew
ExecStop=/bin/bash -c '/bin/cat /etc/letsencrypt/live/ /etc/letsencrypt/live/ > /var/lib/ejabberd/ && /bin/chown jabber:jabber /var/lib/ejabberd/'

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 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.


Within the hosts section, replace localhost with your domain.


Add the following to your config file, beneath the commented certfiles section:

    auto: false
 - /var/lib/ejabberd/

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;

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:

      - no_sslv2
      - no_sslv3
      - no_tlsv1
      - no_tlsv1_1
    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:

      - no_sslv2
      - no_sslv3
      - no_tlsv1
      - no_tlsv1_1
    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

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:

      - 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 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:


Once again, replace “jacob.eva” with your username, and the domain with your own.

Finally, restart ejabberd:

doas/sudo systemctl restart ejabberdctl


Fire up your favourite XMPP client and connect to your server using your JID ( 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.


In order to enable federation, add the following DNS SRV records to your domain via your domain registrar: SRV 5 0 5222 SRV 5 0 5223 SRV 5 0 5269 SRV 5 0 5270

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!


We will be making more XMPP tutorials in the future goy, so keep your eye out. TECHNOLOGY FOR FREEDOM.