Framework-Umbau: Backlogs wird management-Repo (ADR-0005, Kanban + Scrum-Elemente)

- decisions/: ADR-Verzeichnis mit Template + 0001-0005 (git.lab-Kanonik,
  Lab-Cutover, CVE-Meldeweg, Site-to-Site-VPN-Design, Framework-Wahl)
- vision/: je eine Vision fuer Community/Tool/Plattform (Entwuerfe)
- roadmap.md: Linien, Meilenstein-Kandidaten, Kadenz
- hosts/+shared/: offene Punkte -> Issues #1-#12 im management-Projekt
  (IDs bleiben in den Titeln), Dateien halten Bestand + Historie
- README: Framework, Board/status-Labels (WIP-Limit 2), Topologie

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PKhFj1S3UdD6xL2fbWPeYj
This commit is contained in:
Thore Cimbal
2026-08-01 12:00:00 +00:00
co-authored by Claude Fable 5
parent 0f3f155bc5
commit fdf30d42e1
18 changed files with 429 additions and 523 deletions
+8 -175
View File
@@ -32,183 +32,16 @@ Prometheus-Jobs: `operating_prometheus`, `operating_node-exporter`,
(`10.0.0.2:9100`), `pterodactyl_host_node` und `gameserver_cadvisor`
(beide `157.90.155.206`, siehe [game](game.md)).
---
## Offene Punkte → git.lab-Issues
## CFGMON-01 — Zertifikatserneuerung braucht offene Ports (IPv4 **und** IPv6)
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.
**Status:** offen — zeitkritisch ab **2026-09-28**
Das Cert für `selendis.axion1337.de` wurde am 2026-07-30 ausgestellt und läuft am
**2026-10-28** ab. Traefik erneuert ca. 30 Tage vorher, also ab Ende September.
Gitea (`rohana.axion1337.de`) hängt am selben Resolver und ist damit genauso
betroffen — inklusive der Erreichbarkeit dieses Repos per HTTPS.
Traefik nutzt TLS-ALPN-01
(`--certificatesresolvers.letsencrypt.acme.tlschallenge=true`). Die Challenge läuft
ausschließlich über **Port 443, erreichbar aus dem offenen Internet**. Bei
gesperrtem Port scheitert sie mit:
```
urn:ietf:params:acme:error:connection :: Timeout during connect (likely firewall problem)
```
Traefik liefert dann sein Default-Self-Signed-Cert aus. Das fällt niemandem auf, bis
jemand die Seite aufruft — genau so ist es am 2026-07-30 passiert.
Eine IP-Allowlist ist **keine** Option: Let's Encrypt veröffentlicht seine
Validierungs-IPs nicht und prüft seit Einführung der Multi-Perspective Validation
aus mehreren Regionen gleichzeitig.
**IPv6 war der vermutete Fallstrick — geprüft und in Ordnung.** `rohana`, `selendis`
(und noch `www.*`, siehe [ZONE-01](../shared/zone-axion1337.md)) haben AAAA-Records
auf `2a01:4f8:c17:93eb::1`. Damit validiert LE **bevorzugt über IPv6**. Die
Hetzner-Cloud-Firewall kennt kein familienübergreifendes „any": das Feld *Source IPs*
ist eine Liste, `0.0.0.0/0` deckt IPv6 **nicht** mit ab, `::/0` muss separat drinstehen.
Stand 2026-07-30 enthält die Inbound-Regel für TCP 443 **beide** Einträge — vom User
in der Hetzner-Console nachgesehen. Damit ist der IPv6-Pfad frei.
Diese Angabe stammt **nicht** aus einer Messung von diesem Host aus, sondern aus der
Console. Vom Host ist es nicht verifizierbar: die Cloud-Firewall liegt außerhalb des
Systems, `iptables` und `ufw` sagen nichts darüber (und Root gibt es hier nicht), eine
Verbindung auf die eigene öffentliche Adresse läuft lokal, es gibt keinen zweiten Host
für eine Rückverbindung, und Traefik läuft ohne Access-Log — es existieren also auch
keine historischen Client-IPs. Für eine Prüfung von hier aus wäre ein
Hetzner-API-Token mit Read-Berechtigung nötig.
Auch die erfolgreiche Ausstellung vom 2026-07-30 um 12:00 UTC belegt IPv6 **nicht**:
zu dem Zeitpunkt existierte für `selendis` noch kein AAAA-Record, LE hat also über
IPv4 validiert. Die Erneuerung Ende September ist der erste Lauf, der IPv6 überhaupt
versucht.
**Damit bleibt als Risiko nur, ob die Ports offen bleiben.** Sie wurden am
2026-07-30 für die Ausstellung geöffnet; der Normalzustand dieser Umgebung ist, 80
und 443 aus Sicherheitsvorsicht auf die eigene IP zu beschränken. Werden sie wieder
zugezogen, scheitert die Erneuerung Ende September genau wie heute Mittag — und zwar
still.
**Nächster Schritt:** Entscheidung zwischen
- **A — Ports offen lassen** bzw. zur Erneuerung wieder öffnen. Nichts umzubauen,
aber alle ~60 Tage daran zu denken, und ein Fehlschlag fällt erst auf, wenn jemand
die Seite aufruft. Wenn A, dann mit einem Kalendereintrag auf **Mitte September**,
nicht auf das Ablaufdatum.
- **B — auf DNS-01 umstellen** (empfohlen). Validierung über einen TXT-Record,
**kein offener Port nötig**, läuft bei dichter Firewall durch. Braucht ein
API-Token für die Zone bei IONOS, als Secret für Traefik hinterlegt. Ermöglicht
zusätzlich Wildcard-Certs (`*.axion1337.de`), also künftige Subdomains ohne
Portöffnung. Die frühere Voraussetzung — ein anfassbarer, versionierter
Traefik-Stack — ist seit dem 2026-07-30 erfüllt (CFGMON-02, siehe „Erledigt").
---
## CFGMON-03 — Prometheus-Remote-Write und Loki sind öffentlich ohne Auth
**Status:** Weg A beschlossen (sorb 2026-08-01) — **Betrachtung nachgelagert**:
Beim Baseline-Check vom Mac aus waren 9090/3100 bereits zu (Timeout), OHNE dass der
Console-Klick gemacht war — die reale Hetzner-Firewall-Lage weicht offenbar vom
Backlog-Bild ab. Vor dem Abhaken einmal gemeinsam in die Console schauen: welche
Regeln existieren wirklich, und läuft der GAME-Push (nach GAME-01) noch durch?
**Vorbereitung/Empfehlung:** Absender-Inventur ergab: Der k3s/Matrix-Host pusht
längst übers private Netz (10.0.0.3, verifiziert) — öffentlich brauchen 9090/3100
nur noch Absender **außerhalb** des vSwitch, praktisch also der GAME-Host
(157.90.155.206, siehe GAME-01).
- **Weg A (empfohlen, 5 Minuten):** Hetzner-Cloud-Firewall auf CFGMON — eingehend
9090/tcp + 3100/tcp nur von `157.90.155.206` (+ ggf. weitere bekannte Absender)
erlauben; privater vSwitch-Verkehr ist davon unberührt. Sofort wirksam, kein
Config-Umbau.
- **Weg B (sauberer, später):** GAME-Host in den vSwitch aufnehmen (deckt sich mit
gitops#41 „privates Netz statt Internet" und der GAME-01-Firewall-Arbeit) —
danach beide `ports:`-Blöcke aus der Compose entfernen, nichts mehr öffentlich.
- **Weg C (verworfen):** BasicAuth via Traefik — 9090/3100 sind direkte
Port-Mappings, kein Traefik-Routing; der Umbau (Router+Middleware+htpasswd auf
CFGMON, `basic_auth`-Block im GAME-Alloy) wäre deutlich mehr Bewegung als A/B
für denselben Effekt.
Prometheus läuft mit `--web.enable-remote-write-receiver` und Port `9090` ist
veröffentlicht, weil der k3s-Cluster und der Matrix-Server dorthin pushen. Loki ist
auf `3100` ebenfalls veröffentlicht.
Ein offener Remote-Write-Receiver ohne Auth erlaubt Fremden, **beliebige Metriken
einzuspeisen** — damit lassen sich Dashboards und Alerts unbrauchbar machen — und
über die Query-API alle Daten auszulesen. Bei Loki auf `3100` gilt dasselbe für
Logs, die typischerweise mehr Interna enthalten als Metriken.
In `monitoring/docker-compose.yml` steht dazu bereits ein Warnhinweis als Kommentar,
umgesetzt ist er nicht.
**Nächster Schritt:** Beide Ports per Hetzner-Cloud-Firewall auf die Absender
einschränken. Sauberer wäre, sie gar nicht öffentlich zu binden: k3s liegt mit
`10.0.0.2` im selben privaten Netz wie CFGMON (`10.0.0.3`), der Push könnte also
über das private Netz laufen.
**Update 2026-07-30**: der k3s/Matrix-Host (`49.13.132.245`, privat `10.0.0.2` — ist
derselbe Host, siehe [MATRIX-02](matrix.md#matrix-02--pusht-per-remote-write-auf-einen-offenen-prometheus--erledigt-2026-07-30))
nutzt für seinen eigenen Remote-Write/Loki-Push bereits die private IP
(`http://10.0.0.3:9090`/`:3100`, verifiziert in `apps/monitoring/alloy-config.yaml`), nicht
`188.245.193.243`. Der öffentlich erreichbare, unauthentifizierte Port bleibt trotzdem ein
CFGMON-seitiges Risiko (jeder im Internet könnte ihn ansprechen, nicht nur der k3s-Host) -
dieser Teil des Punkts ist also weiterhin offen, nur nicht mehr durch fehlende
Netz-Erreichbarkeit des Matrix-Hosts blockiert.
---
## CFGMON-04 — Grafana-Admin-Credentials aus `.env` gelten nicht für die HTTP-API
**Status:** offen, geringe Priorität
`GF_SECURITY_ADMIN_USER` und `GF_SECURITY_ADMIN_PASSWORD` greifen nur beim
allerersten Start mit leerem Volume. Der Live-Admin wurde offenbar später in der UI
geändert, die Werte aus der `.env` sind damit funktionslos. Verifikation von
Datasources und Dashboards läuft deshalb über `grafana.db` statt über die API.
Kein Defekt, aber eine Falle: die `.env` sieht aus, als wäre sie die Quelle der
Wahrheit, ist es aber nicht.
**Nächster Schritt:** entweder das echte Admin-Passwort in die `.env` nachziehen und
dokumentieren, dass es nur den Ersteinrichtungsfall abdeckt, oder einen
Service-Account mit API-Token für Verifikationszwecke anlegen. Letzteres ist
sauberer, weil dafür kein Admin-Passwort nötig ist.
---
## CFGMON-09 — Gitea-Backups off-host in die Storage Box (eigenes Borg-Repo)
**Status:** offen — bewusst zurückgestellt am 2026-07-30
**Achtung: Der nächtliche Backup-Cron ist seit dem 2026-07-30 deaktiviert**
(auskommentiert in der Crontab von `rantanplan`). Bis zur Umsetzung dieses Punkts
laufen **keine Gitea-Backups** — der letzte Stand ist
`/opt/backup/gitea-dump-2026-07-30.tar.gz`. Beim Erledigen (oder Verwerfen) dieses
Punkts den Cron wieder aktivieren.
Ausgangslage: Die Platte (38G) ist zu 73 % voll, der einzelne lokale Dump belegt
4,3 GB (beides `df`/`du` vom 2026-07-30). Das Backup-Script
(`/opt/thread-net-git/backup/gitea-backup.sh`) rotiert deshalb auf genau einen
Stand; Historie existiert nur, wenn jemand manuell per scp abzieht.
Off-host-Kopien fehlen komplett.
Plan: **Eigenes Borg-Repo auf der Hetzner Storage Box.** Die Storage Box spricht
Borg nativ über SSH (Port 23, laut Hetzner-Doku — nicht von hier verifiziert,
es existiert noch keine Storage Box dafür), z. B.
`ssh://uXXXXXX@uXXXXXX.your-storagebox.de:23/./backups/gitea`.
- **Dedup:** Die nächtlichen Dumps sind fast identisch — Borg überträgt nur
geänderte Blöcke. Dafür den Dump **unkomprimiert** an Borg geben (das `gzip` im
Script entfällt, Borg komprimiert selbst), sonst greift die Deduplizierung nicht.
- **Retention** über `borg prune` (z. B. 7 täglich, 4 wöchentlich, 6 monatlich)
statt nur eines Standes.
- Optional ein **Sub-Account** der Storage Box mit eigenem Verzeichnis, damit das
Gitea-Repo von anderen Backups getrennt bleibt.
Voraussetzungen, beide beim User:
1. Storage-Box-Username (`uXXXXXX`) bzw. Sub-Account (im Hetzner-Robot anlegen).
2. Der Host hat **keinen SSH-Key** (`~/.ssh/` enthält nur `authorized_keys`,
geprüft 2026-07-30) — Key generieren und den Public Key in der Storage Box
hinterlegen (Robot-Webinterface oder einmalig per Passwort-Login).
- [CFGMON-01 — Zertifikatserneuerung braucht offene Ports (zeitkritisch ab 2026-09-28)](https://git.lab/axion1337.chat/management/-/issues/7)
- [CFGMON-03 — Prometheus-Remote-Write/Loki öffentlich ohne Auth (Weg A, nachgelagerte Prüfung)](https://git.lab/axion1337.chat/management/-/issues/8)
- [CFGMON-04 — Grafana-Admin-Credentials aus `.env` gelten nicht für die API](https://git.lab/axion1337.chat/management/-/issues/9)
- [CFGMON-09 — Gitea-Backups off-host (⚠️ Backup-Cron deaktiviert)](https://git.lab/axion1337.chat/management/-/issues/10)
## CFGMON-11 — Gitea-CI-Rückbau nach GitLab-Umzug
+6 -89
View File
@@ -14,95 +14,12 @@ Pterodactyl- / Gameserver-Host.
> aus. Auf dem Host selbst wurde nichts geprüft. Beim ersten direkten Zugriff
> sollten OS, Dienste und Compose-Projekte hier nachgetragen werden.
---
## Offene Punkte → git.lab-Issues
## GAME-01 — Host von CFGMON aus nicht erreichbar, 2 Prometheus-Targets down
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.
**Status:** offen — Ursache liegt auf diesem Host oder in dessen Firewall
- [GAME-01 — Host von CFGMON aus nicht erreichbar, 2 Targets down (⚠️ Silences bis 2026-08-04)](https://git.lab/axion1337.chat/management/-/issues/2)
- [GAME-02 — `www.game.axion1337.de` ist überflüssig](https://git.lab/axion1337.chat/management/-/issues/3)
Zwei Scrape-Targets sind down. Das bestand **schon vor** dem Monitoring-Rework vom
2026-07-30, ist also kein Regressionsschaden aus der Umstellung.
| Job | Target | Fehler |
|---|---|---|
| `gameserver_cadvisor` | `157.90.155.206:8080` | `context deadline exceeded` |
| `pterodactyl_host_node` | `157.90.155.206:9100` | `context deadline exceeded` |
Von CFGMON aus geprüft: der Host antwortet **nicht auf Ping** (100 % packet loss) und
auf keinem der beiden Ports. Das Problem ist also nicht die Prometheus-Konfiguration,
sondern die Erreichbarkeit. Mögliche Ursachen, von wahrscheinlich nach unwahrscheinlich:
1. Die Hetzner-Cloud-Firewall dieses Hosts lässt `188.245.193.243` nicht auf
8080/9100 — passend zum restriktiven Firewall-Setup der Umgebung.
2. cAdvisor und node-exporter laufen nicht (mehr) oder binden nur auf `127.0.0.1`.
3. Der Host ist abgeschaltet oder umgezogen und die IP ist veraltet. Dagegen spricht,
dass `game.axion1337.de` weiter auf sie zeigt.
### Nachtrag 2026-08-01 — Ursache eingegrenzt
Erneut von CFGMON aus geprüft. Die Befunde streichen die Liste oben zusammen:
| Prüfung | Ergebnis |
|---|---|
| Port 80 / 443 | **offen, antworten sofort** |
| Port 22 / 8080 / 9100 | keine Antwort, Timeout |
| ICMP | 100 % Verlust |
| `10.0.0.0/24`, Ports 9100+8080 | nur `10.0.0.2` (k3s) und `10.0.0.3` (CFGMON) — dieser Host ist **nicht** im vSwitch |
| `up == 1` in den letzten 45 Tagen | **nie** — beide Targets waren im gesamten Retention-Fenster nie erreichbar |
Damit ist **Ursache 3 ausgeschlossen**: der Host lebt und bedient 80/443. Und
**Ursache 1 ist die wahrscheinliche**: die Ports laufen ins *Timeout* statt
`connection refused` zu liefern. Ein nicht laufender oder auf `127.0.0.1` gebundener
Exporter würde die Verbindung aktiv ablehnen — stilles Verwerfen ist die Signatur
eines Paketfilters davor. Ursache 2 bleibt als Zusatzbedingung möglich: selbst bei
offener Firewall muss cAdvisor drüben seinen Port auch veröffentlichen (auf CFGMON
läuft er bewusst ohne `-p`, nur containerintern).
**Nächster Schritt:** in der Hetzner-Cloud-Firewall dieses Hosts inbound TCP 8080 und
9100 für `188.245.193.243/32` freigeben — oder besser den Weg unten gehen. Danach auf
dem Host prüfen, ob beide Exporter laufen und worauf sie binden.
**Empfehlung: nicht über die öffentliche IP.** CFGMON scrapt den k3s-Host bereits
über das private Netz (`10.0.0.2:9100`) und der ist up — das ist das Modell, das
hier funktioniert. Wenn dieser Host in denselben Hetzner-vSwitch aufgenommen wird
(CFGMON hat `10.0.0.3`), braucht es für das Monitoring **gar keine im Internet
offenen Ports**. Zwei Exporter öffentlich erreichbar zu machen wäre der schlechtere
Weg: node-exporter gibt detaillierte Host-Interna preis, cAdvisor die komplette
Container-Landschaft.
Danach in `threadnet-operating` die Targets in `monitoring/prometheus/prometheus.yml`
von der rohen IP auf die private Adresse bzw. den DNS-Namen umstellen — aktuell
stehen dort öffentliche IPs, obwohl mit `game.axion1337.de` ein Name existiert.
**Solange offen — Alerting stummgeschaltet.** Seit dem Alerting-Rollout (gitops#32,
2026-08-01) erzeugen beide Targets echte `TargetDown`-Alarme im Matrix-Alerts-Raum,
mit `repeat_interval: 4h` also alle vier Stunden erneut. Dafür sind auf CFGMON zwei
Alertmanager-Silences gesetzt:
| Silence-ID | Matcher |
|---|---|
| `abedb8a2-6969-41d0-aa94-20c1f575fe61` | `alertname="TargetDown" instance="pterodactyl"` |
| `0f64aa3c-67a0-45c5-a9d9-a30ce64e8113` | `alertname="TargetDown" instance="157.90.155.206:8080"` |
**Sie laufen am 2026-08-04 01:30 UTC ab.** Ist der Host bis dahin nicht gefixt, meldet
sich das Alerting von selbst zurück — bewusst so gewählt, damit der Punkt nicht still
liegen bleibt. Verlängern oder aufheben mit `docker compose exec alertmanager amtool
silence expire <id> --alertmanager.url=http://localhost:9093` aus
`/opt/threadnet-operating/monitoring`.
---
## GAME-02 — `www.game.axion1337.de` ist überflüssig
**Status:** offen, geringe Priorität
Es existiert ein A-Record `www.game.axion1337.de``157.90.155.206`, angelegt nach
IONOS-Default-Muster. Bei einer Subdomain ist ein `www.`-Präfix überflüssig, siehe
die Begründung in [ZONE-01](../shared/zone-axion1337.md).
**Nicht verifiziert**, ob auf diesem Host etwas auf den Namen hört — von CFGMON aus
ist er nicht erreichbar. Bei `rohana` und `selendis` liefert das äquivalente
Konstrukt einen Zertifikatsfehler.
**Nächster Schritt:** prüfen, ob der Name irgendwo verlinkt oder konfiguriert ist,
sonst A-Record löschen.
+5 -11
View File
@@ -25,19 +25,13 @@ Host **ist** das Deployment-Ziel dieses Repos, nicht nur verwandt. Client-Forks:
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
## MATRIX-03 — `www.matrix.axion1337.de` ist überflüssig
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.
**Status:** offen, geringe Priorität
A-Record `www.matrix.axion1337.de``49.13.132.245`, nach IONOS-Default-Muster
angelegt. Begründung siehe [ZONE-01](../shared/zone-axion1337.md). **Nicht
verifiziert**, ob auf dem Host etwas auf den Namen hört.
**Nächster Schritt:** prüfen und sonst löschen.
---
- [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
+2 -1
View File
@@ -78,7 +78,8 @@ erst neues Image bauen, dann Referenz umstellen).
## OVERMIND-02 — Host-Ausfall 2026-07-31 ~19:15 lokal (NIC-Hang, Fix aktiv)
**Status:** Fix aktiv, Beobachtung
**Status:** Fix aktiv — die Beobachtung läuft als [Issue #4](https://git.lab/axion1337.chat/management/-/issues/4)
(Framework-Umbau 2026-08-01); dieser Abschnitt ist Bestand/Historie.
**Ursache (Journal des Vor-Boots, via Claude-Session auf Overmind):** `e1000e`
`Detected Hardware Unit Hang` auf `eno1` in Endlosschleife — die Intel-NIC hing