I'm really not sure how many more witty intros I can do on these articles. Think I'll give it a pass today. Let's get into this!
I'm setting this up on FreeBSD, so let's install all the relevant packages. Let's install ejabberd:
root@sin:~ # pkg install ejabberd
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 14 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
ejabberd: 20.12
erlang: 21.3.8.18_1,4
erlang-man: 21.3_2
[...]
[14/14] Extracting ejabberd-20.12: 100%
We'll want to create some DNS records to tell people where to look for our XMPP service. Let's get those out of the way now so they have time to propagate.
I'll be adding these to point to sin.zm.is.
_jabber._tcp.zm.is 86400 IN SRV 0 0 5269 sin.zm.is
_xmpp-client._tcp.zm.is 86400 IN SRV 0 0 5222 sin.zm.is
_xmpp-server._tcp.zm.is 86400 IN SRV 0 0 5269 sin.zm.is
After issuing certificates with acme.sh and copying them into my FreeBSD jail every day with CRON (out of scope of this article), let's update the config with the LDAP definition:
We're going to harden TLS a bit with the following lines in each listen stanza (don't copy this into any configs, see below for full config):
The protocol options are industry standard, and the cipher selected is either CHACHA20-POLY1305 or AES256-SHA384 - arguably the best options out there.
Here's the full file:
You'll want to change all the IP addresses and the admin JID - m@zm.is (message me!).
Now, let's open 5222, 5269, 5443 and 1883 in our firewall in order to let it talk out.
I've done it like this:
xmpp="10.1.0.141"
xmpp_v6="fd20:cead:faff::141"
ports_xmpp="{ 5222, 5269, 5443, 1883 }"
rdr pass on $ext_if inet proto tcp from !<sshguard> to $ext_if port $ports_xmpp -> $xmpp
rdr pass on $ext_if inet6 proto tcp from !<sshguard> to $ext_if_v6 port $ports_xmpp -> $xmpp_v6
rdr pass on $br_if inet proto tcp from $net_v to 10.1.0.4 port $ports_xmpp -> $xmpp
rdr pass on $br_if inet6 proto tcp from $net_v_v6 to fd20:cead:faff::4 port $ports_xmpp -> $xmpp_v6
I've also got the bonus (last 2 lines) of being able to reach my XMPP server from within my VPN, since I've got split-horizon DNS:
x@qi ~ ยป host sin.zm.is
sin.zm.is has address 10.1.0.4
sin.zm.is has IPv6 address fd20:cead:faff::4
If you don't have a fancy network setup like mine you can do a simple pass rule:
ports_xmpp="{ 5222, 5269, 5443, 1883 }"
pass in on $ext_if inet proto tcp from any to any port $ports_xmpp keep state
I'd recommend using Gajim to connect to it, for it's fantastic OMEMO support. Adding an account is rather simple, and thanks to the SRV accounts we set up earlier, set-up will be automatic, with no need to put in the custom server we've set up for our domain. If you are actually running your XMPP server on the same domain, they aren't technically needed but are required if you want to adhere to the standard. So put them in.