Home
Your own xmpp server with ejabberd on Debian 11 Bullseye
0. Intro
AOL, ICQ, Hangouts, Messenger, Whatsapp, ... it's been bothering for quite a long time to switch instant messaging (im) app every few years and share all my conversations with those third parties. I guess I must be one of the few who did not click agree on Whatsapp's latest terms and conditions -I'm not switching to google chats either! I expect to be kicked out any day soon \o/.
Anyway, this feels like a good time to choose a new im protocol, and stick to it. After doing quite some research, I decided to go with irc and jabber (XMPP). If you wonder why, read Solène on how to choose a communication protocol.
Additionally, it is interesting to know that whatsapp is based on XMPP! The WhatsApp Architecture Facebook Bought For $19 Billion. So I decided to install an XMPP server and ordered a vps (virtual private server) for a year. If you wonder why not running it at home, I'm preparing a post about self-hosting!
1. About XMPP Extension proposals (XEP)
As XMPP is an extensible protocol, many functionalities can be built on top of it. These come in the form of XEP, which are public proposals defined by a number (ie: XEP-0313 Message Archive Management - XEP-0384 OMEMO Encryption) and can be implemented by various server/client software once validated. This is nice, as the protocol is not stuck in stone and can evolve. You can check the list of XEP for yourself!
One postitive point about XMPP is the diversity of clients and available for many different platforms.
One sad side about XMPP is that support for different XEP can greatly vary depending on software (both clients and servers) - The one thing that universally works between all clients is simple, clear text messaging...
This is because:
The situation is not as dire as it first sounds, but it is an important factor to take into account when testing and to be cautious about when setting up your own XMPP infrastructure.
2. Servers
In my reasearch, I saw somewhere that ejabberd was an xmpp server that came with included stun/turn capabilities (+sip) - so I decided to give it a try. Reinstalled the debian VM, this time upgraded to bullseye (which was released since). apt get ejabberd, get some config tutorial from the internet and...
nothing... bloody service wouldn't even start.
So I retook the original blank debian config and... asked for help \o/
I reread a few usetull steps in setting up my server.
A kind soul from #selfhosting on irc.tilde.chat pointed me to How to set up ejabberd video & voice calling
Just applying those changes to the default debian conf (and dns servers) was the way to go!
I also needed to set some certificates, for which I almost followed process one's guide on securing jabber with TLS
Instead, to get certbot in bullseye, I did:
apt install certbot
certbot certonly --webroot
/usr/bin/certbot renew
sleep 2
cat /etc/letsencrypt/live/your.doma.in/fullchain.pem /etc/letsencrypt/live/your.doma.in/privkey.pem > /etc/ejabberd/ejabberd.pem
systemctl restart ejabberd
cat /vat/log/ejabberd/error.log
cat /vat/log/ejabberd/ejabberd.log
3. Clients
As you remember from point 1, client choice is not especially easy... These are a few experiments I made:
When you have various clients connected to the same account at the same time (ex blabber.im on phone and gajim on computer), your contacts will or will not be able to call you depending on the client you are currently typing in.
So I'm chatting on the computer (gajim: no av support), a friend tells me "I can't call you", I go on my mobile (blabber.im: good av support) and the call button appears on his (mobile) screen.
This explains why sometimes you can call a contact and sometimes you can not - although they appear online!
4. Config changes
I needed to configure/enable a few specific modules for ejabberd to meet my expectations, somewhere in the process of looking for howto's, I stumbled upon the ejabberd documentation archives. This page is a real goldmine, as it contains the correct syntax for the options for your specific version of ejabberd - as many tutorials on the internet point you in the right direction, all you need is to know how to implement the option in your specific version! The specific page linked is the one with all modules options for 21.01 (debian 11 default). Kudos to the ejabberd team for this well maintained documentation!!!
mod_proxy65:
access: local
max_connections: 10
name: "File transfer proxy"
ip: "ip.of.ser.ver"
port: 7777
mod_mam:
db_type: sql
assume_mam_usage: true
default: always
default_room_options:
allow_subscription: true
persistent: false
mam: true
I set persistent false as default, as only I am supposed to create permanent rooms on my server ^^
just delete the lines relative to mod_register
5. A few commands
Once installed, not being a fan of web interfaces, I noted a few usefull commands here as a personal cheatsheet, but I can only recommend you to get more information from the very extensive and well maintained ejabberd documentation
Reload config without restarting service (without disconnecting users)
ejabberctl reload_config
Backup
ejabberdctl backup ejabberd_backup.$(date +%Y%M%d)
ls /var/lib/ejabberd/ejabberd_backup.*
ejabberdctl restore ejabberd_backup.theoneyouwannarestore
Modules
ejabberctl update_list
ejabberctl update modulename
ejabberctl update all
Users
As we disabled mod_register, it means we will need to add our users by hand \o/
ejabberdctl register username host.doma.in password
registered_users host
ejabberdctl unregister username host.doma.in
Rooms (muc - multi user chat)
or just enter new room with client ;p
ejabberdctl create_room roomname conference.your.doma.in your.doma.in
ejabberdctl muc_online_rooms global
ejabberdctl destroy_room roomname conference.your.doma.in
ejabberdctl get_room_options roomname conference.your.doma.in
ejabberdctl change_room_option roomname muc_service option value
ejabberdctl change_room_option roomname conference.your.doma.in allow_change_subj false
ejabberdctl change_room_option roomname conference.your.doma.in anonymous false
ejabberdctl create_room roomname conference.your.doma.in your.doma.in
ejabberdctl change_room_option roomname conference.your.doma.in mam true
ejabberdctl change_room_option roomname conference.your.doma.in members_only true
ejabberdctl change_room_option test conference.chat.chezmoi.lu public_list false
Won't disappear if everybody leaves
ejabberdctl change_room_option roomname conference.your.doma.in persistent true
Room+user
Affiliation can be one of: owner, admin, member, outcast, none
ejabberdctl set_room_affiliation roomname muc_service user_jid affiliation
ejabberdctl send_direct_invitation roomname muc_service password reason jid1[:jid2]
5. Where to go from here?
I realise I barely scratched the surface from XMPP and ejabberd capabilities, as I now just have "basic" XMPP functionality. On the one side, I would like to study XMPP a bit more, and configure some modules so that it does exactly what I want.
Ejabberd is also an MQTT broker and a SIP server: if you take into account that I have an asterisk and a domoticz server running, it opens the gates to a huge playground! Though it will take time to explore!
These two pages look like a promising start:
6. Conclusion
It woooorks! I am sooo happy + I have a new playground... what else could I ask for! (the answer is more time to explore more things)
As always, the Open Source community has been key to reaching my goals - be it through software, forums, posts, IRC...
From here on, an important next step is to get some friends and family to use it - suddenly configuration looks like the easy part! 😅
Hope it helps ^^