diff --git a/STATUS.md b/STATUS.md index 0414c1e..6b07056 100644 --- a/STATUS.md +++ b/STATUS.md @@ -2,9 +2,9 @@ -## Issues (49 open, 54 closed) +## Issues (50 open, 54 closed) -Verteilung: M2 16 · M3 4 · M4 11 · M5 17 · M6 1 +Verteilung: M2 16 · M3 4 · M4 11 · M5 18 · M6 1 Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md). @@ -54,12 +54,13 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md). | [0100](docs/issues/0100-threadnet-web-13-asset-pfade-tragen-weiterhin-element-themes-e.md) | low | open | Asset-Pfade tragen weiterhin "element" (themes/element/…) | | [0101](docs/issues/0101-threadnet-call-4-kaputtes-paket-0-19-2-threadnet-6-in-der-regi.md) | low | open | Kaputtes Paket 0.19.2-threadnet.6 in der Registry — Herkunft ungeklärt | -### M5 (17) +### M5 (18) | Issue | Priorität | Status | Title | |---|---|---|---| | [0065](docs/issues/0065-gitops-25-k3s-api-security-hardening.md) | high | open | K3s API security hardening | | [0109](docs/issues/0109-der-weg-vom-commit-ins-cluster-meldet-seinen-stillstand-nicht.md) | high | open | Der Weg vom Commit ins Cluster meldet seinen Stillstand nicht | +| [0110](docs/issues/0110-haertung-lebt-auf-dem-host-das-repo-weiss-nichts-davon.md) | high | open | Härtung lebt auf dem Host, das Repo weiß nichts davon | | [0058](docs/issues/0058-gitops-14-web-application-firewall-waf.md) | medium | open | Web Application Firewall (WAF) | | [0059](docs/issues/0059-gitops-16-pod-security-admission-restricted.md) | medium | open | Pod Security Admission (Restricted) | | [0062](docs/issues/0062-gitops-21-renovate-dependabot-for-chart-and-image-updat.md) | medium | open | Renovate/Dependabot for chart and image updates | diff --git a/docs/issues/0110-haertung-lebt-auf-dem-host-das-repo-weiss-nichts-davon.md b/docs/issues/0110-haertung-lebt-auf-dem-host-das-repo-weiss-nichts-davon.md new file mode 100644 index 0000000..7cc5643 --- /dev/null +++ b/docs/issues/0110-haertung-lebt-auf-dem-host-das-repo-weiss-nichts-davon.md @@ -0,0 +1,116 @@ +--- +type: issue +id: "0110" +status: open +created: 2026-08-22 +milestone: M5 +priority: high +area: security +host: cfgmon +related: + - "docs/issues/0108-erlaubnisliste-veraltet-still-wenn-das-chart-die-verdrahtung-ver.md" + - "docs/issues/0109-der-weg-vom-commit-ins-cluster-meldet-seinen-stillstand-nicht.md" + - "docs/aar/2026-08-21-spiegel-ausfall.md" +--- + +# Härtung lebt auf dem Host, das Repo weiß nichts davon + +Der Betriebs-Stack auf CFGMON läuft aus einer Arbeitskopie unter +`/opt/threadnet-operating`. Was dort steht, muss nicht sein, was im Repo steht — +und **nichts vergleicht die beiden**. Eine Änderung von Hand am Host ist damit +unsichtbar, bis jemand zufällig darüber stolpert. + +## Der Beinahe-Unfall vom 2026-08-21 + +Prometheus und Loki nehmen Schreibzugriffe **ohne Authentisierung** an. Im Repo +standen ihre Ports auf `0.0.0.0`: + +```yaml +ports: + - "9090:9090" # Prometheus, remote-write-receiver + - "3100:3100" # Loki, Log-Push + - "9100:9100" # node-exporter +``` + +Bei den Firewall-Arbeiten desselben Tages wurden sie **auf dem Host** an +Adressen gebunden — privater vSwitch für die pushenden Absender, localhost für +den Host selbst. Richtig, wirksam, und **nirgends im Repo**. Der Kommentar +daneben behauptete weiter, die Ports seien öffentlich und nur durch die +Hetzner-Firewall gedeckt. + +⚠️ **Ein `git pull` hätte alle drei wieder geöffnet.** Verhindert hat es allein, +dass git den Pull wegen der lokalen Änderung abgebrochen hat: + +``` +error: Your local changes to the following files would be overwritten by merge: + monitoring/docker-compose.yml +``` + +Der Zufall, der es gerettet hat, ist keine Kontrolle. Wäre die Datei am Host +sauber gewesen — weil jemand die Änderung „aufgeräumt" oder neu ausgecheckt +hätte —, wären zwei nicht authentisierte Schreib-Endpunkte still wieder +öffentlich geworden, und die Meldung darüber wäre: keine. + +Die Bindungen sind am 2026-08-22 ins Repo nachgezogen (`1ce4b55` in +`threadnet-operating`), samt Berichtigung der Kommentare und des Abschnitts +„Offene Punkte / Sicherheit". **Der Einzelfall ist erledigt; der Mechanismus +nicht.** + +## Gemessen, nicht behauptet + +Von einer Quelle aus, die die Firewall durchlässt (Matrix-Host): + +| Ziel | Ergebnis | +|---|---| +| `188.245.193.243:443` (öffentlich) | **offen** — die Quelle ist nicht pauschal gesperrt | +| `188.245.193.243:9090` | dicht | +| `188.245.193.243:3100` | dicht | +| `10.0.0.3:9090` (vSwitch) | **offen** | + +⚠️ Vom Arbeitsplatz aus war **auch 443 dicht** — von dort lässt sich die Frage +gar nicht beantworten, weil die Firewall die Quelle schon abweist. Eine Messung +„von außen" ist nur dann eine Aussage über die Bindung, wenn dieselbe Quelle +etwas anderes am selben Host erreicht. + +## Was zu tun ist + +Der Befund ist derselbe wie in +[#0108](0108-erlaubnisliste-veraltet-still-wenn-das-chart-die-verdrahtung-ver.md) +und [#0109](0109-der-weg-vom-commit-ins-cluster-meldet-seinen-stillstand-nicht.md): +Ein Zustand weicht ab, und niemand erfährt es. Hier ist die Abweichung +besonders billig zu erkennen, weil beide Seiten dieselbe Datei sind. + +1. **Ein Abgleich zwischen Arbeitskopie und Repo**, der sich meldet, wenn sie + auseinanderlaufen — lokale Änderungen ebenso wie ein Stand, der Commits + hinterherhinkt. Am 2026-08-22 waren es **beide gleichzeitig**: `59c75c8` + statt `422b651` **und** eine geänderte Datei. +2. **Die Firewall-Regeln selbst gehören unter Versionskontrolle.** ufw und + iptables auf CFGMON stehen in **keinem** Repo. Solange das so ist, ist jede + Aussage über die Abschottung eine Erinnerung, keine Quelle. + +⚠️ **Punkt 2 ist der größere und gehört zuerst zugeschnitten.** Ob das +Ansible-Rollen werden, eine exportierte Regelliste mit Vergleich oder etwas +Drittes, entscheidet das Design-Gate — nicht dieses Issue. + +## Abnahmekriterien + +1. Eine Arbeitskopie, die vom Repo abweicht, führt binnen **24 h** zu einer + Meldung — mit der Angabe, **wie** sie abweicht (Rückstand, lokale Änderung + oder beides). +2. Die Prüfung wird **rot vorgeführt**: eine Datei am Host ändern, Meldung + erscheint, zurücknehmen, Meldung geht weg. +3. ⚠️ Ein Abgleich, der den Host **nicht erreichen** konnte, meldet einen + **Fehler** — nicht „keine Abweichung". Sonst sieht ein blinder Prüfer aus + wie ein sauberer Stand + ([meldet-erfolg-ist-aber-blind](../wiki/stolpersteine/meldet-erfolg-ist-aber-blind.md)). +4. Die Bindungen von `9090`, `3100`, `9100` sind aus einer **zugelassenen + Quelle** geprüft, nicht aus einem Netz, das die Firewall ohnehin abweist. + +## Nicht Teil davon + +- **Die Ports selbst** — erledigt in `1ce4b55`, hier nur noch als Beleg. +- **Der k3s-Cluster.** Dort ist Flux der Abgleich; das Problem hat genau die + Hosts, die *keinen* haben. +- **Zugangsdaten und Schlüssel.** Was verschlüsselt ins Repo gehört, ist eine + eigene Frage (#0015-Linie), nicht diese. +- Das Homelab und `game-operating`.