The Ultimate Bells-And-Whistles XMPP Setup Guide

Get your friends off Discord, with a better app!

Introduction

Discord has gotten into the surveillance state game, and anyone who values their privacy is trying to find an alternative. There’s one technology everyone seems to have forgotten about: XMPP.

If you are looking for a public server, then you have missed the entire point of XMPP. If you want to invite your friends, you can. It’s pretty easy, they don’t have to do anything. You can send them a link, and it asks for username and and a password, and that’s it. You don’t have to give anyone an email address.

You are going to run this yourself. Think of it like taking care of a pet, it’s a thing that you need to put in some work to make survive.

Here is a shocking vulnearability in every online service today: Every single one tells a third party something about what you’re doing.

Discord has data breaches. The require a govenment ID.

If you are looking for a public server, then you have missed the entire point of XMPP. If you want to invite your friends, you can. It’s pretty easy, they don’t have to do anything. You can send them a link, and it asks for username and and a password, and that’s it. You don’t have to give anyone an email address.
Features

Here’s what’s available, right now:

Server Capabilities

Privacy

Abstract Concrens and Philosophy

Developer Concerns

Protecting Children

You want to protect children online? Setting up your own XMPP server is by far the most effective way to make sure they are not tageted by predators, or exposed in a data leak.

Keeping children safe from strangers

Keeping chldren safe from parents

This is a somewhat counterintuitive point to avertise, but the sad fact is that most child abuse is not done by predators, but by parents.

I would suggest parents let it go, taking care of something is a sign of responsibility.

Downsides

Getting Started

Prerequisites

You will need a domain.

While it is technically possible to set up a working XMPP server without a domain, you will be causing yourself a lot of problems later on.

You will need a server, configured with SSH logon and a static IPv4 address.

We will be using the command line extensively, so if you’re new to text-based tools you may appreciate the Big Glossary of Linux Command Line Tools.

Point your domain at your server

Explained in more detail here.

Make sure your proxy status is “DNS only” - The cloud should be grey instead of orange. You may receive a warning that proxying is required for performance or security features, ignore these. This are more useful for websites than XMPP servers, which need direct connections to determine how to route messages.

Install Prosody

Login to your server. Open your terminal, and run:

ssh root@your_static_ip_v_4_address

The first time you run this command it will say “The authenticity of host ‘your_ip_address’ can’t be established”, and ask if you want to continue connecting. Accept the host and continue.

If it asks for a password, you have not configured your connection correctly. Either you are using password-based authentication, which is less secure, or your SSH keys are not set up correctly.

You should be greeted by a brief message, stating your current operating system version and any important notifications.

Install Prosody and Let’s Encrypt!

Run:

sudo apt install prosody certbot

Get an SSL certificate

There are two options. If you want to provide an email address to be notified when certificates are getting old, run:

sudo certbot certonly --standalone -d yourdomain.com -d rooms.yourdomain.com

Otherwise, run:

sudo certbot certonly --standalone -d owois.me -d rooms.owois.me --register-unsafely-without-email

The certificates it generates will be placed in “/etc/letsencrypt/live/yourdomain.com/”

If you have problems, rerun the command with -v, which will trigger verbose output for debugging. Make sure to replace “yourdomain.com” with your actual domain.

If you get the error:

An unexpected error occurred:
No such authorization

Then it may be due to DNS records not yet propagating, wait a bit and try again. DNS records can take multiple hours to be broadcast to worldwide DNS servers, but the process is normally very fast (on the order of minutes).

Give Prosody permission to read the certificates

Add prosody to the ssl-cert group:

sudo adduser prosody ssl-cert

Set the group for the certificates to ssl-group:

sudo chgrp -R ssl-cert /etc/letsencrypt

If Prosody complains about permissions, you can use the following commands to set them:

sudo find /etc/letsencrypt -type d -exec chmod 750 {} \;
sudo find /etc/letsencrypt -type f -name "privkey*.pem" -exec chmod 640 {} \;
sudo find /etc/letsencrypt -type f -name "fullchain*.pem" -exec chmod 644 {} \;

If you have put your domain information into Prosody’s config file, you can run prosodyctl check certs to verify they are installed and detected correctly. If you have not, it will complain it cannot find a certificate for localhost. This is fine.

Create an admin user

Run:

sudo prosodyctl adduser [email protected]

This can also simply be your personal account. Ignore any warnings about the user being able to log in, we’ll configure that next.

Configure Prosody

Edit your Prosody configuration. The easiest way to edit text in a terminal is using nano, other popular choices include vim (usually included with the OS) and EMACS (usually needs to be installed). This tutorial will assume the use of nano.

Run:

sudo nano /etc/prosody/prosody.cfg.lua

