feat: slice 3 - wiki, sources and AARs in their neckbeard homes
Gate 4, slice 3: verfahren/, hosts/, vision/ and shared/ moved via git mv - six AARs to docs/aar/ (four harvested by the 2026-08-09 retro, two open), procedures and host knowledge to docs/wiki/ (admin, deployment, architecture, new area vision), the retro protocol and the commit mapping table to docs/sources/ (protokolle/, migration/). New: the wiki index linking every page, and the mirror-topology page carrying the why-two-places reasoning verbatim from the old CLAUDE.md (F-013 preserved). All moved-path references retargeted; the link checker drove the sweep to zero. pruefe_prosa.py added (pattern C+D): SHA citations resolve via repo, mapping table, optional component clones or a curated exemption list (documented dead Gitea-force-push commits, a vendor-repo tag, an Authentik uid that is hex but no git SHA, the external neckbeard reference); wiki task prose without an issue reference errors, with a visible pragma for deliberate checklists; the dead-tracker denylist now covers every mirrored repo's retired Gitea tracker (F-005) - two links re-verified against live GitLab titles and retargeted, five defused into honest historical citations. Verified: validate 0/0, gen_status --check current, drift 0. Demo on the pre-migration state fires 6 findings (3 orphaned SHAs, 3 task blocks); on the current tree exactly the 3 F-004 task blocks remain - they turn green in slice 4 when the issues exist, which is why pruefe_prosa joins CI only then. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
70e81e2ff1
commit
92b448fe30
@@ -0,0 +1,220 @@
|
||||
---
|
||||
type: wiki-page
|
||||
area: architecture
|
||||
related: []
|
||||
---
|
||||
|
||||
# Branding: Marke, Farben, Bildsprache
|
||||
|
||||
Übergreifend, weil dieselben Farben in mehreren Oberflächen eingestellt werden
|
||||
(Chat-Clients, Wikis, künftige Dienste) und sich das nicht pro Host oder Linie
|
||||
trennen lässt: **Bestand** (welche Farbe wo eingetragen ist) und **Historie**
|
||||
(was wann warum geändert wurde).
|
||||
|
||||
Hier im `management`-Repo, weil es als einziges der beteiligten Repos
|
||||
**gespiegelt** ist und jede Werkzeugentscheidung überlebt: Wird das
|
||||
BookStack-Experiment nach [ADR-0007](../../adr/0007-wiki-oberflaeche-docusaurus-vs-bookstack.md)
|
||||
abgeräumt oder ein Client ersetzt, bleiben Marke und Paletten bestehen.
|
||||
|
||||
## Bildmarke
|
||||
|
||||
`threadnet-mark.png` (Bildmarke) und `threadnet-logo-wortmarke.png` (mit
|
||||
Schriftzug), erstellt von sorb. Sie liegen im Wiki-Repo unter `static/img/` und
|
||||
sind die Quelle für alle abgeleiteten Formate — Favicon, App-Icons für macOS,
|
||||
Windows und Linux, Web-Icons.
|
||||
|
||||
⚠️ Beim Ableiten den **transparenten Rand wegschneiden** und mit `resize()`
|
||||
skalieren, nicht mit `thumbnail()` — Letzteres verkleinert nur und lässt das Motiv
|
||||
in großen Icons als Briefmarke zurück (real passiert, siehe
|
||||
[AAR 2026-08-02](../../aar/2026-08-02-wiki-und-desktop-clients.md)).
|
||||
|
||||
⚠️ **Und danach mittig setzen — das ist ein zweiter, eigener Schritt.** Beim ersten
|
||||
Anlauf wurde nur beschnitten und skaliert: Das Motiv füllte 81 % der Breite, saß
|
||||
aber mit 3 % Rand oben und 40 % unten an der Oberkante. In runden und quadratischen
|
||||
Icon-Slots fällt das sofort auf. Korrigiert am 2026-08-06 auf 21 % oben wie unten.
|
||||
|
||||
**Das Rezept, das jetzt gilt:** Bounding-Box des Motivs ermitteln, darauf
|
||||
beschneiden, auf ~81 % der Kantenlänge skalieren, auf einer quadratischen,
|
||||
transparenten Fläche **mittig einsetzen**. Alle Größen aus *derselben* Quelldatei
|
||||
ableiten — dann können sie nicht auseinanderlaufen.
|
||||
|
||||
### Wo überall Icons liegen
|
||||
|
||||
Elf Artefakte, alle aus einer Quelle (Stand 2026-08-06, `v0.4.0`):
|
||||
|
||||
| Ort | Was |
|
||||
|---|---|
|
||||
| `apps/web/res/vector-icons/` | 1024, 512, 180, 152, 144, 120, 24 px |
|
||||
| `apps/desktop/build/icon.png` | App-/Installer-Icon |
|
||||
| `apps/desktop/build/icon.ico` | Windows, 7 Größen von 16 bis 256 |
|
||||
| `apps/desktop/build/icon.icns` | macOS, via `iconutil` aus einem `.iconset` |
|
||||
| `apps/desktop/build/icon.icon/Assets/element.png` | Layer des macOS-Icon-Composers |
|
||||
|
||||
Prüfen lässt sich die Gleichheit über die Prüfsumme von `vector-icons/1024.png`
|
||||
gegen `build/icon.png` — weichen sie ab, ist eine Seite nachgezogen worden und die
|
||||
andere nicht.
|
||||
|
||||
## Paletten
|
||||
|
||||
### aXion1337 Dark — das Stammschema
|
||||
|
||||
Gruvbox Dark. Grundtöne `#282828` / `#1d2021`, Text `#ebdbb2`, Akzent `#bd93f9`,
|
||||
Sekundär `#fe8019`. Die acht Username-Farben sind der Gruvbox-Satz.
|
||||
**`aXion1337 Light` ist das exakte helle Gegenstück** (Gruvbox Light) — gleiche
|
||||
Rollenverteilung, gespiegelte Helligkeitsachse. Wer eines ändert, zieht das andere
|
||||
mit.
|
||||
|
||||
### Terrakotta-Beige — sorbs BookStack-Schema
|
||||
|
||||
Am 2026-08-02 in der BookStack-Oberfläche eingestellt und von dort extrahiert
|
||||
(die Werte stehen als CSS-Variablen im ausgelieferten HTML). Fünf der sieben sind
|
||||
der Coolors-Satz `#264653 · #2A9D8F · #E9C46A · #F4A261 · #E76F51`:
|
||||
|
||||
| Rolle in BookStack | Wert | Ton |
|
||||
|---|---|---|
|
||||
| Primäre Farbe | `#264653` | Charcoal |
|
||||
| Standard-Linkfarbe | `#5f757b` | gedämpftes Blaugrau |
|
||||
| Regalfarbe | `#e76e51` | Burnt Sienna |
|
||||
| Buchfarbe | `#e9c46a` | Saffron |
|
||||
| Kapitelfarbe | `#f3a261` | Sandy Brown |
|
||||
| Seitenfarbe | `#77bb41` | Grün |
|
||||
| Seitenentwurfsfarbe | `#e32400` | Rot |
|
||||
|
||||
Bemerkenswert: **dieses von Hand eingestellte Schema ist bis auf zwei Ziffern die
|
||||
offizielle Sunset-Boulevard-Palette** (siehe nächster Abschnitt) — `#e76e51` statt
|
||||
`#e76f51`, `#f3a261` statt `#f4a261`. Beide Wege sind unabhängig voneinander auf
|
||||
demselben Coolors-Satz gelandet. Die Irritation an der ersten Theme-Fassung war
|
||||
also berechtigt und ließ sich an der Originalquelle belegen.
|
||||
|
||||
### theme-factory — die zehn benannten Themes
|
||||
|
||||
Quelle ist Anthropics [theme-factory-Skill](https://github.com/anthropics/skills/tree/main/skills/theme-factory):
|
||||
je Theme vier Farben plus ein Schriftpaar. Sie sind seit 2026-08-02 **wörtlich
|
||||
übernommen** (gitops `b10b607`), nachdem eine erste Fassung die Namen frei
|
||||
interpretiert hatte.
|
||||
|
||||
| Theme | Hintergrund | hell/dunkel | Akzent · Sekundär · Highlight |
|
||||
|---|---|---|---|
|
||||
| Ocean Depths | `#f1faee` | hell | `#2d8b8b` · `#a8dadc` · `#457b9d` |
|
||||
| Sunset Boulevard | `#264653` | dunkel | `#e76f51` · `#f4a261` · `#e9c46a` |
|
||||
| Forest Canopy | `#faf9f6` | hell | `#2d4a2b` · `#7d8471` · `#a4ac86` |
|
||||
| Modern Minimalist | `#ffffff` | hell | `#36454f` · `#708090` · `#d3d3d3` |
|
||||
| Golden Hour | `#4a403a` | dunkel | `#f4a900` · `#c1666b` · `#d4b896` |
|
||||
| Arctic Frost | `#fafafa` | hell | `#4a6fa5` · `#d4e4f7` · `#c0c0c0` |
|
||||
| Desert Rose | `#5d2e46` | dunkel | `#d4a5a5` · `#b87d6d` · `#e8d5c4` |
|
||||
| Tech Innovation | `#ffffff` | hell | `#0066ff` · `#00ffff` · `#1e1e1e` |
|
||||
| Botanical Garden | `#f5f3ed` | hell | `#4a7c59` · `#f9a620` · `#b7472a` |
|
||||
| Midnight Galaxy | `#e6e6fa` | hell | `#2b1e3e` · `#4a4e8f` · `#a490c2` |
|
||||
|
||||
⚠️ **Ob ein Theme hell oder dunkel gemeint ist, steht nicht verlässlich in den
|
||||
Beschreibungen** — „Warm Sand · backgrounds" findet sich bei einem Theme, dessen
|
||||
Showcase-Seite dunkel ist. Maßgeblich ist `theme-showcase.pdf` im Skill: sieben der
|
||||
zehn sind hell, nur Sunset Boulevard, Golden Hour und Desert Rose dunkel.
|
||||
„Midnight" Galaxy ist trotz des Namens ein helles Theme mit dunkelviolettem Akzent.
|
||||
Wer die Werte prüfen will, rendert die PDF-Seiten und misst die Hintergrundfarbe,
|
||||
statt der Prosa zu glauben.
|
||||
|
||||
Die übrigen Rollen (Flächenabstufungen, Username-Farben) sind aus diesen vier
|
||||
Farben gemischt — so bleibt jedes Theme in sich stimmig, ohne dass Werte
|
||||
dazuerfunden werden.
|
||||
|
||||
## Namensgebung: ThreadNet oder aXion1337.Chat?
|
||||
|
||||
**Beides, auf verschiedenen Ebenen — und das ist Absicht, kein Versehen.**
|
||||
|
||||
| Ebene | Name | Wo gesetzt |
|
||||
|---|---|---|
|
||||
| Betriebssystem, Startmenü, Installer, PWA | **ThreadNet** | `productName` in `apps/desktop/axion1337/build.json`, `name` in `apps/web/res/manifest.json` |
|
||||
| in der Anwendung | **aXion1337.Chat** | `brand` in `element-values.yaml` (Prod) und `apps/desktop/axion1337/config.json` |
|
||||
| eingebettetes Call-Widget | **aXion1337.Chat** | `VITE_PRODUCT_NAME` in `.env.production` (threadnet-call) |
|
||||
| Anmeldeseite (Authentik) | **ThreadNet** | `branding_title` im Brand-Blueprint (gitops, `apps/authentik/authentik-blueprints.yaml`) |
|
||||
|
||||
Das Call-Widget folgt der Zeile darüber: Es läuft *in* der Anwendung, also heißt es
|
||||
dort auch so. Die Anmeldeseite dagegen kommt **vor** der Anwendung — dort meldet man
|
||||
sich am Werkzeug an, nicht in der Gemeinschaft. Deshalb ThreadNet.
|
||||
|
||||
Die Leitplanke dahinter steht in [`vision/threadnet.md`](../vision/threadnet.md):
|
||||
*ThreadNet ist das Tool, axion1337.chat die Community.* Das Programm heißt
|
||||
ThreadNet — auch wenn es jemand für eine andere Instanz nutzt; die Gemeinschaft
|
||||
darin heißt aXion1337.Chat.
|
||||
|
||||
⚠️ **Nicht „geradeziehen".** Wer nur eine der beiden Stellen sieht, hält es für
|
||||
eine Inkonsistenz. Ist es nicht.
|
||||
|
||||
**Attribution:** „ThreadNet — powered by Element" steht seit `v0.4.0` in
|
||||
*Einstellungen → Hilfe & Info*, direkt unter der Client-Version, verlinkt auf
|
||||
element.io. Element Web steht unter der AGPL; ein Fork unter eigenem Namen ist
|
||||
erlaubt, die Nennung ist die faire Form davon. Bewusst **nicht** im Kopiertext der
|
||||
Versionsangabe — der landet in Fehlerberichten, dort ist die Fork-Herkunft nur
|
||||
Rauschen.
|
||||
|
||||
## Wo was eingestellt ist
|
||||
|
||||
| Oberfläche | Ort | Anmerkung |
|
||||
|---|---|---|
|
||||
| Element/ThreadNet-Web | `apps/production/custom-configs/element-values.yaml` (gitops), `setting_defaults.custom_themes` | 17 Themes; Änderungen chirurgisch, **nie die YAML neu serialisieren** |
|
||||
| Web-Icons + PWA | `apps/web/res/vector-icons/`, `apps/web/res/manifest.json` (ThreadNet-Web) | `theme_color` = `#ed4f4c`, die Markenfarbe — nicht Elements `#76CFA6` |
|
||||
| Desktop-Icons | `apps/desktop/build/` (ThreadNet-Web) | `.png`, `.ico`, `.icns`, Layer-Asset — alle aus derselben Quelle |
|
||||
| ThreadNet Desktop | `apps/desktop/axion1337/config.json` (ThreadNet-Web) | eigene Kopie derselben Themes — beim Ändern beide mitziehen |
|
||||
| BookStack | *Settings → Customization*, getrennt für hell und dunkel | liegt in der Datenbank, **nicht im Repo** — schriftlich hier und in `theme/sorbs-palette.md` |
|
||||
| BookStack (Feinschliff) | `theme/*.css` im Wiki-BookStack-Repo | nur Flächen, Text, Ränder — die sieben Farben oben gehören in die Oberfläche |
|
||||
| Docusaurus-Wiki | `src/css/custom.css` (homelab/wiki) | bislang nur Akzentfarbe |
|
||||
| Titelbild Login | `apps/web/res/themes/element/img/backgrounds/alpenglow.jpg` (ThreadNet-Web), gesetzt in `SdkConfig.ts` | siehe unten — Bilddatei kommt nur über einen Build in den Container |
|
||||
| Anmeldeseite Authentik | Brand-Blueprint in `apps/authentik/authentik-blueprints.yaml` (gitops) | Favicon und Hintergrund werden **von axion1337.chat referenziert**, nicht hochgeladen. **Logo ist noch Authentiks eigenes** → gitops#55 |
|
||||
|
||||
### Titelbild
|
||||
|
||||
Seit 2026-08-06 zeigt die Login-Seite ein Alpenglühen über einer Bergkette statt
|
||||
Elements See: **John Towner** ([@heytowner](https://unsplash.com/@heytowner)),
|
||||
[Unsplash](https://unsplash.com/photos/JgOeRuGD_Y4), *Unsplash License*.
|
||||
|
||||
Die Lizenz erlaubt kommerzielle Nutzung und Bearbeitung ohne Genehmigung und
|
||||
**verlangt keine Namensnennung**. Genannt wird er trotzdem — in *Einstellungen →
|
||||
Hilfe & Info* unter „Danksagungen". Verboten wäre nur der Weiterverkauf
|
||||
unbearbeiteter Bilder und das Nachbauen eines konkurrierenden Bilddienstes; beides
|
||||
trifft uns nicht.
|
||||
|
||||
⚠️ **Die Danksagung ist bewusst nicht übersetzt.** Elements Schlüssel
|
||||
`credits|default_cover_photo` liegt in 32 Sprachdateien, 31 davon nennen deren
|
||||
Fotografen namentlich. Nur `en`/`de` anzupassen hätte in 29 Sprachen eine **falsche
|
||||
Attribution** stehen lassen — und diese 29 pflegen wir nicht, sie kommen aus Elements
|
||||
Übersetzungsdienst. Deshalb steht die Zeile als fester Text im TSX, wie schon die
|
||||
„powered by Element"-Attribution.
|
||||
|
||||
⚠️ **Authentik hängt an dieser Datei.** Der Flow-Hintergrund dort zeigt auf
|
||||
`https://axion1337.chat/themes/element/img/backgrounds/alpenglow.jpg`. Wer das Bild im
|
||||
Client umbenennt oder entfernt, macht die Anmeldeseite grau — und merkt es nicht,
|
||||
weil im Client alles stimmt.
|
||||
|
||||
### Warum in Authentik kein PNG-Logo funktioniert
|
||||
|
||||
Der erste Versuch setzte `branding_logo` auf `vector-icons/512.png`. Ergebnis: das
|
||||
Logo rendert in der Anmeldemaske in **Naturgröße**. Authentiks Default ist ein SVG,
|
||||
das sich seiner Box anpasst — ein PNG tut das nicht, und der Slot begrenzt die Höhe
|
||||
nicht.
|
||||
|
||||
Zurückgesetzt am 2026-08-06 auf Authentiks eigenes Logo. Ein Ersatz braucht eine
|
||||
**Wortmarke im Querformat, am besten als SVG**; alles Vorhandene ist quadratisch,
|
||||
auch `threadnet-logo-wortmarke.png` (Bildmarke *über* Schriftzug). Offen in
|
||||
gitops#55.
|
||||
|
||||
⚠️ **Nicht über Authentiks Oberfläche einstellen.** Solange `branding_logo` im
|
||||
Blueprint steht, gewinnt der Blueprint: eine Auswahl in der UI hält bis zur nächsten
|
||||
Reconciliation und ist dann wieder weg.
|
||||
|
||||
⚠️ **Das BookStack-Schema lebt nur in der Datenbank.** Bei einem Volume-Verlust
|
||||
ist es weg — deshalb steht es oben in dieser Tabelle. Wiederherstellen heißt:
|
||||
sieben Felder in der Oberfläche neu eintragen.
|
||||
|
||||
Es steht bewusst an **zwei** Stellen schriftlich, und die Rollen sind verschieden:
|
||||
`theme/sorbs-palette.md` im BookStack-Repo ist die betriebsnahe Kopie mit den
|
||||
DB-Schlüsseln, liegt aber in der Gruppe `homelab` — die hat **keine Mirrors** und
|
||||
ist von außerhalb des Labs nicht lesbar. Diese Datei hier ist die gespiegelte
|
||||
und damit maßgebliche Fassung. Wer die Farben ändert, zieht beide mit; im
|
||||
Zweifel gilt, was in der laufenden Instanz eingestellt ist.
|
||||
|
||||
## Offen
|
||||
|
||||
Ob die Terrakotta-Richtung das Stammschema ablösen oder eine Alternative neben
|
||||
Gruvbox bleiben soll, ist nicht entschieden — das gehört in die Rebranding-Runde
|
||||
(→ [`vision/threadnet.md`](../vision/threadnet.md), ThreadNet-Web#10).
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
type: wiki-page
|
||||
area: architecture
|
||||
related: []
|
||||
---
|
||||
|
||||
# Lab-Netzwerk (Heimnetz: Fritzbox + UDM Pro)
|
||||
|
||||
Themen rund um das Homelab-Netz selbst — Router-Kaskade, VLANs, VPN-Zugänge.
|
||||
Hosts im Lab: Overmind (git.lab, [hosts/overmind.md](../admin/overmind.md)),
|
||||
der Mac. Kaskade: **Fritzbox (WAN) → UDM Pro**, kein Doppel-NAT, statische
|
||||
Route in der Fritzbox für das Lab-VLAN.
|
||||
|
||||
> ✅ **Das VPN-Thema ist abgeschlossen und validiert** (sorb, 2026-08-02).
|
||||
> Beide Zugänge laufen und sind abgenommen, ADR-0004 steht auf *akzeptiert*
|
||||
> (Testreihe 1–7 in [#12](https://git.lab/axion1337.chat/management/-/issues/12)).
|
||||
> Es gibt dazu **keine offenen Issues mehr** — auch die Restpunkte #11
|
||||
> (MacBook-Profil) und #16 (LABNET-04, Feinschliff an den UniFi-Regeln) sind
|
||||
> geschlossen. Alles Folgende ist **Bestand und Historie**, keine offene Arbeit.
|
||||
|
||||
**Zwei WireGuard-Zugänge (Stand 2026-08-01, beide gelöst/abgenommen):**
|
||||
|
||||
| Zugang | Server | Port | Tunnelnetz | Zweck |
|
||||
|---|---|---|---|---|
|
||||
| Roadwarrior „Thore" | UDM | 51840 | 10.58.74.0/24 | Handy/MacBook ins Lab (LABNET-01) |
|
||||
| Site-to-Site „Matrix" | UDM | 51841 | 10.58.75.0/24 | Hetzner-Netz 10.0.0.0/24 ↔ Lab (LABNET-02, [ADR-0004](../../adr/0004-site-to-site-vpn-hetzner-lab.md)) |
|
||||
|
||||
### Verhältnis zu `homelab/docs`
|
||||
|
||||
Die Tabelle oben steht **absichtlich doppelt**. Maßgeblich für die
|
||||
Soll-Konfiguration ist
|
||||
[homelab/docs → MorninglightMountain](https://git.lab/homelab/docs/-/blob/main/netz/morninglightmountain.md)
|
||||
(dort auch Portfreigaben, Firewall-Zonen, Diagnose-Merksätze) — dieses Repo
|
||||
führt die **Historie**: was wann warum geändert wurde und mit welchem Issue.
|
||||
|
||||
Der Grund für die Doppelung ist der Mirror-Geltungsbereich aus der
|
||||
[CLAUDE.md](../../../AGENTS.md): Die Gruppe `homelab` hat bewusst **keine Mirrors** und
|
||||
ist von außerhalb des Labs nicht lesbar. Wer ohne Tunnel nachsehen muss, welcher
|
||||
Tunnel überhaupt auf welchem Port liegt, findet es nur hier. Deshalb hält dieses
|
||||
Dokument einen Kurzüberblick vor — Ports, Tunnelnetze, Zweck — und nichts
|
||||
darüber hinaus. **Bei Widerspruch gilt `homelab/docs`.**
|
||||
|
||||
---
|
||||
|
||||
## LABNET-01 — WireGuard-Roadwarrior ins Lab kaputt (seit einigen Monaten)
|
||||
|
||||
**Status:** GELÖST 2026-08-01 ~15:20 — `git.lab` lädt vom Handy über 5G/VPN. ✅
|
||||
Damit ist die Cutover-Voraussetzung für gitops#48 erfüllt.
|
||||
|
||||
**Drei gestapelte Ursachen (jede verdeckte die nächste):**
|
||||
1. **Privater Endpunkt** in jeder UDM-generierten Client-Config (UDM kennt hinter
|
||||
der Fritzbox ihre öffentliche IP nicht) → Fix: Endpunkt `178.25.213.70`;
|
||||
dauerhaft gelöst über UniFi-Option **„Alternate Address for Clients"**.
|
||||
2. **FritzOS reserviert UDP 51820 für seinen eigenen WireGuard-Stack** — die
|
||||
Portfreigabe 51820→UDM lief ins Leere (erklärt die „invalid response"-Stürme
|
||||
im Juli: zwei WG-Stacks auf einem Port) → Fix: UDM-WG auf **51840**.
|
||||
3. **Docker-Routen-Kollision auf Overmind**: Dokploys Bridge-Netze belegen zehn
|
||||
/20-Blöcke in 192.168.0.0/16; `192.168.0.0/20` verschluckte das VPN-Subnetz
|
||||
192.168.5.0/24 → Antworten an VPN-Clients endeten in der Bridge (SYN kam an,
|
||||
SYN-ACK verschwand — exakt der Chrome-Connection-Timeout, während Ping/DNS/
|
||||
fremde Hosts funktionierten) → Fix: **VPN-Subnetz auf 10.58.74.0/24** (Docker
|
||||
fasst 10.x nie an).
|
||||
|
||||
**Restarbeiten:** MacBook-WG-Profil → [Issue #11](https://git.lab/axion1337.chat/management/-/issues/11). ⚠️ Latente Wiederholungsgefahr
|
||||
notiert: Overminds Docker-Pool deckt auch `192.168.176.0/20` ab = kollidiert mit
|
||||
dem Fritzbox-Netz 192.168.178.x — aktuell folgenlos, aber bei künftigen Subnetz-
|
||||
Entscheidungen 192.168.x auf Overmind grundsätzlich meiden (oder Docker
|
||||
default-address-pools begrenzen).
|
||||
|
||||
**Bestätigte Ursachenkette (Diagnose-Session 2026-08-01):**
|
||||
1. Handy-Profil „@home" hatte seit 07.07. die **private** UDM-WAN-IP
|
||||
(192.168.178.20) als Endpunkt — die UDM kennt hinter der Fritzbox ihre
|
||||
öffentliche IP nicht und schreibt sie in jede generierte Config
|
||||
(⚠️ gilt für ALLE künftig exportierten Profile: Endpunkt manuell auf
|
||||
178.25.213.70 ändern!).
|
||||
2. Nach Endpunkt-Fix weiter tot: **FritzOS reserviert UDP 51820 für seinen
|
||||
EIGENEN WireGuard-Stack** — die alte Portfreigabe 51820→UDM lief ins Leere
|
||||
(erklärt auch die „invalid response"-Stürme im Juli: zwei WG-Stacks auf
|
||||
einem Port). Fix: UDM-WG auf **51840** umgezogen + Freigabe angepasst.
|
||||
3. Server + Schlüssel waren nie das Problem (WLAN-Handshake bewies beides).
|
||||
|
||||
Danach nur noch der ursprüngliche Blocker-Vermerk:
|
||||
blockierte gitops#48 (Erreichbarkeits-Entscheidung „WireGuard statt exponieren")
|
||||
|
||||
sorb hatte einen funktionierenden VPN-Zugang fürs Handy ins Lab; seit einigen
|
||||
Monaten „funktioniert das nicht mehr sauber" (Symptome noch zu präzisieren:
|
||||
Handshake? Routing nur teilweise? DNS?). Setup-Rahmen laut sorb (2026-08-01):
|
||||
UDM Pro hinter Fritzbox, ohne doppeltes NAT, statische Route in der Fritzbox
|
||||
für das VLAN.
|
||||
|
||||
**Diagnose-Plan von VOR der Lösung** — ⚠️ abgearbeitet und überholt, steht hier
|
||||
nur als Beleg, wie die Ursachen eingekreist wurden. Nichts davon ist zu tun:
|
||||
1. Symptom präzisieren: Handshake kommt zustande? (`wg show` auf der UDM /
|
||||
Client-Log) — trennt Portweiterleitungs- von Routing-Problemen
|
||||
2. Fritzbox: Portfreigabe UDP (WireGuard-Port) → UDM noch vorhanden/korrekt?
|
||||
(FritzOS-Updates werfen gern Freigaben/Exposed-Host-Einstellungen um)
|
||||
3. ~~DS-Lite~~ **ausgeschlossen** (sorb 2026-08-01: Dualstack + feste IPs) —
|
||||
damit auch kein DynDNS-Drift möglich. Verdacht konzentriert sich auf:
|
||||
FritzOS-Update warf die UDP-Portfreigabe um, UniFi-OS-Update veränderte
|
||||
WG-Server/Firewall, oder die statische Route griff nach Änderung nicht mehr.
|
||||
4. (entfällt — feste IP)
|
||||
5. UDM-Seite: WireGuard-Server-Config/Firewall-Regeln nach UniFi-OS-Updates
|
||||
prüfen; statische Route Fritzbox → VLAN gegenchecken
|
||||
6. Erst wenn 1–5 sauber: Client-Profil fürs Handy neu ausstellen, git.lab-DNS
|
||||
(Lab-Resolver) in die AllowedIPs/DNS-Konfig aufnehmen — Erfolgsbeweis =
|
||||
Issue-Board vom Handy über VPN erreichbar
|
||||
|
||||
**Verwandt:** gitops#48 (Cutover erst nach Lösung), perspektivisch ersetzt ein
|
||||
funktionierender Roadwarrior auch Ad-hoc-Wünsche wie „GitLab exponieren".
|
||||
|
||||
## Zugehörige Issues — alle geschlossen
|
||||
|
||||
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.
|
||||
|
||||
Zum Netz/VPN ist **nichts mehr offen** (Stand 2026-08-02):
|
||||
|
||||
| Issue | Thema | Stand |
|
||||
|---|---|---|
|
||||
| [#11](https://git.lab/axion1337.chat/management/-/issues/11) | LABNET-01-Rest — MacBook-WireGuard-Profil | geschlossen |
|
||||
| [#12](https://git.lab/axion1337.chat/management/-/issues/12) | LABNET-02 — Site-to-Site-VPN (Design: [ADR-0004](../../adr/0004-site-to-site-vpn-hetzner-lab.md)) | geschlossen, Testreihe 1–7 protokolliert |
|
||||
| [#16](https://git.lab/axion1337.chat/management/-/issues/16) | LABNET-04 — Feinschliff UniFi-Regeln | geschlossen |
|
||||
|
||||
Zwei Punkte tragen zwar LABNET im Text, gehören aber **nicht** zum VPN-Thema und
|
||||
bleiben offen: [#13](https://git.lab/axion1337.chat/management/-/issues/13)
|
||||
(LABNET-03, Rückbau der Gitea-Ausnahme für Übergabe-Issues — durch den Tunnel
|
||||
erst möglich geworden, aber eine Repo-Frage) und
|
||||
[#15](https://git.lab/axion1337.chat/management/-/issues/15) (CFGMON-15,
|
||||
Widerruf der Einmal-Tokens aus der LABNET-02-Nacht — Credential-Hygiene, und der
|
||||
Widerruf kann still einen Push-Mirror brechen, solange dessen hinterlegtes Token
|
||||
unbekannt ist).
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
type: wiki-page
|
||||
area: architecture
|
||||
related:
|
||||
- "docs/adr/0001-gitlab-kanonisch-push-mirror.md"
|
||||
- "docs/adr/0002-issues-und-management-ins-lab.md"
|
||||
- "docs/adr/0004-site-to-site-vpn-hetzner-lab.md"
|
||||
- "docs/adr/0006-wikis-konsolidieren-docusaurus.md"
|
||||
---
|
||||
|
||||
# Mirror-Topologie: Das Lab ist die Quelle der Wahrheit
|
||||
|
||||
Begründungsprosa übernommen aus der alten `CLAUDE.md` (Abschnitt
|
||||
„Projektrealitäten", Wortlaut in der git-Historie vor der
|
||||
neckbeard-Migration); die verbindlichen Regeln stehen in `AGENTS.md` §6
|
||||
und den verlinkten ADRs. Erhalten per Feldtest-Befund F-013: Diese
|
||||
Begründung samt Gegenargument und Rettungspfad ist der Wert — sie
|
||||
erklärt, warum die Topologie so aussieht und so bleiben soll.
|
||||
|
||||
- Kanonische Repos liegen auf `git.lab/axion1337.chat/*` (nur im
|
||||
Lab/VPN auflösbar). Gitea/rohana wird per **Push-Mirror** beliefert
|
||||
und bleibt Flux-Source, Container-/npm-Registry und Release-Download
|
||||
([ADR-0001](../../adr/0001-gitlab-kanonisch-push-mirror.md)).
|
||||
- **Warum überhaupt zwei Orte — und warum das kein Altbestand ist:**
|
||||
Auf git.lab liegen die *Baupläne*, auf Gitea eine Kopie, die der
|
||||
Cluster **ohne verfügbares Lab** erreicht. Der Hetzner-Cluster muss
|
||||
sich bauen und neu ausrollen lassen, wenn das Homelab aus ist, im
|
||||
Umbau steckt oder niemand zu Hause ist — er darf deshalb nicht von
|
||||
einem Host abhängen, der nur im Lab antwortet.
|
||||
⚠️ **Die Flux-Quelle nicht „geradeziehen"** auf git.lab: Das sähe
|
||||
aufgeräumter aus und würde die Verfügbarkeit der Produktion an das
|
||||
Lab koppeln — genau das, was die Trennung verhindert.
|
||||
- **Gespiegelt wird nur die Gruppe `axion1337.chat`** (die Produkt-Repos
|
||||
und `management`). Die Gruppe **`homelab`** (`docs`, `wiki`,
|
||||
`wiki-bookstack`) hat bewusst **keine Mirrors**: Sie beschreibt und
|
||||
konfiguriert ausschließlich Lab-Infrastruktur, und seit dem
|
||||
Site-to-Site-VPN ([ADR-0004](../../adr/0004-site-to-site-vpn-hetzner-lab.md))
|
||||
erreichen auch Host-Sessions git.lab direkt — Tunnel einschalten
|
||||
genügt. Betriebslehren, die von außen lesbar sein müssen, gehören
|
||||
deshalb in die **AARs** unter `docs/aar/` (dieses Repo ist
|
||||
gespiegelt), nicht nur in die READMEs der Lab-Repos.
|
||||
- Landet doch ein Commit auf Gitea (z. B. aus einer Host-Session ohne
|
||||
Lab-Route): **Kanonisierungs-Verfahren** in
|
||||
[deploy-uebergabe](../deployment/deploy-uebergabe.md) — `.patch` von
|
||||
Gitea ziehen, `git am` (erhält Autorschaft), Push über git.lab.
|
||||
- ⚠️ gitops-Issue-Nummern haben sich beim Gitea-Umzug verschoben (Gitea
|
||||
zählte PRs mit; z. B. Gitea#48 → GitLab#46) — alte „gitops#N"-Verweise
|
||||
meinen die Gitea-Nummer; verbindlich ist der Migrations-Fußtext im
|
||||
Issue ([ADR-0002](../../adr/0002-issues-und-management-ins-lab.md)).
|
||||
- **Ausnahme** (bewusst entschieden, nur noch eine): der
|
||||
TURN-Rotations-CronJob schreibt weiter nach Gitea, weil er im Cluster
|
||||
läuft und git.lab nicht erreicht. **Die Rotation nicht von Hand
|
||||
nachziehen und den PR nie auf Gitea mergen** — das erledigt seit
|
||||
2026-08-02 der geplante CI-Job `canonize_rotation` im gitops-Repo
|
||||
täglich von git.lab aus. Scheitert er, bleibt die Pipeline rot; diese
|
||||
rote Pipeline **ist** der Alarm, einen zusätzlichen Termin gibt es
|
||||
bewusst nicht.
|
||||
- **Dokumentation** ([ADR-0006](../../adr/0006-wikis-konsolidieren-docusaurus.md)):
|
||||
Das gitops-Wiki liegt seit 2026-08-02 auf git.lab (*Wiki*-Reiter im
|
||||
Projekt); ⚠️ der `wiki`-**Branch** im gitops-Repo ist ein überholter
|
||||
Mai-Abzug von `docs/` und nicht die gepflegte Fassung. Alle Quellen
|
||||
zusammen erscheinen unter **axionwiki.lab**
|
||||
([`homelab/wiki`](https://git.lab/homelab/wiki), Docusaurus) —
|
||||
Inhalte werden beim Bau geholt, **Änderungen gehören ins Quell-Repo**.
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
type: wiki-page
|
||||
area: architecture
|
||||
related: []
|
||||
---
|
||||
|
||||
# DNS-Zone `axion1337.de` und Mail-Policy
|
||||
|
||||
Übergreifend, weil die Zone alle Hosts abdeckt und die Mail-Policy sich nicht pro
|
||||
Host trennen lässt.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Registrar / DNS** | IONOS (`ns1098.ui-dns.biz`, `ns1022.ui-dns.com`, `ns1070.ui-dns.org`, `ns1059.ui-dns.de`) |
|
||||
| **Apex** | `217.160.0.140` / `2001:8d8:100f:f000::2e9` — IONOS-Hosting, nicht eigene Infrastruktur |
|
||||
| **Mail** | IONOS (`mx00.ionos.de`, `mx01.ionos.de`) |
|
||||
| **Stand** | 2026-08-06 (Mail-Records gemessen) |
|
||||
|
||||
**Ist-Stand der Mail-Härtung** (gemessen 2026-08-06 über DoH, um den Lab-Resolver
|
||||
zu umgehen):
|
||||
|
||||
| Name | `www` | MX | SPF | `_dmarc` | Bewertung |
|
||||
|---|---|---|---|---|---|
|
||||
| `rohana` | löst auf ❌ | gelöscht | **gelöscht** ⚠️ | fehlt | ⚠️ schwächer als vorher |
|
||||
| `selendis` | weg ✅ | IONOS ❌ | `~all` ❌ | fehlt | unangetastet |
|
||||
| `matrix` | löst auf ❌ | IONOS ❌ | `~all` ❌ | fehlt | offen |
|
||||
| `game` | löst auf ❌ | — | — | fehlt | teilweise |
|
||||
| **Apex** | legitim ✅ | IONOS (genutzt) | `~all` | **`p=none`** ⚠️ | siehe ZONE-02 |
|
||||
|
||||
Kein einziger Name trägt bisher `_dmarc`, alle erben damit `p=none` vom Apex.
|
||||
|
||||
> **Die Aufstellung ist nicht garantiert vollständig.** Zonentransfer ist verweigert,
|
||||
> DNS erlaubt kein Enumerieren. Die Records unten stammen aus gezielten Abfragen und
|
||||
> der IONOS-Oberfläche. Für eine vollständige Prüfung entweder die ungefilterte
|
||||
> IONOS-Liste durchgehen oder die Certificate-Transparency-Logs abfragen (zeigt alle
|
||||
> Namen, für die je ein Cert ausgestellt wurde).
|
||||
|
||||
## Bekannter Bestand
|
||||
|
||||
| Name | A | AAAA | Ziel |
|
||||
|---|---|---|---|
|
||||
| `axion1337.de` | `217.160.0.140` | `2001:8d8:100f:f000::2e9` | IONOS-Hosting |
|
||||
| `www` | `217.160.0.140` | dito | IONOS-Hosting — hier ist `www` **legitim** |
|
||||
| `rohana` | `188.245.193.243` | `2a01:4f8:c17:93eb::1` | CFGMON, Gitea |
|
||||
| `selendis` | `188.245.193.243` | `2a01:4f8:c17:93eb::1` | CFGMON, Grafana |
|
||||
| `game` | `157.90.155.206` | — | Pterodactyl |
|
||||
| `matrix` | `49.13.132.245` | — | Matrix-Homeserver |
|
||||
| `ftp` | `217.160.233.227` | `2001:8d8:1000:30f5:…` | IONOS-Default |
|
||||
| `www.rohana`, `www.selendis`, `www.game`, `www.matrix` | wie ohne `www` | teils | überflüssig, siehe ZONE-01 |
|
||||
|
||||
Mail-Records existieren auf `selendis` und `matrix` (MX ×2, SPF, DKIM-CNAMEs,
|
||||
`autodiscover`), auf `rohana` und `game` nicht.
|
||||
|
||||
## Was die Mail-Records eigentlich tun
|
||||
|
||||
Damit die Rezepte in [ZONE-01](https://git.lab/axion1337.chat/management/-/issues/5)
|
||||
nicht als Zahlensalat dastehen: Vier Mechanismen, die zusammenspielen. **Keiner
|
||||
schützt allein.**
|
||||
|
||||
### Das Grundproblem
|
||||
|
||||
Der Absender einer Mail (`From:`) ist frei wählbar — SMTP prüft ihn nicht. Jeder
|
||||
kann `rechnung@rohana.axion1337.de` in den Umschlag schreiben. Die folgenden
|
||||
Records sind die Möglichkeit, dem widersprechen, **bevor** jemand darauf hereinfällt.
|
||||
|
||||
### SPF — „diese Server dürfen für mich senden"
|
||||
|
||||
TXT-Record am Namen selbst. Listet die berechtigten Absender-IPs.
|
||||
|
||||
Entscheidend ist das **Ende** des Eintrags:
|
||||
|
||||
| Endung | Bedeutung | Wirkung beim Empfänger |
|
||||
|---|---|---|
|
||||
| `~all` | Softfail | „war nicht auf der Liste" → wird meist **trotzdem zugestellt**, evtl. markiert |
|
||||
| `-all` | Hardfail | „war nicht auf der Liste" → **ablehnen** |
|
||||
|
||||
`v=spf1 -all` ohne jeden Server davor heißt: *Für diesen Namen sendet niemand.*
|
||||
Genau die richtige Aussage für `rohana`, `selendis`, `matrix` — die verschicken keine
|
||||
Mail (für `matrix` verifiziert in MATRIX-01: weder Synapse noch MAS senden).
|
||||
|
||||
⚠️ **Es darf nur EIN SPF-Record je Name existieren.** Ein zweiter erzeugt
|
||||
`PermError`, und dann prüfen viele Empfänger **gar nicht mehr** — die Härtung
|
||||
schlägt ins Gegenteil um. Deshalb: bestehenden TXT **editieren**, nie einen zweiten
|
||||
anlegen.
|
||||
|
||||
### DKIM — „diese Mail wurde unterwegs nicht verändert"
|
||||
|
||||
Signatur mit einem privaten Schlüssel, öffentlicher Teil als CNAME/TXT im DNS
|
||||
(`s1-ionos._domainkey…`). Beweist Unversehrtheit und Herkunft.
|
||||
|
||||
Für Namen, die nicht senden, sind die DKIM-Einträge schlicht **Ballast** — sie
|
||||
signieren nichts. Sie können weg.
|
||||
|
||||
### DMARC — „und das tust du, wenn SPF oder DKIM nicht passen"
|
||||
|
||||
TXT unter `_dmarc.<name>`. SPF und DKIM stellen nur **fest**; DMARC sagt, welche
|
||||
**Konsequenz** das hat:
|
||||
|
||||
| Policy | Wirkung |
|
||||
|---|---|
|
||||
| `p=none` | nur beobachten — **kein Schutz**, Mail wird zugestellt |
|
||||
| `p=quarantine` | in den Spam-Ordner |
|
||||
| `p=reject` | ablehnen |
|
||||
|
||||
⚠️ **DMARC wird vererbt.** Fehlt `_dmarc.rohana`, gilt die Policy des
|
||||
organisatorischen Namens `axion1337.de`. Die steht heute auf **`p=none`**
|
||||
([ZONE-02](https://git.lab/axion1337.chat/management/-/issues/6)) — **damit erben
|
||||
alle Subdomains „kein Schutz"**, egal wie sauber ihr SPF ist.
|
||||
|
||||
Das ist der wichtigste Hebel der ganzen Zone: **Der Apex wirkt auf alle Namen
|
||||
gleichzeitig.** Mit `sp=` lässt sich für Subdomains sogar eine strengere Policy
|
||||
setzen als für den Apex selbst.
|
||||
|
||||
### Null-MX — „hier nimmt niemand Mail an" (RFC 7505)
|
||||
|
||||
Ein MX-Record mit dem Ziel `.` (Punkt) und Priorität 0.
|
||||
|
||||
Der Grund, warum **Löschen nicht reicht**: Findet ein Absender **keinen** MX,
|
||||
weicht er per RFC 5321 auf den **A/AAAA-Record** aus und versucht, direkt an den
|
||||
Webserver zuzustellen. Der Name sieht dann nach „nimmt vielleicht Mail an" aus.
|
||||
Null-MX sagt stattdessen ausdrücklich *nein* — Absender brechen sofort ab.
|
||||
|
||||
### Warum die Kombination
|
||||
|
||||
| Record | Beantwortet die Frage |
|
||||
|---|---|
|
||||
| **Null-MX** | Nimmt dieser Name Mail **an**? → nein |
|
||||
| **SPF `-all`** | Darf jemand für diesen Namen **senden**? → niemand |
|
||||
| **DMARC `p=reject`** | Was tun, wenn doch jemand behauptet, es zu dürfen? → ablehnen |
|
||||
|
||||
Erst zusammen ergeben sie eine Aussage, auf die sich ein Empfänger verlassen kann.
|
||||
Einzeln bleibt jeweils eine Lücke — und **ersatzloses Löschen** hinterlässt die
|
||||
größte: keine Aussage ist schwächer als eine schlechte Aussage.
|
||||
|
||||
**Real eingetreten:** Bei `rohana` sind MX und SPF gelöscht, die Ersatz-Records
|
||||
fehlen (gemessen 2026-08-06). Vorher gab es wenigstens ein Softfail-SPF, jetzt gar
|
||||
keine Aussage mehr — dazu die geerbte `p=none` vom Apex. Der Halbfertig-Zustand ist
|
||||
schwächer als der Ausgangszustand.
|
||||
|
||||
## 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.
|
||||
|
||||
- [ZONE-01 — IONOS-Default-Records bereinigen (Rezepte im Issue; rohana/selendis in Arbeit)](https://git.lab/axion1337.chat/management/-/issues/5)
|
||||
- [ZONE-02 — Apex-DMARC ist `p=none` und schützt nichts](https://git.lab/axion1337.chat/management/-/issues/6)
|
||||
|
||||
Reference in New Issue
Block a user