Selfhosted Matrix Notifications

Selfhosted Matrix Notifications
Photo by Brett Jordan / Unsplash

In my last post I wrote about setting up a matrix server:

Setting up a matrix server
I was curious and wanted to try setting up a Matrix server again. I’d already attempted it a few years back, using Synapse as the server and Element as the client. My conclusion then was that it was a bit annoying to set up, and the client’s usability and

After that I fiddled a bit around to get notifications working on my android phone without relying on google firebase.

ntfy.sh

ntfy.sh is an excellent self-hostable notification service. There are many ways to install it - at first I tried out the docker version because it is the easiest way to get started and the easiest to remove if it would not fit my case.

Let's look at the relevant config items I set:

The Server

  • base-url for the domain
  • listen-http because I will run it behind a reverse-proxy
  • behind-proxy this is important for internal handling of the IP and therefore the rate-limiting

Authentication

  • auth-file this is the file path for the user database
  • auth-default-access I set this to deny because I don't want my server to be public by default
  • auth-users this is a list of users, each entry carries 3 values. The auth-users will be written to the auth-file database when ntfy.sh is started. This way you can update the users simply based on the config
    • the user name
    • a bcrypt hash of the password
    • the role of the user
  • auth-access this is a list of permission entries, you can allow access to certain topics to certain users, read only, write only or both
  • auth-tokens this is a list of tokens that allows a user to intact with the ntfy api without relying on basic auth

ntfy.sh android app

There are different ways to subscribe to topics but I will focus on the free android app.

One important note: You have to disable battery optimization because otherwise, especially on samsung phones, the app will be killed and not receive notifications.

There will be a persistent notification pinned to your phone which is annoying at first but it can be disabled by disabling the "subscription service" notification channel:

From your phone - ntfy
Send push notifications to your phone via PUT/POST

Unified Push

I already use the app for other notification like monitoring so I was pleasantly suprised when the Matrix Element App suggested using ntfy.sh as UnifiedPush Distributor. What does that mean?

Picture by Element Knowledge
  1. The element app asks the ntfy app to create a unified push topic
  2. ntfy server will respond with a topic name like "upEX4MP3L" and offers the matrix push gateway at /_matrix/push/v1/notify
  3. The ntfy app now listens to this topic
  4. The element app tells the matrix server "please notify me using this unified push endpoint with the following topic name"
  5. The matrix server send future notification request to the distributor (the ntfy.sh server) which distributes it to anyone listening to the topic
  6. The ntfy app receives the notification and wakes up the element app which then triggers an android notification by element

Troubleshooting

After a bit of confusion why it does not work I found the UnifiedPush config example in the docs:

UnifiedPush requires that the application server (e.g. Synapse, Fediverse Server, …) has anonymous write access to the topic used for push messages. The topic names used by UnifiedPush all start with the up* prefix. Please refer to the UnifiedPush documentation for more details.

In my ntfy app I am authenticated using my user but the app does not share this authentication with the element app or the matrix server of course.

So adding this to the config allows anyone write-only-access to any topic starting with "up".

auth-access:
  - "*:up*:wo"

Since nobody will know the topic name it is safe in theory. The topic name is "up" followed by 12 alphanumeric characters upper/lowercase, which results in about 3.2 sextillion possible combinations and bruteforcing is not really possible because of per-ip and global ratelimiting on the ntfy server.

selfhosted matrix, selfhosted notifications! selfhosted phone when?