Decommissioning Matrix: Moving to XMPP for Instant Messaging

May 16 2021

With my recent announcement that I’ll be ending my personal Matrix service, there comes the added question: what now? For me it is a walk down memory lane, to XMPP.

Edit 2021 AUG 7: As much as I enjoyed XMPP back around 2010, the application ecosystem has changed a lot and there seems to be less support for XMPP now. I’m sorry to report that OMEMO wasn’t what I expected it to be either, and the major drivers for XMPP, to me, was being able to use Irssi or Weechat. That didn’t work out either and Profanity was disappointing. I’m leaving it with that and the fact that you can now again reach me on Matrix.

A list of the XMPP Extensions (XEP) is maintained at the XMPP Extensions website. There are currently 457 XEPs.

XMPP is a universal messaging standard which have been in active use for a long time. The same way it is challenging to use with different types of sub-standards, called XEPs, it is also a wonderful way to work with the ecosystem and different purpose-built clients. While Matrix was starting to build this ecosystem but had problems gaining momentum - especially for the CLI clients, XMPP has had a wide variety of support for different clients. Personally I found Profanity good.

For now I just wanted to share some details on how to get in touch via Jabber/XMPP after we have exchanged an email introduction via my contact page.

To get a JID (Jabber ID, XMPP JID, you can register at e.g.

When you have registered an account, and if you do not want a permanent presence on the network or do not want a desktop messenger, you may login through converse.js.

OMEMO, which is equivalent to Matrix encryption is defined in XEP-0384. I am particularly fond of the threat model described, the clarity of it. A recommended read.If end to end encryption is required for the conversation, which would make sense using third party XMPP servers - OMEMO can be enabled in converse.js.

Tags: #matrix #xmpp #decommissioned #transtion #messaging
Read with Gemini

Using Matrix For Out-of-Band Communications

July 11 2018

We have all been there during security operations. One of the parties involved in an incident or daily routine is not prepared for thinking they could be compromised.

Communications and information sharing is one of the fundamental things that you need to get right during a crisis.

James Comey about cyber breaches in 60 minutes.As now-retired FBI director James Comey put it to 60 minutes:

There are two kinds of big companies in the United States. There are those who’ve been hacked by the Chinese and those who don’t know they’ve been hacked by the Chinese.

– James Comey, 60 minutes, Oct 5 2014

The following question always arises: How do we maintain operational security while still being able to communicate with all parties involved?

In practical terms this requires a communications platform to:

  • Be independent of the service infrastructure
  • Provide traceability
  • Be resistant to resourceful threat actors
  • Have simple and secure identity management
  • Have cross-platform compability
  • Provide file-sharing capabilities and ability to give the user an opportunity to express himself
  • Support video and audio exchanges
  • Be under the control of the team using it (the smallest circle of trust)
  • Provide both end-to-end and transport layer encryption
  • Disposable server infrastructure

This could have been a bit too much to ask for a couple of years ago, but today there are at least two alternatives satisfying the above requirements: Mattermost and the Matrix ecosystem. For the remainder of this post I will focus on how to establish an ad-hoc system with the tools provided by the Matrix project.

Setting Up An Out-of-Band Channel for Incident Handling with Matrix

Getting started takes three steps:

Matrix Recorder is a recording bot using the Matrix API to archive short messages over time.

  1. Establish a back-end server on Digital Ocean
  2. Serve the Riot front-end website
  3. Establish a recording capability with Matrix Recorder

For the two first points, it is clever to use an approach that can be easily reproduced and that provides exactly the same, secure-by-default configuration each time. Due to this the preferred method in this case is to manage the VPS that can be established on anything with Debian or CentOS with Ansible. There is a script available on Github, known as matrix-docker-ansible-deploy. The latter have also been endorsed by the Matrix project. Both 1 and 2 can be accomplished with matrix-docker-ansible-deploy.

matrix-docker-ansible-deploy is an ansible role to deploy a Matrix server. In the Matrix Weekly there as a Matrix project endorsement for the ansible role. So let’s get started.

Basic DNS-service

For this example I created a domain on and pointed that to (ns1|ns2|ns3) It would be ufortunate for the continuity of the service if a domain was taken offline or redirected somewhere, but due to the end to end encryption in Matrix it would not compromise the content of the conversations. Now that Digital Ocean has control of the primary domain, make sure to add the following before continuing:

Type	Hostname	          Value	                       TTL	
A	    <domain>               <ip>                        600 
A	    riot.<domain>          <ip>                        600 
A	    matrix.<domain>        <ip>                        600 
SRV	    _matrix._tcp.<domain>  10 0 8448 matrix.<domain>   600 

This can take some time to propagate, so make sure that the DNS-infrastructure is readily resolvable before you continue deploying the services.


Make sure to grab a copy of the current matrix-docker-ansible-deploy by running:

git clone

Create the following files:


vars.yml should look like this:

host_specific_matrix_ssl_support_email: <your-contact-email>
host_specific_hostname_identity: <domain>
matrix_coturn_turn_static_auth_secret: "<run pwgen -s 64 1>"
matrix_synapse_macaroon_secret_key: "<run pwgen -s 64 1>"

The Ansible hosts file should be formatted like the following:

          ansible_user: root

Deploy and Execute

Now that your configuration files and server are ready, you can start deploying the Matrix Synapse server and start serving the Riot HTML/JS client.

First deploy the services (Riot and Matrix Synapse) by running:

ansible-playbook -i inventory/hosts setup.yml --tags=setup-main

When that completes successfully, you can start the services by:

ansible-playbook -i inventory/hosts setup.yml --tags=start

After starting the services, the Riot web interface is available on https://riot.<domain> where metadata is protected by a Let’s Encrypt certificate.

The two primary endpoints you now have exposed to the WWW is:

  • The Matrix API which runs at https://matrix.
  • The Riot UI which runs at https://riot.

Going to https://riot.<domain> brings you to the Riot logon-screen

Adding Users

Registration is disabled by default on the server, so new users can be added by the following command:

ansible-playbook -i inventory/hosts setup.yml
	     --extra-vars='username=<first user>
	                   password=<some password>

It is better to use pseudonyms on such a platform to make sure no information can be traced to a specific individual not involved in the case. Each user needs to verify his private key fingerprint with the other participants.

Vital Steps to Take as an Administrator

When using multiple servers, it is necessary to create an #control channel that is a fallback if a server hosting a room goes down.

Setup Matrix Recorder

To make sure that all communications is stored for traceability make sure to install the Matrix Recorded (MR). MR should be installed locally and not on the Matrix server.

git clone
cd matrix-recorder/
npm install

To execute the recorder, run the following. The first time you will be asked to enter the login credentials of the user.

$ node matrix-recorder.js <case-folder>
Loading olm...
Your homeserver (give full URL): https://matrix.<domain>
Your username at the homeserver: <username>
Your password at the homeserver: <password>
No of items to retrieve for initial sync: 1000

View messages as HTML by running the Matrix Recorder conversion script:

node recorder-to-html.js <case-folder>

Controlling Logins

Access monitoring can be done in the console by e.g. tail -f /matrix/synapse/run/homeserver.log.

The Power of Disposability

At some point you have finished the information exchange. The beauty of this setup is that is can now be safely deleted from the Digital Ocean droplet console.

Tags: #matrix #e2e #realtime
Read with Gemini

This blog is powered by cl-yag and Tufte CSS!