How to Set Up Prosody for You and Your Friends
Signal seems to have gone closed-source. I like Signal a lot but there are some legitimate criticisms of it-- I never really minded that it's centralized and not federated, but I really don't want to be using a platform that is (currently) lying to its users and claiming to be free and open-source when it's not. I'm no free software maniac, but it just doesn't feel right. Even though it's end-to-end encrypted, so theoretically a compromised server wouldn't reveal my conversations, I started looking for a different solution.
I've heard a lot about federated, self-hostable protocols like XMPP and Matrix, so I decided to explore if it's feasible to switch my small non-programmer friend group over to a self-hosted XMPP server running on a Raspberry Pi in my house.
The two most popular XMPP servers out there are ejabberd and Prosody. I went with Prosody since I found that it's easier to configure (all the settings are basically perfect out of box) and it's less resource hungry, especially nice for running on a Pi. For the following instructions, I'm going to assume you're using a Debian-based OS since that's what I used.
Contents
- 1 Step 1: Get a Domain Name
- 2 Step 2: Install Prosody
- 3 Step 3: Add a VirtualHost for your domain
- 4 Step 4: Enable multi-user-chat and file sharing
- 5 Step 5: Get the Prosody community modules
- 6 Step 6: Set up the community modules
- 7 Step 7: Enable the modules
- 8 Step 8: Set up Let's Encrypt
- 9 Step 9: Enable the HTTPS certificate
- 10 Step 10: You're basically done
Step 1: Get a Domain Name
Yeah, if you're self-hosting then you pretty much need to set up a domain name for your server. Sucks, but them's the breaks. I bought a .xyz domain for $1 and pointed it at a No-IP domain, then set up my router to do DDNS with No-IP.
Step 2: Install Prosody
Add Prosody's repository in order to get the latest version.
echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list
Then install Prosody.
sudo apt-get install prosody
Step 3: Add a VirtualHost for your domain
Open up /etc/prosody/prosody.cfg.lua
and scroll down to the very bottom. Add a line like this:
VirtualHost "<your domain>"
Step 4: Enable multi-user-chat and file sharing
Since we want to be able to create group chats, add these lines below your VirtualHost line. "MUC" means Multi-User Chat in XMPP parlance and just means group chats.
Component "conference.<your domain>" "muc" modules_enabled = { "muc_mam"; "muc_cloud_notify"; }
To enable file uploading (pictures, audio, etc) put these lines right below that:
Component "upload.<your domain>" "http_upload" http_host = "<your domain>"
We now have a usable XMPP server, but it's not complete yet-- we need to enable some plugins which enable some useful features that most people will want.
Step 5: Get the Prosody community modules
A few plugins we need are part of the Prosody community modules repository.
First, install mercurial.
apt-get install mercurial
Then download the community modules repository somewhere. I put it in my home directory but you can put it anywhere.
hg clone https://hg.prosody.im/prosody-modules/ prosody-modules
Step 6: Set up the community modules
Since Prosody scans plugin directories for everything, and some modules are part of both the community repository and the default pack-in Prosody collection, they recommend creating a separate folder called prosody-modules-enabled
, adding THAT to Prosody's plugin path, and then symlinking the modules you want into the directory. So let's do that for the modules we want to use.
mkdir prosody-modules-enabled cd prosody-modules-enabled ln -s ../prosody-modules/mod_cloud_notify ln -s ../prosody-modules/mod_http_upload ln -s ../prosody-modules/mod_muc_cloud_notify ln -s ../prosody-modules/mod_smacks
mod_cloud_notify
and mod_mud_cloud_notify
enable mobile clients such as ChatSecure, Monal and Conversations.im to send push notifications to your phone when you receive a message.
mod_http_upload
enables you to share pictures and files in your chats.
mod_smacks
is an enhancement which allows spotty or terminated sessions to be resumed without discarding messages in the queue. This is useful for mobile devices on mobile data networks.
Step 7: Enable the modules
Go back into /etc/prosody/prosody.cfg.lua
and set a few things.
Add your prosody-modules-enabled
folder to the list of plugin_paths
plugin_paths = { "/home/pi/prosody-modules-enabled" }
Add these 2 lines inside the modules_enabled
table:
"cloud_notify"; "smacks";
Enable other modules as you see fit.
Below the modules-enabled
table, put these 2 lines:
push_notification_with_body = false; push_notification_with_sender = true;
This allows push notifications to be sent-- you don't want to include the body of the message in the notification, because then Google or Apple can read it, defeating the point of encryption! I enabled the sender part though, since the NSA can already detect which IPs are connecting to your server and figure out who all is talking. Besides, your JID (Jabber IDs) can be anonymous usernames.
Step 8: Set up Let's Encrypt
If you want people to be able to connect to your server, chat, and upload files without certificate errors/warnings, then you'll need an SSL certificate. Luckily this is fairly easy to set up.
First, install certbot:
sudo apt-get install certbot
Then, create a new certificate for your server:
sudo certbot certonly --standalone --preferred-challenges http -d <your domain> -d upload.<your domain>
Remember to open up port 80 on your router for this to work. Once you've got your certificates, you need to import them into Prosody.
prosodyctl --root cert import /etc/letsencrypt/live
You can add this as a hook to your certbot so that it always gets called when certbot renews its certificate. Open up /etc/letsencrypt/renewal/<your domain>.conf
and add this line at the very bottom:
renew_hook = prosodyctl --root cert import /etc/letsencrypt/live
Step 9: Enable the HTTPS certificate
In order to serve files from its internal HTTP server, Prosody also needs a HTTPS certificate. Fortunately, you can use the one you just created.
Open /etc/prosody/prosody.cfg.lua
and go to the line which defines https_certificate
(it might be commented out) and put this:
https_certificate = "/etc/prosody/certs/<your domain>.crt"
Step 10: You're basically done
Now we have everything we need. The server should be fully configured and ready to go.
Be sure to:
- Run
sudo systemctl restart prosody
for your server to reload the config file and restart itself. - Port forward ports 5222, 5280, and 5281 so that you can connect to your server.
- Add a user for yourself! Do
sudo adduser <username>@<yourdomain>
and put in a password. You can also create accounts for your friends, and they can change their passwords later.
Connect up using a client such as Gajim, and you're off to the races with a private chat server that's 100% your own. Be sure to turn on OMEMO in your chats so that your messages are end-to-end encrypted! Since you run the server, it's actually okay to send "unencrypted" messages since everything is going through TLS in the first place, but it's nice to have that extra layer of protection. Since files in XMPP are shared via an HTTPS server, you definitely want OMEMO to encrypt your files as well, since otherwise you'll be serving your media to the open web!
There's more you can do, such as enabling federation or installing more plugins, but that's out of the scope of this article.
Special thanks go to the folks in the Prosody IM Chatroom (xmpp:prosody@conference.prosody.im?join) for helping me get set up. Note that you'll have to enable federation in order to join that link using your current server.
Enjoy!