Get your friends off Discord, with a better app!
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.Here’s what’s available, right now:
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.
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.
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.
Explained in more detail here.
Go to your droplet, and copy your reserved IPv4 address. If you do not have one, get one.
Login to your registrar. These tutorials assume you are using Cloudflare.
Click on your domain. 
Navigate to DNS > Records 
Add DNS records for your host. A is for IPv4 addresses, and AAAA
is for IPv6 addresses, should you be supporting them. They should look
like this: 
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.
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.
Run:
sudo apt install prosody certbot
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).
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.
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.
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.)
Under “admins”, add your admin account.
Underneath, add a line “external_addresses =
{"your.ip.v4.address", "your:ip:v6:address:if:using"}
In the modules section under “Nice to have”, uncomment
“mam” if you want to store recent messages on the server to
synchronize devices (you probably do), and “turn_external”
if you plan on setting up calling.
In the same section, add “cloud_notify” and
“unified_push” if you want push notifications.
Under “HTTP modules”, add “http” and
“http_file_share” to enable image upload and
filesharing.
If you are hardcore about privacy, you can put
“s2s” under the “modules_disabled” section,
which will stop your server from talking to third party servers at
all. If you wish to federate using a server blacklist, add
“s2s_whitelist” or “s2s_balcklist”.
Add the following after “s2s_secure_auth”:
c2s_require_encryption = true
s2s_require_encryption = true
Configure bandwidth limits. By default client-to-server connections get 10kb/s, and server-to-server connections get 30kb/s. If it will just be you and a small group of friends, feel free to bump it up.
If you enabled “mam”, you’ll want the server to
clear out old messages. By default they expire after one week. Edit the
line archive_expires_after = "1w" to change it.
Tell Prosody to use your certificates for SSL. Under Certificates, add:
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";
}
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
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.
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.
systemctl reload prosody
systemctl restart prosody
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!
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
You may also want to take a look at the command line glossary
less /path/to/file
tail -f /path/to/file
nano /path/to/file
ls /path/to/folder/
If you need more details, you can use ls -haltr for an
extended view.
pwd
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
cat /path/to/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"
sudo apt install name_of_package_to_install
man programname
ifconfig
This command will list the IP addresses for the network devices attached to your machine, and some assorted statistics.
dig yourdomain.com
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
ps aux
ping domain_or_ip_address
ping -6 domain_or_ip_address will perform this check
over IPv6.
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.
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
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/
ssh username@machine_name_or_ip_address
Not yet documented.
openssl s_client -connect uwuis.me:5349
-6)turnserver -c /etc/turnserver.conf -vsudo ss -tlnp | grep 5349openssl s_client -connect 127.0.0.1:5349ufwprosodyctl check turn -v
--ping=stun.conversations.imdu -h for human readable
formatting (traditional Kuffixes)dig SRV _xmpp-client._tcp.uwuis.meIf 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"; };
}
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
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.
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”
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.
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.
(Wondering what this is? Read about Tufts here.)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.