The anonymisation rewrite of 2026-08-07 gave every touched commit a new SHA, leaving the references in these documents pointing at objects that no longer exist. The mapping was reconstructed from the backup branches and each pair verified by tree and commit message before substituting. Prefix lookups were built for lengths 7 to 12 and any ambiguous prefix would have been skipped; none were ambiguous across all 251 pairs.
212 lines
11 KiB
Markdown
212 lines
11 KiB
Markdown
# matrix
|
||
|
||
Matrix-Homeserver (Element Server Suite / Synapse) + K3s-Single-Node-Cluster, GitOps-verwaltet.
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Hostname** | `MATRIX` |
|
||
| **IPv4** | `49.13.132.245` |
|
||
| **IPv6** | kein AAAA-Record |
|
||
| **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. |
|
||
| **Stand** | 2026-07-30 |
|
||
|
||
**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.
|
||
|
||
`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).
|
||
|
||
## Offene Punkte → git.lab-Issues
|
||
|
||
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.
|
||
|
||
- [MATRIX-03 — `www.matrix.axion1337.de` ist überflüssig](https://git.lab/axion1337.chat/management/-/issues/1)
|
||
|
||
## MATRIX-05 — node-exporter-DaemonSet in CrashLoopBackOff, Cluster-Scrape seit 2026-08-01 tot
|
||
|
||
**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).
|
||
|
||
**Fix (gitops `228807f`, Weg A aus gitops#45):** HelmRelease + Alloy-Scrape entfernt,
|
||
Flux hat gepruned — DaemonSet/Service/Pod sind weg, Host-Metriken kommen unverändert
|
||
vom systemd-Exporter. Volle Diagnose:
|
||
[gitops#45](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/issues/45).
|
||
|
||
<details><summary>Ursprünglicher Befund (CFGMON-Session, vor der Host-Prüfung)</summary>
|
||
|
||
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.
|
||
|
||
---
|
||
|
||
</details>
|
||
|
||
## 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
|
||
[ZONE-02](../shared/zone-axion1337.md) an dieser Stelle entblockt.
|
||
|
||
**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,
|
||
[Issue #24](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/issues/24)):
|
||
`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.
|