tailscale: auf natives Plugin konsolidieren, redundanten Docker-Stack entfernen, ACL-Haertung dokumentieren
- host-services/tailscale/ (userspace-only Docker-Stack) entfernt; Komodo stop/destroy durch Operator, danach git rm - Glance-Widget Tailscale-Docker entfernt - HOMELAB_ARCHITECTURE/SERVICE_CATALOG/DISASTER_RECOVERY/CLAUDE/RESTORE_MATRIX: tailscale als natives Unraid-Plugin dokumentiert; Restore-State-Pfad korrigiert auf /boot/config/plugins/tailscale/state (Flash-Backup) - NETWORK_INVENTORY: restriktive tag-basierte grants-ACL (2026-06-06; tag:server/tag:operator, tag:family vorbereitet) und Subnet-Router-Befund dokumentiert Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+90
-56
@@ -55,7 +55,7 @@ Gemessen am 2026-06-05 per read-only SSH auf den Host (`tailscale status`,
|
||||
| Tailscale IPv6 | `fd7a:115c:a1e0::2c01:62b2` (gemessen 2026-06-05) |
|
||||
| Exit Node | **Nein.** `Self.ExitNodeOption: false` und `Self.ExitNode: false` — Host bietet keinen Exit Node an und nutzt keinen. Entspricht dem Ziel (Operator-Zugang ist eingehend, nicht als Internet-Ausgang). |
|
||||
| Subnet Router | **Ja, aktiv.** Host advertised und ist Primary fuer `192.168.178.0/24` (`Self.PrimaryRoutes: ["192.168.178.0/24"]`, ebenfalls in `AllowedIPs`). Das LAN ist also fuer das gesamte Tailnet ueber diesen Subnet-Router erreichbar — bewusst gemessener Ist-Zustand, **kein** "keine Route" wie zuvor vermutet. |
|
||||
| ACL-Policy extern dokumentiert | **Operator-Entscheidung offen** — siehe eigener Block unten; durch den aktiven Subnet-Router ist die ACL-Frage sicherheitsrelevanter als zuvor angenommen. |
|
||||
| ACL-Policy extern dokumentiert | **Angewendet 2026-06-06** — restriktive Tag-basierte `grants`-Policy live (`tag:server`/`tag:operator`, `tag:family` schlafend). Default-Allow entfernt, verifiziert. Details im Block unten. |
|
||||
|
||||
### Tailnet-Geraete (Snapshot 2026-06-05)
|
||||
|
||||
@@ -65,13 +65,37 @@ Gemessen am 2026-06-05 per read-only SSH auf den Host (`tailscale status`,
|
||||
| `100.78.133.37` | baerchen-1 | windows | aktiv (aktuelle Operator-Workstation, direct) |
|
||||
| `100.105.203.21` | baerchen | windows | offline, zuletzt vor ~1 Tag gesehen (Alt-Node) |
|
||||
| `100.73.83.55` | iphone-14 | iOS | bekannt |
|
||||
| `100.112.0.90` | kallilab-core | linux | gelistet, kein aktiver Verkehr — **moeglicher Alt-/Dubletten-Node**, separat pruefen |
|
||||
| `100.112.0.90` | kallilab-core | linux | **am 2026-06-06 entfernt.** War der redundante userspace-only `Tailscale-Docker`-Stack (`host-services/tailscale/`). Komodo-Stack gestoppt+destroyed, Repo-Pfad per `git rm` entfernt, Container weg (read-only verifiziert). Node-Eintrag in der Admin-Konsole noch zu entfernen. |
|
||||
|
||||
> Hygiene-Hinweis (kein Secret): Es existieren zwei linux-Nodes mit aehnlichem
|
||||
> Namen (`kallilabcore` und `kallilab-core`) sowie zwei `baerchen`-Nodes
|
||||
> (`baerchen-1` aktiv, `baerchen` offline). Bei Gelegenheit in der
|
||||
> Tailscale-Admin-Konsole pruefen, ob die inaktiven Eintraege stillgelegt werden
|
||||
> koennen. Das ist Aufraeumarbeit, kein akutes Risiko.
|
||||
> **Befund 2026-06-06 (read-only auf dem Host ermittelt):** Der Host hat **zwei**
|
||||
> `tailscaled`-Prozesse:
|
||||
>
|
||||
> 1. **Native Unraid-Plugin** = `kallilabcore` (100.80.98.33). Prozess
|
||||
> `/usr/local/sbin/tailscaled -statedir /boot/config/plugins/tailscale/state
|
||||
> -tun tailscale1`. **Echtes TUN-Interface `tailscale1`, ist der Subnet-Router
|
||||
> fuer `192.168.178.0/24`**, laeuft seit 24. Mai, installiert via
|
||||
> `tailscale.plg` + `unraid-tailscale-utils`. State unter
|
||||
> `/boot/config/plugins/tailscale/state` → ueber das **Flash-Backup** gesichert.
|
||||
> Im ACL-Rollout `tag:server`. **Das ist die funktionale, kanonische Instanz.**
|
||||
> 2. **Docker-Stack** = `kallilab-core` (100.112.0.90), `host-services/tailscale/`.
|
||||
> Prozess `tailscaled --tun=userspace-networking` → **nur Userspace, kann
|
||||
> technisch nicht routen / kein Subnet-Router/Exit-Node sein**, advertised
|
||||
> nichts, kein Container teilt seinen Namespace, seit 31. Mai. State unter
|
||||
> `/mnt/user/appdata/tailscale`. Im ACL-Rollout untagged → isoliert.
|
||||
> **Hochwahrscheinlich redundant.**
|
||||
>
|
||||
> **Umgesetzt 2026-06-06:** Der redundante Docker-Stack `host-services/tailscale/`
|
||||
> wurde sauber per GitOps abgebaut — Komodo-Stack `tailscale` gestoppt+destroyed
|
||||
> (Operator), `git rm host-services/tailscale/`, Glance-Widget entfernt, und
|
||||
> Architektur-/Service-Catalog-/DR-/CLAUDE-Doku auf "natives Plugin" nachgezogen.
|
||||
> Read-only verifiziert: Container weg, nur noch der native `tailscaled` mit
|
||||
> `tailscale1`, Subnet-Route + Operator-Zugriff intakt. Offen: Node-Eintraege
|
||||
> `kallilab-core` und alter `baerchen` in der Admin-Konsole entfernen; State-Pfad
|
||||
> `/mnt/user/appdata/tailscale` bei Gelegenheit nach `_archive/` (kein Sofort-Loeschen).
|
||||
>
|
||||
> **Doku-Korrektur erledigt:** `docs/RESTORE_MATRIX.md` zeigt jetzt auf den
|
||||
> funktionalen State `/boot/config/plugins/tailscale/state` (im Flash-Backup)
|
||||
> statt auf den entfernten userspace-Docker-Pfad.
|
||||
|
||||
### Subnet-Router-Konsequenz
|
||||
|
||||
@@ -91,34 +115,22 @@ tailscale ip -4
|
||||
tailscale ip -6
|
||||
```
|
||||
|
||||
### ACL-Policy — Entwurf und Rollout-Plan (Stand 2026-06-05, NICHT angewendet)
|
||||
### ACL-Policy — ANGEWENDET 2026-06-06 (restriktive Tag-basierte grants)
|
||||
|
||||
Die Tailnet-ACL wird in der Tailscale-Admin-Konsole unter `Access controls`
|
||||
verwaltet (kein Wert/Secret gehoert ins Repo). Aktueller Live-Stand ist
|
||||
Default-Allow (`src: ["*"] -> dst: ["*:*"]`), d. h. jedes Tailnet-Geraet darf
|
||||
alles inklusive der LAN-Subnet-Route.
|
||||
**Status: live und verifiziert.** Die restriktive Policy wurde am 2026-06-06
|
||||
gemeinsam mit dem Operator in der lockout-sicheren Reihenfolge ausgerollt und
|
||||
read-only verifiziert (siehe "Rollout-Protokoll" unten). Ausgangspunkt war die
|
||||
**unveraenderte Default-Policy** im **`grants`-Schema** (eine Allow-all-Regel,
|
||||
keine Groups/Tags/`autoApprovers`); es gab also keinen eigenen Bestand zu
|
||||
erhalten.
|
||||
|
||||
**Abgestimmte Richtung (Operator-Entscheidungen 2026-06-05):**
|
||||
> **Schema-Hinweis:** Dieses Tailnet nutzt das `grants`-Modell
|
||||
> (`{"src","dst","ip"}`), nicht das aeltere `acls`/`action:accept`-Modell.
|
||||
> Normaler SSH-Zugriff (`ssh kallilabcore` ueber OpenSSH Port 22) wird ueber
|
||||
> `grants` geregelt, nicht ueber den `ssh`-Block; letzterer betrifft nur die
|
||||
> Tailscale-SSH-Funktion.
|
||||
|
||||
- Ziel ist eine restriktivere, Tag-basierte ACL.
|
||||
- Single-User-Realitaet: aktuell gehoeren alle Nodes demselben User
|
||||
`michaelkaleschke@`. Eine Differenzierung Operator/Familie ist nur ueber
|
||||
**Tags** moeglich. Tagging aendert Ownership/Key-Expiry und erfordert je Geraet
|
||||
Re-Auth — deshalb bewusst ein eigener, spaeterer Schritt.
|
||||
- **Heute bewusst nur Sichtung + Entwurf, kein Tagging, keine Anwendung.**
|
||||
- Familiengeraete brauchen Tailnet-Zugriff auf **bestimmte** Dienste (welche
|
||||
genau, ist noch zu konkretisieren) — `tag:family` bekommt gezielte `dst`-Regeln.
|
||||
- `iphone-14` ist ein Operator-Geraet und faellt unter `tag:operator`.
|
||||
|
||||
**Geraete -> Tag (fuer den spaeteren Tagging-Schritt):**
|
||||
|
||||
| Tag | Geraete |
|
||||
|---|---|
|
||||
| `tag:server` | `kallilabcore` (Host, Subnet-Router) |
|
||||
| `tag:operator` | `baerchen-1`, `iphone-14` |
|
||||
| `tag:family` | kuenftige Familiengeraete |
|
||||
|
||||
**Entwurf (Vorschlag, noch nicht in der Konsole gespeichert):**
|
||||
**Angewendete Policy (live, kein Secret):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -130,42 +142,64 @@ alles inklusive der LAN-Subnet-Route.
|
||||
"autoApprovers": {
|
||||
"routes": { "192.168.178.0/24": ["tag:server"] }
|
||||
},
|
||||
"acls": [
|
||||
{ "action": "accept", "src": ["tag:operator"], "dst": ["*:*"] },
|
||||
{ "action": "accept", "src": ["tag:server"], "dst": ["tag:operator:*"] },
|
||||
{ "action": "accept", "src": ["tag:family"], "dst": ["100.80.98.33:443"] }
|
||||
"grants": [
|
||||
{"src": ["tag:operator"], "dst": ["*"], "ip": ["*"]},
|
||||
{"src": ["tag:server"], "dst": ["tag:operator"], "ip": ["*"]},
|
||||
{"src": ["tag:family"], "dst": ["tag:server"], "ip": ["tcp:443"]}
|
||||
],
|
||||
"ssh": [
|
||||
{ "action": "accept", "src": ["tag:operator"], "dst": ["tag:server"],
|
||||
"users": ["root", "autogroup:nonroot"] }
|
||||
{"action": "check", "src": ["autogroup:member"], "dst": ["autogroup:self"],
|
||||
"users": ["autogroup:nonroot", "root"]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> Die `tag:family`-`dst` `100.80.98.33:443` ist ein **Platzhalter** und wird
|
||||
> durch die real benoetigten Familien-Dienste ersetzt, sobald diese feststehen.
|
||||
**Geraete-Tags (live):** `kallilabcore` = `tag:server`; `baerchen-1` + `iphone-14`
|
||||
= `tag:operator`; `kallilab-core` (Docker) + alter `baerchen` bewusst untagged ->
|
||||
isoliert.
|
||||
|
||||
**Lockout-sichere Reihenfolge (wenn die Umsetzung freigegeben wird):**
|
||||
**Rollout-Protokoll 2026-06-06 (lockout-sicher, je Schritt read-only verifiziert):**
|
||||
|
||||
1. `tagOwners` + `autoApprovers` + neue ACL-Regeln speichern, **Allow-all-Regel
|
||||
zunaechst behalten**.
|
||||
2. Geraete taggen (`baerchen-1`, `iphone-14` -> operator; `kallilabcore` ->
|
||||
server) und je Geraet die Verbindung verifizieren.
|
||||
3. Subnet-Route bleibt approved (jetzt via `autoApprovers`/`tag:server`).
|
||||
4. **Erst zuletzt** die Allow-all-Regel entfernen -> restriktiv schalten.
|
||||
5. Sofort Smoke-Tests fahren (siehe unten).
|
||||
1. Policy additiv erweitert (Tags/grants definiert, Allow-all noch drin) -> alle Peers unveraendert verbunden, Route approved.
|
||||
2. `baerchen-1` getaggt `tag:operator` -> online, verifiziert.
|
||||
3. `iphone-14` getaggt `tag:operator` -> verifiziert.
|
||||
4. `kallilab-core` faktisch geprueft (Docker-Sidecar, keine Abhaengigen) -> bewusst untagged gelassen.
|
||||
5. Host `kallilabcore` getaggt `tag:server` -> Route blieb via `autoApprovers` automatisch approved, SSH ok.
|
||||
6. Allow-all entfernt -> restriktiv. Smoke-Tests gruen: Operator-SSH ok, AdGuard-Admin ueber Tailnet `HTTP 302`, Ping 0% Verlust, Route weiter approved; Host sieht nur noch die zwei Operator-Peers (untagged Nodes isoliert). LAN-Rueckweg durchgehend verfuegbar.
|
||||
|
||||
**Smoke-Tests nach Anwendung:**
|
||||
**Schema-/Erhaltungs-Hinweis fuer spaeter:** Die LAN-Subnet-Route
|
||||
`192.168.178.0/24` wird jetzt ueber `autoApprovers`/`tag:server` approved
|
||||
(vorher manuell). Es gibt keinen eigenen Bestand zu erhalten; die Policy oben
|
||||
ist die vollstaendige Wahrheit.
|
||||
|
||||
- `baerchen-1` erreicht Host: `ping 100.80.98.33`, `ssh kallilabcore hostname` (read-only).
|
||||
- `baerchen-1` erreicht LAN ueber Route: z. B. AdGuard-Admin `http://100.80.98.33:8082`, `curl -kI https://192.168.178.58`.
|
||||
- Falls testbar: ein nicht-Operator-Geraet erreicht Route/Admin-Ports **nicht** mehr.
|
||||
- Host-Gegencheck: `tailscale status` zeigt alle Soll-Peers weiter verbunden.
|
||||
**Hintergrund / Designentscheidungen (2026-06-05/06):**
|
||||
|
||||
**Noch offene Eingaben vor Finalisierung:**
|
||||
- Single-User-Realitaet: alle Nodes gehoeren demselben User `michaelkaleschke@`.
|
||||
Eine Differenzierung Operator/Familie ist nur ueber **Tags** moeglich, deshalb
|
||||
der Tag-Ansatz statt user-/gruppenbasiert.
|
||||
- Erster Rollout bewusst klein: nur `tag:server` + `tag:operator`.
|
||||
- **`tag:family` ist vorbereitet, aber schlafend:** Tag und eine konservative
|
||||
Minimal-Regel (`dst: tag:server`, `ip: tcp:443`) sind definiert, aber **kein
|
||||
Geraet traegt den Tag**, daher null Wirkung. Sobald ein echtes Familiengeraet
|
||||
dazukommt, wird es einmal mit `tag:family` getaggt und die Regel greift sofort
|
||||
— ohne Policy-Umbau. Vor dem ersten realen Familiengeraet die Regel auf die
|
||||
dann benoetigten Dienste/Ports pruefen.
|
||||
- Der `ssh`-Block bleibt der Default (Tailscale-SSH Check-Modus); normaler
|
||||
OpenSSH-Zugriff laeuft ueber die `grants` (Port 22, fuer `tag:operator` ueber
|
||||
`ip: ["*"]` abgedeckt).
|
||||
|
||||
1. Aktueller ACL-JSON aus der Admin-Konsole (read-only gesichtet, nur Struktur dokumentiert).
|
||||
2. Konkrete Liste der Dienste/Ports, die Familiengeraete ueber Tailscale brauchen.
|
||||
**Offene Folgepunkte (kein Risiko, Hygiene/spaeter):**
|
||||
|
||||
- Familien-Dienste/Ports konkretisieren — erst wenn ein reales Familiengeraet dazukommt.
|
||||
- **Zwei-Tailscale-Konsolidierung: ERLEDIGT 2026-06-06** — redundanter Docker-Stack
|
||||
abgebaut, nur noch die native Plugin-Instanz `kallilabcore` (Subnet-Router) aktiv.
|
||||
- Tailnet-Konsole aufraeumen: Node-Eintraege `kallilab-core` (jetzt down) und
|
||||
alter Offline-`baerchen` entfernen (trivial, nur tote Geraeteeintraege).
|
||||
- State-Pfad `/mnt/user/appdata/tailscale` (vom entfernten Docker-Stack) bei
|
||||
Gelegenheit nach `_archive/tailscale-removed-2026-06-06/` (kein Sofort-Loeschen).
|
||||
- Optionaler Off-LAN-Routentest: von einem Operator-Geraet im Mobilfunk
|
||||
(nicht im Heim-LAN) ein LAN-Ziel ueber `192.168.178.0/24` erreichen, um die
|
||||
Subnet-Route end-to-end zu bestaetigen (im Heim-LAN nicht sauber isolierbar).
|
||||
|
||||
## Portfreigaben und Exposure
|
||||
|
||||
|
||||
Reference in New Issue
Block a user