Keel ntfy: an alert server for one site, as a layer on Keel Web (decision 0063)
- Shell 99.3%
- Makefile 0.7%
| .forgejo/workflows | ||
| conf.d | ||
| keel | ||
| overlay | ||
| plan | ||
| tests | ||
| .gitignore | ||
| changelog | ||
| COVERAGE.md | ||
| LICENSE | ||
| Makefile | ||
| README.rst | ||
Keel ntfy
=========
`ntfy`_ is a server that sends a message to a phone. This layer is the alert
server of Keel Linux for one site (handbook decision 0063). It is built on
the ``web`` layer:
bt-layer ntfy --parent web
The chain is Core, Web and ntfy. The server is the ``ntfy`` package of
Debian 13, version 2.11. Keel has no package of its own for it.
Why a server of its own
-----------------------
An alert must not depend on what it reports. A server on a pair would
depend on the VIP, etcd, the mesh and the replication, which are the parts
that it must report on. So each site runs one node of one, outside the
cluster that it watches. keel sends each alert to every server in its list.
A phone subscribes to the same topic on all of them.
What the layer adds to Web
--------------------------
- ``ntfy.service`` on ``127.0.0.1:2586``, with the configuration
``/etc/ntfy/server.yml``. The server trusts the proxy, denies all access by
default, keeps no attachment and contacts no other server. Its state is in
``/var/lib/ntfy``.
- A route in each include directory of Keel Web. Nginx terminates HTTPS and
proxies to the loopback. It does not buffer, and it waits 1 hour for a
subscription. Port 80 does not serve ntfy: it serves the ACME HTTP-01
challenge, and answers 301 to HTTPS for every other request.
- A preset that keeps ``ntfy-client.service`` of the Debian package off.
- The route in ``keel-front.d`` takes the request before Anubis. Anubis
does not challenge ntfy, because the clients are apps and keel. Coraza
still inspects the request.
- The first boot hook ``45ntfy``. It writes ``base-url`` from
``app.options.base_url``, starts the server and makes two accounts. The
administrator has the role ``admin`` and the password
``secrets.app_password``. The publisher can only write, to any topic.
- The manifest ``ntfy.yaml``. It declares the process, a health check of
``/v1/health``, the option ``base_url`` and the secret
``publisher_password``.
The image has no account, no token and no password. The user database does
not exist in the image.
The token
---------
ntfy makes the token. It cannot take a value that the description chose.
So the token is not a secret of the instance description. The first boot
writes it to ``/etc/keel/secrets/ntfy_publish_token``. Only root can read
the file. Copy the token to ``monitor.notify.ntfy.token`` of each node that
sends alerts to this server. A later run of the hook keeps the token.
Who may read
------------
The publisher cannot read. The administrator reads and writes every topic.
A person who reads gets an account with read access to the topics of their
tenant (decision 0063, point 4). Make it on the machine, as the service
user:
NTFY_CONFIG_FILE=/etc/ntfy/server.yml setpriv --reuid=_ntfy --regid=_ntfy \
--init-groups /usr/bin/ntfy user add NAME
A later step makes this a part of the description.
The mode
--------
The node is a simple installation. In that mode the ``vip``, ``etcd``,
``wireguard``, ``crowdsec``, ``coraza`` and ``anubis`` overlays are all
disabled. Manifest version 1 does not let a child change the state of an
overlay that it inherits, so ``ntfy.yaml`` lists no overlay. Write
``installation.mode: simple`` in the description, as
``keel/instance.example.yaml`` does. A cloud mode would enable the mesh and
etcd, and ``keel spec validate`` does not refuse it.
Tests
-----
See ``tests/README.md`` and ``COVERAGE.md``.
.. _ntfy: https://ntfy.sh