Google Hangouts (at least as we know it) is going
The company’s largest messaging app, which has been around for 15 years
and was tightly integrated into Google Talk and GMail, will slowly lose
features over the coming months before being killed off entirely.
As this venerated, popular, way to keep in touch slowly dies, you might
be wondering, “what if I could run a messaging service? That way I
control how long it lasts. And I could ensure it was safe and secure,
with no advertisers (or other people) reading my messages.
Well, here’s the thing: you can! I made a private XMPP (Jabber) server
for my husband and I, and you can too!
Before I talk about how I did this, and the pitfalls you may face, I
want to address a question you’re probably asking: Why? There are plenty
of other messaging products out there (after they kill of Hangouts,
Google alone will have four other chat services). And there are privacy
focused messaging services: WhatsApp and Signal are both end-to-end
encrypted, preventing the messaging operators from reading your
messages. So why bother with any of this?
In a word: control. Running your own messaging service lets you define exactly
what you want. While I’ll be setting up XMPP, a pretty
simple instant messaging protocol, you can instead deploy
something like Slack and Discord, offering channels for group discussions and
direct messages (Mattermost is the free, open source
alternative to Slack that seems most popular) or, if you wanted to go in the
other direction, simple Internet Relay
Chat is still alive and
kicking (the classic internet chatroom, created in 1988, where you only see
messages when you’re logged in).
Regardless of what you’re going for, all these options let you define
your own security and rules – you’re not bound by message size limits,
restrictions on how many people can be in your chat or how much history
you can save. It is your private messaging system – you can do what you
Plus, you’ll get hacker cred. And I know you, dear reader, want that.
And Now, A Warning
So I’ve said why you might want to do this (or at least why I did). Now
let me tell you why you might not.
Running servers on the public internet is a responsibility. If you’re
acting as your own server admin, it’s up to you to make sure that server
is secure, and not getting
and attacking vulnerable
It’s not hard to setup a server online – there are excellent
to help you get started, and the initial setup will probably take 15-20
minutes if you’ve used Linux with a command line before. And even if you
haven’t, the basic aren’t too difficult to
But once your system is up and running, you do need to monitor it. That
means logging in every so often (at least every month or so) and
checking if there are security updates, making sure the SSL certificates
are up to date, etc… While you can automate much of this with tools like
it’s still a thing you have to check up on. While it shouldn’t take more
effort than a basic houseplant, it’s still a thing you need to care
If that doesn’t appeal to you – that’s totally fine!
Signal is an excellent, privacy focused
messenger that works beautifully!
Mattermost will give you a
private instance, for free, for up to ten people, with unlimited
history. Discord is readily available.
But you will be beholden to their policies and rules. That’s the
And there’s something freeing about building your own thing!
XMPP and The Joys of Decentralized Platforms
As I mentioned, I’ll be talking about setting up an
XMPP server. The Extendable Messaging and
Presence Protocol (also known as Jabber) has been around since the late 90s, and
coexisted with other popular IM systems like AOL Instant Messenger (AIM) and MSN
Messenger back in the day.
While it’s old, it’s still quite capable, and has provided the backend
for other messaging platforms, including Facebook Chat and Google
Unlike other IM systems even today, XMPP works on a decentralized
platform. Instead of everyone needing to be on the same service (like
Facebook Messenger, where there’s only one place you can get an
account), XMPP is like email – users are
email@example.com. And they
can talk to each other freely – so I, at
happily chat with you at
There’s something beautiful about this model (and is something I’ll talk
more about if I ever do a write up of decentralized social networks like
Mastadon); by having a decentralized
network, rather than a monolithic service, each server operator can set
their own policies, and users can shift between them while still being
able to talk to their friends. Want to send bigger files than your
server allows? Switch servers. Want private chatrooms but your server
doesn’t offer them? Switch servers.
Similarly, the clients for XMPP were not bound to any network (in the
same way most desktop email clients can talk to any mail provider), so
you also could choose which client you liked the most!
This decentralization and freedom comes at a cost though – complexity.
Not every client implemented every feature, and even if they did have a
feature, it might not work when chatting with someone using a different
program. This was one of the things that bit me in this journey. But
more on that later.
Let’s Build This Thing!
While there’s nothing stopping you from running your chat server on a
$30 raspberry pi under your desk
(that’s actually what I did for my husband and I), I’ll be discussing
creating a public server, using a public cloud provider.
While all this might seem daunting at first, but the basic order of
- Get a server and setup your admin account
- Get a domain (and point it to the server)
- Get SSL Certificates
- Setup the XMPP software on the server (and setup SSL certificates as
part of that step).
This should take about 30 minutes for someone who has setup a server
before, but can take a few hours or more if you run into trouble.
I do think it’s good to learn about computers and networks by doing, and
I do think you’ll learn quite a bit by giving this a shot, but, again,
no shame if this isn’t for you.
Step 1: Setting Up Our Server
Your server is the heart and soul of this project – the physical thing
that connects to the internet, and allows you to be
firstname.lastname@example.org. There are quite a few companies that
will sell you servers, including the “big” cloud infrastructure
providers (Amazon Web Service, or Microsoft Azure). That said, if you’ve
never done this before, I’d recommend grabbing one from Digital
Ocean – their least expensive
“droplet” costs $5/month, but their documentation and support is solid,
and their systems are turn-key, requiring very little configuration or
Setting Up SSH Keys
Before we login and hit that “Create” button we’re need to prepare our
system. We’re going to want to use SSH Keys to connect instead of plain
old passwords. You can think of these keys as special files that will
enable you to login (instead of using passwords). This is far more
secure, and Digital Ocean can pre-setup a system to use key-based
logins. You just have provide the keys, so… let’s create some keys!
Since this is going to depend on if you’re on Mac, Windows, or Linux
(though, if you’re already on Linux, I suspect you know the drill), I’m
instead going to link to you Digital Ocean’s own documentation here on
Creating Keys and Adding them To Your
Just note that you’re adding keys to your account, not a specific
droplet, at this stage.
Creating Our Droplet
Once you have your keys setup and uploaded into Digital Ocean, you’re
ready. Go ahead and hit that Create button in the upper right of the
Digital Ocean website, and then hit ‘Droplet’!
You’ll be asked a few questions about what type of Droplet you want –
here’s the quick reference:
- Distribution: Ubuntu 20.04 LTS x64 (well supported, reliable, and
will receive updates until 2025)
- Plan: Basic, $5/mo (you shouldn’t need more capacity than the $5
tier, even if you have quite a few users)
- Block Storage: None (don’t do anything here)
- Datacenter: Pick the one closest to you
- VPC Network: Leave this alone
- Authentication: SSH Keys (and check the key you uploaded)
- How Many Droplets: 1
- Hostname: This can be anything and distinguishes this from other
droplets you may have, so the only real requirement is to make it
descriptive, like chatserver
- Backups: Not required, but up to you. They do cost a small amount
It will take a minute or two once you hit the final button, but once
it’s done you’ll get an IP address for your new droplet, that you can
login to via SSH. You can follow the instructions here on how to
Note that since you’re using SSH keys – you’ll need to login from a
computer with the SSH keys. You can move them between computers – but
remember you’ll need them to access your server.
At this stage we want to setup a regular user on the server (it’s bad
practice to always login as the admin), and setup things like the basic
firewall. Thankfully, there’s a guide for this too – just follow along
At this point, you should have a server online, ready, and secured, that
we can use. Now we need to a domain to point to it.
Step 2: Getting a Domain
If you want to be
email@example.com (for example) – you need to own
someplace.net. Namecheap is a popular
domain registrar that will allow you to buy a domain, though there are
others like GoDaddy.
Some quick terms: the domain registrar allows you to buy the name, and
then the name servers (usually run by the registrar) directs someone who
someplace.net over to your server.
Now, technically you don’t have to use domain. There’s nothing
stopping you from just using IP addresses. But, that’s both a pain for
users (who wants to remember 220.127.116.11), and will complicate the
certificate setup, so… I’d strongly recommend getting a domain.
Aside: If you’re really opposed to spending money, there are free
services like DuckDNS that allow you to get
a subdomain (
myaccount.duckdns.org) for free. The only requirement here
is that you will need the ability make subdomains
chatrooms.mywebsite.org). Thankfully, this is standard when you buy a
top level domain (
mywebsite.org), and some subdomain providers (like
DuckDNS) automatically route all subdomains (like
chatrooms.myaccount.duckdns.org) to your primary subdomain (so, in this
chatrooms.myaccount.duckdns.org would automatically route to
Anyway, once you register your domain (which may take up to 72 hours to
process), you’ll want to add two ‘A’ records to point to your server.
Assuming you’ve registered
someplace.net, you’ll need:
An ‘A’ record for your ‘root domain’ (
someplace.net) pointing to
your server’s IP address (which you got from Digital Ocean)
Another ‘A’ record, called a wildcard record, that also points to
the server’s IP address.
You need that second record because we’re going to use ‘components’ in
XMPP. These components power things like multi-user chatrooms, image and
file transfer, and more. However, they need their own address (like
upload.someplace.net). Instead of creating a record for each one, we’re
creating a wildcard record that says “if we haven’t specified otherwise,
just route it to the main server.”
How you’re going to insert these records varies from registrar to
registrar, unfortunately. However, for Namecheap, the procedure is
Note: if your registrar/name service doesn’t allow you add wildcard
records, you’ll need to create subdomain records for each service
manually. To do that, create three additional ‘A’ records, one for each
of the components:
At this point, you should be able to SSH into your server, specifying
the domain name instead of the IP address (
for example). Remember, it can take a while after setting these records
for them to be reflected across the internet, so don’t worry if it
doesn’t work immediately after adding the records.
Step 3: SSL Certificates
This used to be the hard part.
You’re creating a public service that is online and accessible on the
internet, which means you’re going to want SSL. The SSL certificate
does two things – it enables encrypted connections to your site, but
also proves that your server is actually the one responding to the
request (the SSL connection you have with this site confirms to your
computer that you’re really connected to seanzwrites.com, and not
someone who just jumped in the middle and hijacked the connection).
You used to have to pay money for certificates and installing them could
be painful. Thankfully, this is no longer the case, and you can get
certificates for free, automatically, from within your server itself,
thanks to Let’s Encrypt.
We’ll cover this in the next section.
Step 4: XMPP Server Software
At this point, you’ve setup a server on the internet. Congrats! It could
do so many different things – it could host a website, a private social
media instance, your own file
store, a private
for you and your friends to game… You have options!
But we’re making a XMPP server, so let’s install some XMPP software.
While the configuration isn’t hard, I’m actually going to route you to
another tutorial, which will walk you through the process of getting SSL
certificates, setting up the XMPP server, creating your first XMPP user,
and setting up those pesky certificates to auto-renew.
Here’s that tutorial from the homebrewserver.club
Note – you’ll need to use the command line on your server to add
accounts manually, unless you want people to freely register accounts on
your server (you probably don’t). Users can change their passwords on
their own, though, so you just need to give them a starter-password.
Step 5: Connecting
You’ve built a server, you’ve installed software, all that’s left is to
For this, you’ll need an XMPP program on your PC. I’d recommend
Gajim (Windows) or Monal
(Mac). Like an email client, just enter your information, and hit
connect. You’ll be greeted with a list of contacts (which is likely
empty), but still – you’ve done it!
At this point, you’re set. Create accounts for your friends, grab a
client for your phone (Xabber, ChatSecure and
Conversations are well reviewed), and enjoy
the fact that you’re free. You control your own instant messaging
Coda: Why Doesn’t File/Image Transfer Work in XMPP?
If you’re following the tutorial from HomeBrewServer that I linked
above, you there’s a good chance you won’t run into component problems.
But complexity around components and clients can often lead to some
frustrating problems. So, even if you followed the tutorial (or if you
didn’t, and you somehow ended up here because you were wondering why you
couldn’t send an image in XMPP), let’s talk about components and
Think of components as services that provide additional functionality on
top of the basic instant messaging system, like providing multi-user
chatrooms, or mediating direct file transfer connections.
Some components require their own subdomains (like
for the HTTP upload component). It’s important that you both configure
this domain in the DNS/name server record (or have a wildcard), and
include it in your SSL setup (again, you were instructed to do this in
the earlier tutorial, so you’ve likely already done this — don’t worry).
I bring this up because these components, in modern instant messaging,
are less optional and more expected. For example, here’s something that
you’d probably assume was incredibly simple: sending someone an image
file in chat.
Because of XMPP’s age, and its need to work across servers, it does not allow
you to just send a big file as part of a message itself (email also has this
problem). The way this was solved in most XMPP clients and servers was to
simply transfer the file to the server – when you want to share a file, your
client uploads it to the server with your account, and then the server forwards
a link to the file to the other person. That’s what that HTTP upload component
is doing – allowing your client to shove the file somewhere that is accessible
for another user. It’s a pretty simple solution.
The problem is not every XMPP program does this. Pidgin, for example, is
a very popular instant messaging client doesn’t support this type of
file upload in XMPP. However, it does support a different way of
transferring images – sending them directly to the other person using
the server as a mediator (supported by, you guessed it, a different
component – proxy65).
When looking at the webpage for a messaging client, it will tell you all
the features it supports, like sending images, and it probably does all
the things it advertises. What might not be obvious is how it’s
handling that, since XMPP’s age and flexibility allows for more than
one way to do something.
So if you’re wondering why something doesn’t work with one friend who’s
using a different program, or with one feature, look at the XEPs – the
XMPP enhancements — supported by the client. XMPP clients often have a
page in their documentation where they list which XEPs they support
(here’s the list for
Usually XEPs directly correlate to features (HTTP upload, for example,
is XEP-0363). If your client doesn’t support that specific XEP, it
probably won’t play nice with other clients doing that same task.