Back to home


Setting up your own XMPP server using prosody

You know what's great about prosody apart from it being free software? It's federated so you can run your own server thus minimizing reliance on big players (try to do that with messenger or whatsapp normalfags). And no, creating an account does not require a phone number signalfags, all you need is a username and a password. So here I'll try to showcase how to set up your own XMPP instance.


Home-hosting or using a VPS

I'd say it's not that important really as both have their upsides and downsides (home-hosting gives out your IP address to the public, VPS providers will have a bit of your personal information). What you should consider here is if you're even able to home-host, maybe your internet provider doesn't provide public IP addresses or maybe your internet is Luke-Smith-slow. You should just choose what's the best for you here, prosody isn't really resource intensive. Sadly I can't recommend any VPS providers for now as I'm still looking for one I could actually use and I'll update this article when I find one.


Registering a domain name

This one is actually important I'd say, you should choose something cool be it personal or not. As for domain registrars I'm currently using gandi but I'll probably switch to njalla next time I'll be renewing the domain (need to figure out crypto before that tho). For now I'm happy with gandi but I feel like they want too much personal information from you although that's probably required by law in France or EU in general, maybe domain providers require some of that info too (I'm not saying these laws are great or anything).

Update while writing:

The price went up significantly for .me domains at gandi (or it will on 1st February) bringing it to €20 per year (previously €16) so it makes it even less appealing compared to njala although it's €30 there but they don't require any personal information, will for sure switch to njala on next renewal.


Configuring your domain

There's a few things you need to do before you can set up your XMPP server, basically you need to link your domain to the IP address of your server and the other way around if possible. You can do both of these from the web interface of your registrar and your VPS or internet provider. You'll need to create a few A and CNAME records: one A record for your main domain, in my case that's: leglock.me, another A record for a dedicated xmpp subdomain, in my case xmpp.leglock.me, another A record for proxy support, in my case proxy.leglock.me and a few CNAME records pointing at the xmpp subdomain, in my case that's conference.leglock.me (for MUCs - that is Multi User Chats) and upload.leglock.me (for file uploads). You'll need to create a few SRV records too, they'll be used for pointing other servers and clients to your server, they should look like this:

_xmpp-client._tcp 300 IN SRV 10 10 5222 xmpp.leglock.me.
_xmpp-server._tcp 300 IN SRV 10 10 5269 xmpp.leglock.me.
_xmpps-client._tcp 300 IN SRV 10 10 5223 xmpp.leglock.me.
	
I think that's all but I may be wrong so expect updates with corrections. The last thing you should do if you're able to is setting up a rDNS record, that's done by either adding the thing on the web interface of your VPS provider or calling or messaging your ISP, I should mention tho that probably not every ISP will be keen on doing that for you and they probably will question you for whatever reason, on the VPS side it's really straight forward and easy to do.


Choosing an OS for your server

Anything unix-like (be it a Linux distro or some BSD) should be fine, really. I'm running my server on Arch Linux just because I like to have latest versions of packages and because I wanted NextCloud to behave (I'm thinking about getting rid of it tho as it drives me crazy now and I don't like it that much), if I were to set up my server once again (which I may do in the future) I'd choose OpenBSD because of its simplicity, absolutely amazing documentation and great programs in base system (in that an http server and a client for getting ssl/tls certificates which will be needed). You may choose whatever you like tho like debian or FreeBSD, I'll try to make the instructions applicable to all.


Installing required software

Apart from prosody,lua-sec (for encryption) and lua-event (for better connection handling), you'll need to install a web server - I've used and can recommend both nginx and OpenHTTPD - becuase of this stupid mentality of not accepting self-signed certificates for whatever reason and trust me they're all bullshit, but I guess people put more trust in cloudflare now than in websites owners, you'll also need certbot with certbox-nginx or in case of OpenBSD acme-client which is already in base and you don't need to install anything (truly a great OS) and mercurial to clone one repo. Now I'm not gonna tell you how to install shit on your OS of choice that's not what this guide is for just look it up on the web or better yet check out the man pages.


Getting your shiny certificates

Certificates are used for encrypting connections and in today's age you really want that (because of scary haxorz, am I right?), now you've just installed nginx and certbot or if you're using OpenBSD you already have OpenHTTPD (which is actually called just httpd) and acme-client installed so you're all ready, I mean almost. You should create a really basic configuration for your website which covers all your domains you've previously set up (again look up the web or corresponding man pages) and start the web server. Now you just need to run as root either certbot --nginx or acme-client -v domain.ltd (which in my case would be acme-client -v leglock.me, -v stands for verbose ofc also be sure to create a config file for it first). That should generate certificates for all your domains and you should finally be ready for setting up prosody.


Setting up prosody

Certificates

The first thing you should do is read the documentation... for real. That can save you a lot of headaches as this guide won't replicate the whole thing described there, Of course I'll try to help you set up your server with all the basics covered but there may be a specific setting or thing you'd like to have that's not present here. With that out of the way the first thing you should do is make prosody able to read your certificate. Basically there are two ways of doing that, symlinks or just plain old copying, with both methods you should have three files present in /etc/prosody/certs/. One should contain your full certificate and should be named domain.ltd.crt (in my case leglock.me.crt), another one should contain your private key and should be named domain.ltd.key (in my case leglock.me.key) and the last one should contain the contents of both previous files and should be named https.pem. Just be sure to make them only readable by root and whatever user you'll run prosody as (to minimize the risk of someone being able to read those files). With that you can move to actually setting up prosody.

Getting community modules

The last step before actually modifying prosody's config file is cloning a community mantained modules repos for prosody as not everything that's really useful is available upstream. I have it in /usr/lib/prosody/ where artix/arch installs prosody, you can clone it by issuing this command as root: hg clone 'https://hg.prosody.im/prosody-modules/' /where/you/want/it/to/be/in/prosody-modules. Now if you don't want to make all the modules available you can create another directory containing symlinks to actual directories with modules (in my case that's /usr/lib/prosody/prosody-modules-enabled/ and that's what I use as custom modules location). Now we can change some settings in /etc/prosody/prosody.cfg.lua.

Admins

The first thing you'd want to change is defining admin users on your server, they can for example access prosody's config through ad-hoc commands and whatnot, note that this won't actually create these users on the server, you have to do it yourself. A valid declaration of admin user would look something like this:

admins = { "admin@domain.ltd" }
	
That's not really required of course, you can do fine without any users with admin rights as you can always access your server by ssh.

Enabling libevent for better connection handling under high load

This may not be needed when your server is small but better is always better especially so when it doesn't add many dependencies in this case just one program: lua-event. To enable libevent uncomment this line (by deleting -- at the beginning of the line):

use_libevent = true
	
Easy, isn't it?

Making community modules available

Something I'd consider must have is telling prosody the location of previously cloned community maintained modules repo. You can do that by adding the path to an option named plugin_paths like this (uncomment it first):

plugin_paths = { "/usr/lib/prosody/prosody-modules-enabled" }
	

Enabling modules

Then you should enable some more modules in modules_enabled to make your xmpp server more functional, these modules would be: mam (to let your clients download messages already downloaded by your other clients, you can tell prosody how long you want to store these messages), csi_simple (to optimize prosody for mobile devices), groups (so you'll be able to group your contacts), server_contact_info (to publish contact info to maintainers of your server or admins or whatever really). Now, those modules are maintained by prosody so you only need to uncomment them, now I'll list a few of community maintained modules which you need to insert by hand into modules_enable. Those would be: bookmarks - so your users can bookmark shit, smacks - to make resuming a disconnected connection possible which may come in handy when your connection is unstable and you want to prevent message loss - and cloud_notify - for push notifications. Note that you need to enable all the modules I've listed to get almost a 100% compliance rate on conversations's xmpp compliance tester. I've skipped turn and stun servers as I haven't used them yet.

Changing settings for enabled modules

I like to keep my config files in some order so after enabling additional modules I decided to change their settings just underneath the modules_enabled option, note that what I'll be modifying here isn't strictly necessary. There are a few settings I've changed (apart from http and https ports which is totally stupid and I need to revert that) like in case of contact_info which provides other users with you guessed it contact info for various users on your server - to get closer to 100% compliance rate on conversations' tester you need to add both abuse and admin info there like this:

contact_info = {
	abuse = { "xmpp:user@domain.ltd" };
	admin = { "xmpp:user@domain.ltd" };
}
	

Obviously you need to change domain.ltd to you actual domain and user to your preffered user which you'll need to create later. I've also changed two settings regarding cloud_notify:

push_notification_with_body = "true"
push_notification_with_sender = "true"
	
And that's about it for the settings I've changed for modules I've enabled.

Enabling in-band registration

In-band registration is disabled by default and I consider it a good thing, because my server is for personal use and I can still create users for whoever by sshing into my server. If you want tho you can enable in-band registration by changing the value of allow_registration from false to true

Enabling legacy ssl and forcing encryption and certificate authentication

You need to enable legacy ssl to get closer to 100% compliance rate but that's not required to make your server work, to enable legacy ssl you need to add a line like this: (preferably below settings you've changed previously)

legacy_ssl_ports = { 5223 }
	
While not stricly necessary you can improve your security a lil bit by forcing encryption on both client and server connections by changing values of c2s_require_encryption and s2s_require_encryption to true.

You can also force certificate authentication but that would break connecting to servers with invalid or self-signed certificates. If you still want to do that change uncomment the line with s2s_secure_auth and make sure the value is true. You can then unbreak specific domains by adding them to s2s_insecure_domains (ofc uncomment that first too). I'd advise against forcing certificate authentication as there's nothing wrong with self-signed certificates.

Configuring mam

Now this is really important as without this using omemo (encryption) on multiple different clients will basically break (you won't be able to get seen messages on one client on another client and so on) and as mam is present already in modules_enabled we now only need to configure for how long we want to store our messages in archives. I'd say the default value of one week is great but you can change it if you want.

Logging

By default prosody logs to syslog and additionaly you can enable logging to a file and to the console. I'd say tho that you probably don't need logging at all and should turn it off by default and only turn it on when you'll have to debug some client not working or in similar situations. So go ahead an comment out that line with "*syslog" in it.

Specifying certs location

There are two settings for specifying certs location but they're for different things, so you probably need to set up both. First setting is called certificates and it wants to know the directory with certificates relative to the main config file, certificates that're present in that directory will be used to encrypt connections from the server to other servers and to clients. The default folder is called certs and that's where I told you to put your certificates earlier so there's no need to change that really. Second setting is called https_certificates and it wants a full path to a file containing both fullchain certificate and your private key and you should point it to a previously set up https.pem file, this file will be used for encrypting connections made to prosody's http server used for i.e. uploading and downloading files.

Telling prosody which domain to use

Pretty self-explanatory, it's basically a name of the server. The setting for that is called VirtualHost and you should point it to the domain you own and want to use, for example:

VirtualHost "leglock.me"
	

Setting up components (another name for modules)

This is basically the last step of configuring prosody and it doesn't really differ from setting up other modules, I'll list here components I have enabled and tell you what they're used for. First component is used for setting up MUC which stands for Multi User Chat which basically means groupchats, if you want to set up groupchats on your server (note: not setting this up doesn't prevent you from accesing MUCs on other servers) you should set this one up. I have mine set up like this:

Component "conference.leglock.me" "muc" -- note: specific url just for MUCs can be a CNAME record
	restrist_room_creation = "local" -- only users registered on this server can create MUCs
	modules_enabled = { "muc_mam", "vcard_muc" } -- enables MAM (archiving messages for up to 1
	week as specified earlier) and VCards (avatars) in MUCs
	

Another component (module) you may want to enable is a proxy module which enables two clients behind NAT routers or firewalls to send files to each other. You can define it like this:

Component "proxy.leglock.me" "proxy65" -- url just for proxy needs an A record when proxy65_address is not set
	proxy65_address = "hprx.leglock.me" -- url for proxy set up as an A record
	proxy65_acl = { "leglock.me" } -- only users from this server can use it
	

The last component I have set up is used for sending files in chats, very useful if you ask me and should absolutely be a must-have, it's alos very easy to set up just like the rest of things in this guide. To set it up:

Component "upload.leglock.me" "http_upload" -- specific url, can be a CNAME record
	http_upload_file_size_limit = 8388608 -- max upload size in bytes, can't be more than 10MiB
	http_upload_expire_after = 60 * 60 * 24 * 7 -- files are deleted after a week
	(note: by default uploaded files are saved to default storage path, in Arch's case it's
	/var/lib/prosody/http_upload/)
	
That's pretty much it when it comes to setting up prosody, now we may proceed to actually running it and creating some users.


Starting prosody and creating users

Starting prosody is very easy, basically all you need to do is start it by the service manager your system provides (systemd for Arch, OpenRC for Gentoo/Artix, BSDs init) and then when everything is working how it should be you can enable it on boot (add to default init or whatever your init does). When prosody is running you can check if everything is ok by issuing prosodyctl check as root. That should give you a basic overview of what's wrong, nothing should be tho (if there's something wrong with certificates make sure the group of user running prosody can read them). Then you can create your first user by issuing prosodyctl adduser user@domain.ltd (ofc replace user with username of your choise and domain.ltd with your domain - must be the same as VirtualHost) it will automatically ask you for password you want that user to use and you can later change that using a client of your choice. That should be all and you can start messaging other people on xmpp now ;).


Some quirks

One thing I've stumbled upon when running prosody is that after a suspend-resume cycle I have to restart prosody by issuing (in my case) sudo systemctl restart prosody to make it work correctly (fetch messages, show people on other servers as online or even be able to chat with them) but other than that everything is working just fine.


Thanks wbsurfer for proofreading ;)


Viewable in any browser Valid XHTML 1.1 We run GNU Cloudflare is not an option Micro$oft free! Discord? No way hacker emblem


Created: 2021.01.10