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
Diffstat:
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