There are three sections to this file:

We will be configuring one virtual host (yourdomain.com) and one component (rooms.yourdomain.com, for chat room support.)

Prosody config global section

c2s_require_encryption = true
s2s_require_encryption = true
c2s_interfaces = { "*" }
c2s_ports = { 5222 } 
https_ports = { 5281 } 
https_ssl = { 
  certificate = "/etc/letsencrypt/live/yourdomain.com/fullchain.pem"; 
  key = "/etc/letsencrypt/live/yourdomain.com/privkey.pem"; 
}

Prosody config Virtual Hosts section

Set up the Virtual Host certficates.

VirtualHost "yourdomain.com" 
  enabled = true 
  ssl = { 
    key = "/etc/letsencrypt/live/yourdomain.com/privkey.pem"; 
    certificate = "/etc/letsencrypt/live/yourdomain.com/fullchain.pem"; 
 } 

While you’re here, also give yourself free Nitro. Set the http_upload_file_size_limit and http_file_share_size_limit to choose maximum file upload sizes.(TODO: ONE OF THESE IS PROBABLY REDUNDANT FIND OUT WHICH ONE)

   http_upload_file_size_limit = 1000 * 1024 * 1024 -- 1000MB 
   http_upload_path = "/var/lib/prosody/http_upload" 
   http_file_share_size_limit = 1000 * 1024 * 1024 -- 1000 MiB 

This is unneeded once your domain is configured. If you’d like to silence warnings for certificate errors for localhost, you will also need to comment out the Virtual Host line in ./confd.d/localhost.cfg.lua

Prosody config Components section

Add:

Component "rooms.yourdomain.com" "muc" 
 enabled = true 
 ssl = { 
 key = "/etc/letsencrypt/live/yourdomain.com/privkey.pem"; 
 certificate = "/etc/letsencrypt/live/yourdomain.com/fullchain.pem"; 
 }  
modules_enabled = { "muc_mam" } 
default_archive_policy = true

If you’re aiming for a no-logs server, also set:

muc_log_by_default = false
muc_log_presences = false

Save and exit.

Verify your config file is OK

Run prosodyctl check to check the configuration. Prosody will report any errors it finds. Running prosodyctl help will give a list of other supported operations.

Reload Prosody

systemctl reload prosody
systemctl restart prosody

Test logging in to your server

Open your chosen XMPP client, or ConverseJS for a simple web client, and log into your account. If it successfully connects, congratulations! You have a working XMPP server!

Test your features

Go through and test each feature: File upload, file size limits, notifications, and server federation.

To see if Prosody is loading modules correctly, you can run:

journalctl -u prosody

to see all system logs relating to Prosody.

Prosody’s logs are stored in /var/log/prosody/prosody.log

Command Line Tools

Cheat sheet for the commands used in this tutorial

You may also want to take a look at the command line glossary

Viewing a file:

less /path/to/file 

Keeping an eye on a file as messages are being written:

tail -f /path/to/file

Editing a text file:

nano /path/to/file

Show the contents of a folder

ls /path/to/folder/

If you need more details, you can use ls -haltr for an extended view.

See the current directory

pwd

Move to a different directory:

cd /path/to/directory/

Special abbreviations supported by cd: * To go to the previous directory, use cd -. * To go up a level, use cd .. * To go to your home directory use cd ~

Clear the screen if there’s too much text:

clear

To print an entire file to the screen:

cat /path/to/file

To search for text in a file:

grep "your search term" /path/to/file

grep supports an enormous number of options. A few helpful ones: * -A x and -B x: Show x lines above or below the found match * -i: ignore case * -v: Exclude lines with this match instead of including

As an example, to check for Jingle errors in the Prosody logs:

cat /var/log/prosody/prosody.log | grep -i "jingle"

Install software:

sudo apt install name_of_package_to_install

View the manual for a piece of software:

man programname

Examine network configuration

ifconfig

This command will list the IP addresses for the network devices attached to your machine, and some assorted statistics.

Check your DNS records

dig yourdomain.com

Change firewall rules

All managment is done through ufw.

To open a port:

sudo ufw allow 5222/tcp

To set your host to allow all outgoing connections:

sudo ufw default allow outgoing

To set your host to deny all incoming connections:

sudo ufw default deny incoming

List running processes

ps aux

To check if a machine is reachable at all

ping domain_or_ip_address

ping -6 domain_or_ip_address will perform this check over IPv6.

Make a copy of a file

cp /path/to/source/file /path/to/location/to/copy/to/new_filename

So for example, to backup your Prosody config to a file named BACKUP.prosody.cfg.lua:

cp /etc/prosody/prosody.cfg.lua /etc/prosody/BACKUP.prosody.cfg.lua

