2026-08-11 12:00:00 +00:00
---
type : wiki-page
area : admin
related : []
---
2026-07-30 12:00:00 +00:00
# matrix
2026-07-30 12:00:00 +00:00
Matrix-Homeserver (Element Server Suite / Synapse) + K3s-Single-Node-Cluster, GitOps-verwaltet.
2026-07-30 12:00:00 +00:00
| | |
|---|---|
2026-07-30 12:00:00 +00:00
| **Hostname** | `MATRIX` |
2026-07-30 12:00:00 +00:00
| **IPv4** | `49.13.132.245` |
| **IPv6** | kein AAAA-Record |
2026-07-30 12:00:00 +00:00
| **Privat** | `10.0.0.2` (`enp7s0` , dasselbe Hetzner-Netz wie CFGMON `10.0.0.3` ) |
| **OS** | Debian 13 (trixie) |
| **DNS** | `matrix.axion1337.de` **und** `matrix.axion1337.chat` zeigen auf dieselbe IP — ebenso `axion1337.chat` (Apex) und `account.axion1337.chat` (MAS). `axion1337.de` ist die ältere/Registrar-Domain (IONOS-Mail läuft dort), `axion1337.chat` die eigentliche Matrix-Service-Domain. |
2026-07-30 12:00:00 +00:00
| **Stand** | 2026-07-30 |
2026-07-30 12:00:00 +00:00
**Inventarisiert** (direkter SSH-Zugriff, `~/.ssh/config` -Alias `axion1337` , Port 2248):
K3s + FluxCD + Element Server Suite (Synapse, MAS, Element Web, MatrixRTC), Authentik (OIDC),
Traefik, Cert-Manager, coturn, Draupnir, ClamAV, NetworkPolicies (Default-Deny). IaC-Repo:
[`sorb/axion1337.chat-gitops` ](https://rohana.axion1337.de/sorb/axion1337.chat-gitops ) - dieser
Host **ist** das Deployment-Ziel dieses Repos, nicht nur verwandt. Client-Forks:
`sorb/ThreadNet-Web` (Element Web), `sorb/threadnet-call` (Element Call/LiveKit-Widget).
`sorb/element-web` und `sorb/ThreadNet-Stack` sind **veraltete/abgelöste** Vorgänger-Repos
(letzte Aktivität 2026-05-11 bzw. 2025-10-24) - nicht mehr das, was hier läuft.
2026-07-30 12:00:00 +00:00
2026-07-30 12:00:00 +00:00
`ufw` : aktiv, Default Deny Incoming / Allow Outgoing, explizite Allow-Regeln für
2248/tcp (SSH), 80/443, TURN/RTC-Ports. `unattended-upgrades` aktiv (Debian-Security +
Debian-Origin), siehe [MATRIX-04 ](#matrix-04--host-level-pre-update-benachrichtigung-erledigt ).
2026-07-30 12:00:00 +00:00
2026-08-01 12:00:00 +00:00
## Offene Punkte → git.lab-Issues
2026-07-30 12:00:00 +00:00
2026-08-01 12:00:00 +00:00
Seit dem Framework-Umbau (2026-08-01) leben offene Punkte als Issues im
[management-Projekt ](https://git.lab/axion1337.chat/management/-/issues ); die IDs bleiben in den Issue-Titeln erhalten.
Dieses File hält nur noch Bestand und Historie.
2026-07-30 12:00:00 +00:00
2026-08-01 12:00:00 +00:00
- [MATRIX-03 — `www.matrix.axion1337.de` ist überflüssig ](https://git.lab/axion1337.chat/management/-/issues/1 )
2026-07-30 12:00:00 +00:00
2026-08-01 12:00:00 +00:00
## MATRIX-05 — node-exporter-DaemonSet in CrashLoopBackOff, Cluster-Scrape seit 2026-08-01 tot
2026-08-01 12:00:00 +00:00
**Status:** erledigt (2026-08-01 ~04:10, vom Mac aus mit kubectl/SSH)
**Auflösung:** Beide Teile hatten dieselbe Wurzel — ein **doppelter node-exporter** .
Teil 1 bestätigt per Pod-Log: `listen tcp 0.0.0.0:9100: bind: address already in use` ;
den Port hält der systemd-Dienst `prometheus-node-exporter` (der etablierte, den CFGMON
via `10.0.0.2:9100` scrapt). Teil 2 erklärt: der Cluster-Service "funktionierte" nur in
den Ready-Momenten des Crashloop-Pods, dessen hostNetwork-Endpoint (= Host-IP) zufällig
auf den gesunden systemd-Exporter zeigte; seit der Endpoint dauerhaft NotReady war,
setzte kube-proxy `no endpoints → REJECT` . ufw-Regeln seit April unverändert — kein
Firewall-Drift; extern war 9100 nie freigegeben (und soll es nicht sein).
2026-08-09 12:00:00 +00:00
**Fix (gitops `228807f`, Weg A aus gitops#45):** HelmRelease + Alloy-Scrape entfernt,
2026-08-01 12:00:00 +00:00
Flux hat gepruned — DaemonSet/Service/Pod sind weg, Host-Metriken kommen unverändert
vom systemd-Exporter. Volle Diagnose:
2026-08-11 12:00:00 +00:00
`gitops#45` (Gitea-Zählung, Tracker stillgelegt — verbindlich: Migrations-Fußtext im GitLab-Issue).
2026-08-01 12:00:00 +00:00
<details><summary>Ursprünglicher Befund (CFGMON-Session, vor der Host-Prüfung)</summary>
2026-08-01 12:00:00 +00:00
Von CFGMON aus diagnostiziert, per kube-state-metrics und den remote-geschriebenen Serien.
**Auf dem Host selbst wurde nichts geprüft** — CFGMON hat kein `kubectl` .
### Teil 1 — der Pod crasht seit Monaten (chronisch)
| Messwert | Stand 2026-08-01 |
|---|---|
| Pod `prometheus-node-exporter-4wwn7` , Restarts | **4880** , davon 1970 in 7 Tagen |
| Vorgängerpod `…-fv7hj` , Zählerstand vor 30 Tagen | 13918 |
| aktuelle Rate | ~12/h — entspricht dem CrashLoopBackOff-Deckel von 5 min |
| `last_terminated_reason` | `Error` (Exit ≠ 0, **kein** OOMKill) |
| `waiting_reason` / `ready` | `CrashLoopBackOff` / `0` |
Das besteht mindestens seit 30 Tagen, also **lange vor** dem Monitoring-Rework und vor dem
Alerting-Rollout. Neu ist nur die Sichtbarkeit: die Regel `KubePodRestartLoop` kam am
2026-08-01 dazu. Wie bei Synapse hat das Alerting einen stillen Altfehler aufgedeckt.
**Vermutete Ursache, nicht verifiziert:** Der Pod läuft mit `hostNetwork: true` und will
Port 9100 auf dem Host binden. Dort hört bereits ein **eigenständiger node-exporter** —
derselbe, den CFGMON als Job `k3s_host_node` direkt auf `10.0.0.2:9100` scrapt und der
2706 Metriken sauber ausliefert. Zwei Exporter, ein Port; der Pod bekäme
`address already in use` und beendete sich sofort, was zu `reason: Error` ohne OOM passt.
Zum Bestätigen auf dem Host:
```
ss -lntp | grep :9100
kubectl -n monitoring logs prometheus-node-exporter-4wwn7 --previous | tail -20
```
### Teil 2 — der Cluster-Scrape ist am 2026-08-01 01:19 UTC ausgefallen (akut)
| Messwert | Stand |
|---|---|
| `up` -Mittel 24 h für `prometheus-node-exporter.monitoring.svc.cluster.local:9100` | 98,3 % |
| Zustandswechsel in 24 h | **1** — einmal runter, nicht zurück |
| Host-Uptime | 77,6 Tage → **kein Reboot** |
Ein Pod, der 12× pro Stunde stirbt, kann kein Target sein, das zu 98 % up ist. Geantwortet
hat also nie der Pod, sondern der eigenständige Exporter über die Host-IP. Der Pod hat
`hostNetwork` , sein Pod-IP ist die öffentliche `49.13.132.245` , dorthin zeigt der
Service-Endpoint — und dort kommt seit 01:19 nichts mehr.
Von CFGMON aus gemessen:
| Pfad | Ergebnis |
|---|---|
| `10.0.0.2:9100` (privat) | offen, 2706 Metriken |
| `49.13.132.245:9100` (öffentlich) | **keine Antwort** |
| `49.13.132.245:80` / `:443` | offen — Host lebt |
Ohne Reboot heißt das: in der Nacht wurde die Erreichbarkeit auf 9100 eingeengt. Zwei
Möglichkeiten, von hier aus nicht unterscheidbar:
1. Der Exporter bindet jetzt `10.0.0.2:9100` statt `0.0.0.0:9100` .
2. Eine `ufw` -Regel wurde geändert. Die Allow-Liste oben in dieser Datei führt 9100
ohnehin nicht auf — die private Zustellung muss also über eine Interface- oder
Subnetz-Regel laufen, an der sich etwas geändert haben kann.
Zeitlich fällt das exakt in das Fenster der Synapse-Port-Korrektur derselben Nacht. Wer
dort die Exposition aufgeräumt hat, hat den Cluster-Scrape-Pfad mitgenommen. Prüfen mit
`ss -lntp | grep :9100` und `ufw status numbered` .
### Fix — es ist ein node-exporter zu viel
**Weg B (empfohlen):** Den DaemonSet-Exporter abschalten (`nodeExporter.enabled: false` in
den kube-prometheus-stack-Values) und das Cluster-Alloy statt auf den Service-Namen direkt
auf `10.0.0.2:9100` zeigen lassen. Beendet den Crashloop und erhält die enge Bindung ans
private Netz, die in der Nacht vom 2026-08-01 gesetzt wurde.
**Weg A:** Den eigenständigen Exporter stilllegen und dem DaemonSet den Port überlassen.
Ebenfalls sauber, aber er bindet dann wieder `0.0.0.0` — also auch die öffentliche IP,
abgesichert nur noch durch `ufw` und die Cloud-Firewall. Das nähme die Einschränkung
zurück, die gerade erst gesetzt wurde.
### Nebenbefund — Job-Label kollidiert zwischen zwei Hosts
Das Label `prometheus.scrape.node_exporter` existiert zweimal, weil CFGMONs Alloy und das
Cluster-Alloy ihre Scrape-Komponente gleich benennen:
```
up=1 instance=node-exporter:9100 -> CFGMON (Kernel 6.8.0-136-generic)
up=0 instance=prometheus-node-exporter.monitoring.svc...:9100 -> MATRIX
```
Die Serien kollidieren nicht, `instance` trennt sie. Aber jede Abfrage, die nur nach `job`
filtert, mischt zwei Maschinen — und in Alarmtexten steht dann ein Job-Name, der nicht sagt,
welcher Host gemeint ist. Ein External Label auf der Remote-Write-Seite dieses Clusters
(`cluster="matrix"` ) würde das sauber trennen.
---
2026-08-01 12:00:00 +00:00
</details>
2026-07-30 12:00:00 +00:00
## Erledigt
### MATRIX-01 — Klären, ob der Server Mail als `@matrix.axion1337.de` verschickt · erledigt 2026-07-30
Für `matrix.axion1337.de` existiert der komplette IONOS-Mail-Satz: `MX mx00/mx01` ,
`TXT "v=spf1 include:_spf-eu.ionos.com ~all"` , `CNAME s1-ionos._domainkey` und
`CNAME autodiscover` . Bei `selendis` ist dasselbe Muster reine Altlast; hier war die Frage
offen, weil Matrix-Homeserver typischerweise Mail für Registrierung/Passwort-Reset
verschicken.
**Antwort, verifiziert per Config** (nicht nur vermutet) — direkt im IaC-Repo
`sorb/axion1337.chat-gitops` , dem tatsächlich hier deployten Stand geprüft:
- `apps/production/custom-configs/synapse-values.yaml` — kein `email:` /`smtp_host` /
`notif_from` -Block.
- `apps/production/custom-configs/mas-secret.yaml` (SOPS-entschlüsselt geprüft) — kein
`email` /`smtp` /`mailer` -Eintrag.
- `apps/production/element-server-suite.yaml` (HelmRelease values) — dito, nichts.
Weder Synapse noch MAS versenden aktuell irgendeine Mail. Registrierung/Passwort-Reset
laufen ausschließlich über Authentik (OIDC, `auth.axion1337.chat` ) und Einladungslinks.
Der komplette IONOS-Mail-Satz auf `matrix.axion1337.de` ist damit **funktional unnötig** —
dieselbe Härtung wie bei `selendis` anwenden (Null-MX, `v=spf1 -all` , `_dmarc p=reject` ),
`autodiscover.matrix` kann ebenfalls weg. Damit ist auch
2026-08-11 12:00:00 +00:00
[ZONE-02 ](../architecture/zone-axion1337.md ) an dieser Stelle entblockt.
2026-07-30 12:00:00 +00:00
**Separat davon** (andere Domain-Ebene, kein Widerspruch): auf diesem Host läuft seit
2026-07-30 ein eigener Mailversand für Host-Wartungsbenachrichtigungen
(`wartung@axion1337.de` , **Apex** -Postfach, nicht die `matrix.` -Subdomain) — siehe
MATRIX-04 unten. Nutzt die ohnehin am Apex laufende echte IONOS-Mail-Infrastruktur,
betrifft die `matrix.` -Subdomain-Records oben also nicht.
### MATRIX-02 — Pusht per Remote-Write auf einen offenen Prometheus · erledigt 2026-07-30
**Korrektur einer falschen Annahme im ursprünglichen Eintrag** : der Text ging von zwei
getrennten Absendern aus - "CFGMON (`10.0.0.3` ) und der k3s-Host (`10.0.0.2` )" - als wären
das zwei verschiedene Maschinen. Es ist **dieselbe Maschine** : dieser Host (`matrix` ) hat
selbst die private IP `10.0.0.2` (verifiziert per `ip -4 addr show` auf dem Host).
Verifiziert in `apps/monitoring/alloy-config.yaml` (diesem Cluster): Der Remote-Write-Push
geht bereits an `http://10.0.0.3:9090/api/v1/write` und Loki an `http://10.0.0.3:3100/...` -
**private IP, nicht die öffentliche** `188.245.193.243:9090` . Von dieser Seite aus ist hier
nichts mehr zu tun. Ob Prometheus/Loki auf CFGMON zusätzlich öffentlich erreichbar sind
(unabhängig davon, ob dieser Host den privaten Weg nutzt), ist
[CFGMON-03 ](cfgmon.md#cfgmon-03--prometheus-remote-write-und-loki-sind-öffentlich-ohne-auth )
- ein reines CFGMON-Thema, nicht mehr blockiert durch etwas auf diesem Host.
### MATRIX-04 — Host-Level Pre-Update-Benachrichtigung · erledigt 2026-07-30
Neuer, eigenständiger Mechanismus auf diesem Host, außerhalb von Flux/GitOps (Details:
`docs/deployment-guides/07-host-maintenance-notifications.md` im gitops-Repo,
2026-08-11 12:00:00 +00:00
`gitops#24` (Gitea-Zählung, Tracker stillgelegt)):
2026-07-30 12:00:00 +00:00
`unattended-upgrades` war bereits aktiv, neu ergänzt ist ein systemd-Timer
(`maintenance-notify.timer` , fest 05:00 Uhr, vor dem 06:00-07:00-Update-Fenster), der bei
anstehenden Paket-Updates per Mail **und** Matrix (Thread-Reply im `wartung` -Raum)
benachrichtigt.
Mail-Versand läuft über `msmtp` , Absender `wartung@axion1337.de` (IONOS SMTP,
`smtp.ionos.de:587` , STARTTLS - **Port 465 war ausgehend blockiert** , vermutlich
Cloud-Provider-Firewall-Regel, 587 ging durch). Relevant für die Mail-Policy-Diskussion
oben: dieses Postfach nutzt die reale, bereits am Apex laufende IONOS-Mail-Infrastruktur,
keine neue Subdomain, kein neuer Handlungsbedarf für die Zone.