sources for e1e0 website
git clone https://git.e1e0.net/e1e0.net.git
Log | Files | Refs

commit a356ede7a14e785c91638731e51cc77b07b6317d
parent 00555609dd1726e8c8383cb0d7df54cbb0874800
Author: Paco Esteban <paco@onna.be>
Date:   Thu, 25 Apr 2019 15:20:04 +0200

New article about self hosted XMPP server

Acontent/self-hosted-xmpp-server.md | 263+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 263 insertions(+), 0 deletions(-)

diff --git a/content/self-hosted-xmpp-server.md b/content/self-hosted-xmpp-server.md @@ -0,0 +1,263 @@ +title: Self hosted XMPP server (on OpenBSD) +author: paco +date: 2019-04-25 +css: style.css + +XXmenuXX + +--------- +# Self hosted XMPP server (on OpenBSD) +2019-04-25 + +Tested on OpenBSD 6.5 (prosody version 0.11.2) + +## Intro + +Self-hosting an instant messaging service is quite simple. This guide shows how +to do it using OpenBSD as a base system and XMPP as the messaging protocol. + +The end result is an End-to-End encrypted chat system for 1:1 or multi-user +conversations. + +The software used for the server is [prosody][1], and it's all based on +[this guide][2]. + +For the clients, I've tried [Gajim][3] for the desktop (works for Windows, +Linux and *BSD), [Conversations][4] on the phone (Android) and [profanity][5] +on the terminal (works almost everywhere). There's a client for iOS called +[ChatSecure][8], but I have not tried it. + +## Rationale + +I used to host my messaging services back in the day. People stopped using this +for some reason, and then came all the Whatsapp and co. So all that was +forgotten. + +Although I never used whatsapp, on recent times I've been testing some instant +messaging systems, but none of them were good enough. In the end, all rely on +central systems, often owned by companies that have to make money from +somwhere. Most of the times is you (one way or another) even if they say the +service is free. + +I wanted something simple, client independent, secure (well, as secure as +possible ...), easy to use from the client point of view and easy to manage +from the server part. My goal is to replace things like Signal that I use with +my family and friends. + +XMPP is federated, just like email is. And with recent extensions like easy to +use End-to-End encryption and http file sharing it's a viable solution for +resilient and secure instant messaging system, that does not spy on you (no +more than encrypted email for instance). + +For now is not a complete replacement, as it does not provide VoIP, but is a +start. I may look for voice alternatives or dig deeper for a jabber client that +supports voice. + +## Previous steps (DNS and TLS) + +Some DNS configuration is needed for this guide. If you are not using file +uploads or multi-user chat, then is probably fine if your root dns name points +to the machine that will host the xmpp server. If not, you'll have to define +some SRV records, and also any record you may use for the mentioned services. +It may look like this (config depends on your DNS provider): + + _xmpp-client._tcp 1800 IN SRV 5 0 5222 server.mydomain.com. + _xmpp-server._tcp 1800 IN SRV 5 0 5269 server.mydomain.com. + +This will tell xmpp clients and other servers trying to reach your accounts +where (host and port) to knock. + +In this particular case I configured also multi-user chat and http file +uploads, so I defined `uploads`, `proxy` and `groups` as `CNAME` of the +server's `A` record. + +I also configured `acme-client(1)` and `httpd(8)` to get certificates from +letsencrypt, so all communications client/server and server/server is +encrypted. + +How to do that is out of the scope of this guide, just read the man pages, it's +quite easy to do. The only detail to take into account is that is better to +have all the domains/subdomains with its own cert and into separated folders +containing the certificate and the private key. This important for certificate +import on prosody later on. So I ended up configuring it to store certs on a +structure like: + + /etc/ssl/letsencrypt/ + |-- mydomain.com + | |-- cert.pem + | |-- fullchain.pem + | `-- privkey.pem + |-- groups.mydomain.com + | |-- cert.pem + | |-- fullchain.pem + | `-- privkey.pem + ... + +## Server install + +Install the server is as easy as: + + $ doas pkg_add prosody + +## Server config + +So here comes the fun part. + +First you should get the community modules. Some of them provide functionality +that is needed on any modern IM system. + +The way to do that is cloning the [mercurial][6] repository. I did not want to +have it installed on my server, so I cloned it on my desktop machine and synced +to the server. So, on my desktop I did: + + hg clone https://hg.prosody.im/prosody-modules/ prosody-modules + +Then I uploaded it to `/usr/local/lib/prosody-modules/` on the server. +Here's the important parts I changed from the config files and why: + +Community modules location: + + plugin_paths = { "/usr/local/lib/prosody-modules" } + +List of globally enabled modules: + + modules_enabled = { + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + "carbons"; -- Keep multiple clients in sync + "pep"; -- Enables users to publish their mood, activity, playing music and more + "private"; -- Private XML storage (for room bookmarks, etc.) + "blocklist"; -- Allow users to block communications with other users + "vcard"; -- Allow users to set vCards + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + "register"; -- Allow users to register on this server using a client and change passwords + "mam"; -- Store messages in an archive and allow users to access it + "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + "server_contact_info"; -- Publish contact information for this service + "vcard4"; + "vcard_legacy"; + "smacks"; -- XEP-0198: Stream Management, keep chatting even when the network drops for a few seconds + "csi_simple"; + "bookmarks"; + "cloud_notify"; -- XEP-0357: Push Notifications. + } + +Disable registration, as this will not be a public server. This is the default, +but just check it just in case. + + allow_registration = false + +Force clients to use encrypted connections + + c2s_require_encryption = true + +Force servers to use encrypted connections. + + s2s_require_encryption = true + + +Force certificate authentication for server-to-server connections. This may +bring problems with servers that use self-signed certificates. Today nobody +should be using that, as there are alternatives like letsencrypt but, if you +have some server you want to talk to that uses self-signed certs, check +`s2s_insecure_domains` + + s2s_secure_auth = true + +Location of directory to find certificates in (relative to main config file), +on OpenBSD that's `/etc/prosody/certs` + + certificates = "certs" + +Virtual host. You can have many, for many domains. In my case this is just one +personal domain. I limited the uploads to 9MB, but you can set up any other +limit. Keep in mind that there's a 10MB limit for `http_max_content_size` + + VirtualHost "mydomain.com" + Component "uploads.mydomain.com" "http_upload" + http_upload_file_size_limit = 1024 * 1024 * 9 -- 9MB upload limit + Component "groups.mydomain.com" "muc" + modules_enabled = { "muc_mam", "vcard_muc" } + Component "proxy.mydomain.com" "proxy65" + +At this point you can import the certificates you got from letsencrypt (or from +any other CA), with the command: + + prosodyctl --root cert import /etc/letsencrypt/letsencrypt + +That will copy all needed files to `/etc/prosody/certs` so they are accessible +to the prosody daemon. Now you can start the daemon: + + doas rcctl start prosody + +To make it permanent on boot, add it to the `pkg_scripts` on +`/etc/rc.conf.local`. + +Also remember to open ports on the firewall (pf or any other you may have in +front of your server). They are: + + 5000 --> for proxying large file transfers between clients + 5222 --> for client to server + 5269 --> server to server + 5281 --> default https port for http file transfers + +## Add accounts and client config. + +In order to add an account to your new server just execute: + + prosodyctl adduser user@mydomain.com + +You'll be asked for the new password and that's it ! + +On the client side is usually enough to enter the jid (jabber id, in this +example `user@mydomain.com`) and the password. As we configured the necessary +dns records earlier, the client will discover to which server and port to +contact to. + +## OMEMO + +[OMEMO Multi-End Message and Object Encryption][7] is an extension to XMPP that +provides encryption for 1:1 and multi-user chats. + +This is key for a secure chat system. Some of the most popular xmpp clients +already support it. Conversations, for instance, has it enabled by default. +Do not forget to set it up on your client. + +OMEMO trusts devices on first use, then you should check the key fingerprints +to see if the person you're talking to is who it claims to be. + +Is a good practice to publish those fingerprints on some place public, like you +would do with your GnuPG public key. In fact you could sign those to provide +some proof of ownership. + +On Conversations, for instance, you can later verify a contact fingerprint via +a QR code. From that moment no other key will be allowed for that contact if +you do not explicitly allow it. I think all clients should support that ... + +## Conclusion + +Now you should have a working XMPP server. It can not only be used for IM, but +also for notifications on your scripts using the libraries for your language of +choice. Here you have some examples in [perl][9], [python][10] and [golang][11] + +--- + +[1]: https://prosody.im +[2]: https://homebrewserver.club/configuring-a-modern-xmpp-server.html +[3]: https://gajim.org/ +[4]: https://conversations.im/ +[5]: http://www.profanity.im/ +[6]: https://www.mercurial-scm.org/ +[7]: https://en.wikipedia.org/wiki/OMEMO +[8]: https://chatsecure.org/ +[9]: https://metacpan.org/pod/Net::XMPP +[10]: https://lab.louiz.org/poezio/slixmpp +[11]: https://github.com/FluuxIO/go-xmpp + +Last update: XXlastXX