Matrix gateway setup with ejabberd

As of version 24.02, ejabberd is shipped with a Matrix gateway and can participate in the Matrix
federation
. This means that an XMPP client can exchange messages with Matrix users or rooms.

Let’s see how to configure your ejabberd to enable this gateway.

Configuration in ejabberd

HTTPS listener

First, add an HTTP handler, as Matrix uses HTTPS for Server-Server API.

In the listen section of your ejabberd.yml configuration file, add a handler on Matrix port 8448 for path /_matrix that calls the mod_matrix_gw module. You must enable TLS on this port to accept HTTPS connections (unless a proxy already handles HTTPS in front of ejabberd) and provide a valid certificate for your Matrix domain (see matrix_domain below). You can set this certificate using the certfile option of the listener, like in the example below, or listing it in the certfiles top level option.

Example:

listen:
  -
    port: 5222
    module: ejabberd_c2s
  -
    port: 8448 # Matrix federation
    module: ejabberd_http
    tls: true
    certfile: "/opt/ejabberd/conf/matrix.pem"
    request_handlers:
      "/_matrix": mod_matrix_gw

If you want to use a non-standard port instead of 8448, you must serve a /.well-known/matrix/server on your Matrix domain (see below).

Server-to-Server

You must enable s2s (Server-to-Server federation) by setting an access rule all or allow on s2s_access top level option:

Example:

s2s_access: s2s

access_rules:
  local:
    - allow: local
  c2s:
    - deny: blocked
    - allow
  s2s:
    - allow # to allow Matrix federation

Matrix gateway module

Finally, add mod_matrix_gw module in the modules list.

Example:

modules:
  mod_matrix_gw:
    matrix_domain: "matrixdomain.com"
    key_name: "key1"
    key: "SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo="

matrix_domain

Replace matrixdomain.com with your Matrix domain. That domain must resolve to your ejabberd server or serve a file https://matrixdomain.com/.well-known/matrix/server that contains a JSON file with the address and Matrix port (as defined by the Matrix HTTPS handler, see above) of your ejabberd server:

Example:

{
   "m.server": "ejabberddomain.com:8448"
}

key_name & key

The key_name is arbitrary. The key value is your base64-encoded ed25519 Matrix signing key. It can be generated by Matrix tools or in an Erlang shell using the command base64:encode(element(2, crypto:generate_key(eddsa, ed25519))).:

Example:

$ erl
Erlang/OTP 24 [erts-12.3.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [dtrace]

Eshell V12.3.1 (abort with ^G)
1> base64:encode(element(2, crypto:generate_key(eddsa, ed25519))).
<<"SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo=">>
2> q().
ok

Once your configuration is ready, you can restart ejabberd.

Testing

To check if your setup is correct, go to the following page and enter your Matrix domain (as set by the matrix_domain option):
https://federationtester.matrix.org/

This page should list any problem related to Matrix on your ejabberd installation.

Routing

What messages are routed to an external Matrix server?

Implicit routing

Let’s say an XMPP client connected to your ejabberd server sends a message to a JID user1@domain1.com. If domain1.com is defined by the hosts parameter of your ejabberd server (i.e. it’s one of your XMPP domains), the message will be routed locally. If it’s not, ejabberd will try to establish an XMPP Server-to-Server connection to a remote domain1.com XMPP server. If this fails (i.e. there is no such external domain1.com XMPP domain), then ejabberd will try on the Matrix federation, transforming the user1@domain1.com JID into the Matrix ID @user1:domain1.com and will try to open a connection to a remote domain1.com Matrix domain.

Explicit routing

It is also possible to route messages explicitly to the Matrix federation by setting the option matrix_id_as_jid in the mod_matrix_gw module to true:

Example:

modules:
  mod_matrix_gw:
    host: "matrix.@HOST@"
    matrix_domain: "matrixdomain.com"
    key_name: "key1"
    key: "SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo="
    matrix_id_as_jid: true

In this case, the automatic fallback to Matrix when XMPP s2s fails is disabled and messages must be explicitly sent to the matrix gateway service Jabber ID to be routed to a remote Matrix server.

To send a message to the Matrix user @user:remotedomain.com, the XMPP client must send a message to the JID user%remotedomain.com@matrix.xmppdomain.com, where matrix.xmppdomain.com is the JID of the gateway service as set by the host option of the mod_matrix_gw module (the keyword @HOST@ is replaced with the XMPP domain of the server). If host is not set, the Matrix gateway JID is your XMPP domain with the matrix. prefix added.

The default value for matrix_id_as_jid is false, so the implicit routing will be used if this option is not set.


Let us know what you think 💬


5 thoughts on “Matrix gateway setup with ejabberd

  1. Hi, probably “great” but on version ejabberd 24.02 linux after hours and hours just get :
    ******** ERROR
    2024-03-11 06:49:06.336771+01:00 [critical] @ejabberd_app:start/2:72 Failed to sta
    rt ejabberd application: Invalid value of option listen->2->request_handlers: Expected map,
    got empty string instead

    • Thanks for the report.
      If you could share the full log on Github, that would be helpful.

      Thanks !

  2. Hi ,

    -1- i understand that XMPP is a standard ( created in 1999 under the Jabber name, became XMPP in 2004 ) with very hight level specifications.

    According to Madam Amandine Le Pape ( source : https://usbeketrica.com/fr/article/matrix-le-protocole-decentralise-made-in-france-qui-cartonne-en-ukraine )
    she pretend that in 2014 there were NO protocol which offer interoperability and decentralisation …
    She pretend that Matrix is a STANDARD,

    So my question are :
    Does Matrix is a STANDARD ? Does XMPP is a STANDARD ?
    And last but not least could we please organise a collect to buy a Labrador to Madame Le Pape who since 2014 has a very bad view cause she was NOT able to type into google ” instant messaging protocol ” with the consequence that she feel herself oblige to creat one.

    -2- you are right : i had a indent error, but now i can telnet the port localy but not from external … Where to place ” s2s_access: s2s ” maybe ?

    Cheers

    • Matrix is supported by a foundation, but it is not a standard. A standard is defined by standard organizations.

      XMPP is an IETF (Internet Engineering Task Force) standard. The Internet Engineering Task Force (IETF), founded in 1986, is the premier standards development organization (SDO) for the Internet.

      Regarding your question, if you can telnet locally, it means it is not an ejabberd issue, but a networking/routing/firewalling configuration issue.

      Cheers,

Leave a Comment


This site uses Akismet to reduce spam. Learn how your comment data is processed.