This command is different from moving a directory, which is mv, and has the same syntax.

To look for a file or folder

Running:

find /folder/to/search/under

will give you a complete listing of all files inside that folder. Your search can be narrowed down further using grep.

Find also supports executing a command on all matching files it finds, using the -exec flag

Changing ownership or group of a file

Change owner:

chown ownername:groupname /path/to/file

Change just one file’s group:

sudo chgrp groupname /path/to/file

Change group for every file in a folder:

sudo chgrp -R groupname /path/to/folder/

Connect to a remote machine

ssh username@machine_name_or_ip_address

Other commands

Not yet documented.

Debugging

Steps to debug common issues

More verbose logging for Prosody

If you are debugging Prosody, it can be helpful to enable debug logging:

log = {
        debug = "/var/log/prosody/prosody.log";
        error = "/var/log/prosody/prosody.err";
        { levels = { "error" }; to = "syslog";  };
}

Fix module installation problems

This can affect any modulle not included by default with Prosody, which at time of writing includes the following modules from this tutorial: * cloud_notify * unified_push * s2s_whitelist * s2s_blacklist

You can install missing modules using prosodyctl:

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

(Replace mod_cloud_notify with mod_{whatever_youre_installing})

If you get luarocks errors, it’s probably because you need to install luarocks: sudo apt install luarocks

Depending on your distribution, you may also need to install lua development libraries:

sudo apt install liblua5.4-dev

Problems with IPv6

IPv6 support has a number of issues out of the box. These are largely due to the somewhat scattershot support for IPv6 globally - A further tutorial is coming (it’s good to do), but in the meantime this guide is focused on getting features up, running, and stable.

However, if you are working on IPv6 support, one piece of information that’s good to know: DigitalOcean does not always bind the IPv6 address correctly to the host. This may require messing with something called “netplan”, (I managed to get it working on one host with this), so best of luck.

Set up STUN/TURN server

Incomplete, collapsed for now.

Run: sudo nano /etc/prosody/prosody.cfg.lua

This file is somewhat long, but is almost entirely comments explaining how to use this file. Somewhere in the middle, you will see a section labeled “Certificate file”, underneath which is a section labeled “Private key file”.

Add the line > cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem

to the certificate section and

pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem

to the private key file section. Again, make sure to edit the domain.

sudo nano /etc/prosody/prosody.cfg.lua

Under the section titled “Specify the address of the TURN service (you may use the same domain as XMPP),” add:

turn_external_host = “yourdomain.com” turn_external_port = 3478 turn_external_secret = “some_long_gibberish_secret_key_that_does_not_need_to_be_memorable”

Installing Coturn

Coturn provides a STUNserver to help voice calls (and other connections) connect, even if your device is on an unusual network (like a cell tower) that does not allow direct connections.

STUN (Session Traversal Utilities for NAT) provides tools for finding an IP address the client is capable of talking to, and TURN (Traversal Using Relays around NAT) will route data through your server as a falback if needed. Without this installed, calling will be extremely unreliable to connect.


Time Travelling Unicorn’s Journal

Feb 14, 1999

My name is Tufts, the Time Traveling Unicorn From The Future, and this is my logbook. By the time you receive this message, the robot wars will have begun. You will need to save the future from the satanic billionaire pedophile cabal.

As you know, the only way to win against advanced artificial intellegence is to send a unicorn back in time to search for ancient alien technology.

When the world ended in 2000, the timeline cracked. A portal opened, leading straight to the faraway land of 1999. To save the future, we found a way to step through it.

People here are finally waking up to the potential of the internet. Everyone is talking about “seeing The Matrix”, and the engineers here are preparing for the Y2K superbug. But that’s the first thing that bother me - As I remember it, Y2K never happened. So where did it go?

I suspect, but cannot yet prove, that your timeline has already started moving backwards. Software is getting worse, not better. There are years missing between you and 2020. The little holes have started creeping in - I remember reading the Berenstein bears, and watching Loony Toons on TV. Is this all caused by some shadowy complex trauma?

No. It’s the millenium portal.

At this rate, the entire internet will be enshittified surveillance state within a year. The only thing that can save us is 1990s VoIP telephony. Are you a bad enough dude to evade the president?

The only thing you need to do to fight robots is to pass the one CAPTCHA that never fails: No robot in existence will ever give you $5. Where we’re going… you will need $5.

Attached are blueprints for a technology called XMPP. Assemble them in your timeline, you have just this shining moment in time to escape the AI deep state. I’ll try to talk to you soon. If I’m not back before Overwatch II becomes Overwatch I… well, good luck. You’ll need it.

(Wondering what this is? Read about Tufts here.)