Files
infrastructure/docs/GNAI-006-SEC_VPN_Implementation-Log.md
T
2026-09-19 15:55:58 +02:00

139 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GNAI-006-SEC – Implementation-Log
**Dokumenten-ID:** GNAI-006-SEC-SOP-04
**Bezug:** [Gateway-Architektur](GNAI-006-SEC_VPN.md)
**Zweck:** Historische Umsetzung, Korrekturen an früheren Befunden und noch offene Abnahmen nachvollziehbar halten.
## Änderungsverlauf
| Datum | Version | Autor | Änderung |
| --- | --- | --- | --- |
| 2026-09-09 | 1.x | spektr | ursprüngliches Aufbau- und Testprotokoll |
| 2026-09-15 | 2.0 | spektr | Historie nach v14/v15 getrennt, Betreiberangaben eingearbeitet, unbelegte Befunde korrigiert, offene Sicherheitsabnahmen ausgewiesen |
| 2026-09-16 | 2.1 | spektr | bestätigten Fail2Ban-Pin und wieder laufenden Container als Querverweis aufgenommen; weitergehende Abnahme nicht unterstellt |
| 2026-09-18 | 2.2 | spektr | Lesenden SSH-Abgleich von CT 105 und Grenzen des Nachweises dokumentiert. |
## 1. Evidenz und zeitliche Einordnung
| Zeitpunkt | Evidenz |
| --- | --- |
| 09.09.2026 | Quellenprotokoll zum Serveraufbau, initial v14 und anschließende Migration auf v15.4.0 |
| 12.09.2026 | dokumentierter CachyOS-Laptoptest aus WAN |
| 15.09.2026 | Betreiber liefert LXC-Konfiguration, Quadlet, Hooks, Routen und Forwarding; bestätigt deaktivierte Per-Client Firewall |
| 15.09.2026 | Betreiber bestätigt NPM `.10`, WireGuard `.15`, dynamischen LXC-Bestand bis `.99`, DHCP `.100–.200`; neues Rollenmodell |
| 16.09.2026 | Betreiber bestätigt Fail2Ban-Pin `1.1.0-r2-ls43` und wieder laufenden Container; weitergehende Fail2Ban-Abnahme nicht gemeldet |
| 18.09.2026 | lesender SSH-Abgleich auf CT 105: Dienste, Container, nftables, iptables-legacy und Listener geprüft |
| diese Revision | Dokumentationsänderungen; keine WireGuard-Systemänderung und keine zusätzliche WireGuard-Abnahme |
## 2. Historischer Serveraufbau am 09.09.2026
Im WireGuard-LXC wurde Benutzer `admin` mit SSH-Key und passwortlosem sudo eingerichtet. Quellen nennen uid 1000 und `/etc/sudoers.d/admin`. SSH-Drop-in `/etc/ssh/sshd_config.d/99-security.conf` deaktiviert Root-, Passwort- und Keyboard-Interactive-Login. Der lokale SSH-Alias `lxc` verwendet `10.0.0.15`, Benutzer `admin` und einen dedizierten Ed25519-Key. Der Alias ist Workstation-Konfiguration, kein DNS- oder Hostname.
Die nftables-Baseline mit INPUT/FORWARD-DROP und breiter VPN→LAN-Freigabe sowie persistentes `net.ipv4.ip_forward=1` wurden dokumentiert. TUN war über `105.conf` durchgereicht. Podman 5.4.2, Datenverzeichnis und Quadlet wurden eingerichtet. Die generierte Unit heißt `wg-easy.service`.
### 2.1 v14-Phase: ausschließlich historisch
Die erste Phase verwendete `ghcr.io/wg-easy/wg-easy:latest`, zu diesem Zeitpunkt laut Quellen v14. VPN-Defaults lagen in `WG_HOST`, `WG_PORT`, `WG_DEFAULT_ADDRESS`, `WG_DEFAULT_DNS` und `WG_ALLOWED_IPS`; GUI-Anmeldung verwendete bcrypt-`PASSWORD_HASH`. Zustand lag in `wg0.json`, Client-IDs waren UUIDs.
Historische API-Pfade waren `POST /api/session`, `POST /api/wireguard/client` und `GET /api/wireguard/client/<UUID>/configuration`. Diese Referenz gehört nicht in v15-Betriebsanweisungen. Das damals globale clientseitige AllowedIPs-Default wurde um Split-Tunnel-Netze ergänzt. Alte Environment- und API-Anweisungen sind obsolet und dürfen nicht in das aktuelle v15-Setup übernommen werden.
### 2.2 Migration auf v15.4.0
Das Hauptdokument protokolliert eine Migration am 09.09.2026 mittels Setup-API und Import von `wg0.json`; Server- und Client-Schlüssel einschließlich PresharedKeys wurden übernommen. Ein Backup ist unter `/opt/wg-easy/backup-2026-09-09/` genannt. Existenz, Konsistenz und Restore wurden in dieser Revision nicht überprüft.
Der aktuelle Quadlet-Pin `15.4.0` ist durch den Betreiber bestätigt. v15 verwendet `wg-easy.db`; `wg0.conf` wird erzeugt. VPN- und Clientwerte werden im Admin Panel gepflegt. Das alte `PASSWORD_HASH`-Environment ist kein aktueller Passwortspeicher. Quellen nennen 1Password-Eintrag `ghostnet/wg-easy-ui`; Passwort nicht in Dokumente übernehmen. Historische API-Aufrufe sind keine geprüfte aktuelle API-Spezifikation.
## 3. Historische Peers und Laptoptest am 12.09.2026
| Altpeer | VPN-IP | v15-Client-ID laut Quellen | Einordnung |
| --- | --- | --- | --- |
| Laptop-FullAdmin | `10.8.0.2` | 1 | neue Rolle Familie oder Server Admin noch ausdrücklich zuordnen |
| Android-LLMAdmin | `10.8.0.3` | 2 | Altbestand; Android außerhalb des neuen SOP-Umfangs, keine Praxisabnahme |
Profile wurden laut Log manuell aus der SQLite-Datenbank generiert und gegen die Serverkonfiguration geprüft. Das ist ein historischer Vorgang, kein künftiges SOP-Verfahren. Neue Profile werden über die GUI exportiert. Der Pfad `docs/GNAI-006-profiles/` wurde als gitignored genannt; Profile bleiben unabhängig von Git-Ausschlüssen Geheimnisse.
Der Laptop wurde von außerhalb des Heimnetzes über EasyCable mit damaliger Außen-IPv4 `80.187.120.60` getestet. Diese und die damalige Heimnetz-WAN-IP sind zeitgebundene Messwerte, keine DNS-Sollwerte.
| Prüfung | Ergebnis |
| --- | --- |
| WireGuard-Handshake | bestanden; Server sah Endpoint `80.187.120.60:1688` und Transfer |
| Ping `10.8.0.1` | bestanden |
| Ping `10.0.0.2` | bestanden |
| `curl -4 ifconfig.co` | `80.187.120.60`; Internetpfad blieb direkt |
| Ping KI-Server `10.0.0.90` | nicht durchgeführt / zurückgestellt, Server ausgeschaltet |
| Android-Handshake und Zugriff | ausstehend |
| Proxmox-GUI / SSH und Rollenisolierung | kein Abnahmenachweis |
Der Betreiber bestätigt: Seit diesem Test keine weiteren WireGuard-Abnahmen.
## 4. Betreiberbestätigung am 15.09.2026
CT 105: unprivileged, Debian/amd64, Hostname `wireguard`, 1 Core, 512 MiB RAM, 512 MiB Swap, 4 GiB RootFS, nesting/keyctl, `eth0` an `vmbr0`, statisch `10.0.0.15/24`, Gateway `.1`, onboot und TUN-Passthrough. Quadlet rootful mit host-Netz, NET_ADMIN/NET_RAW, Environment-File und persistenter Datenvolume-Bindung. Vollständige reproduzierbare Angaben stehen in der Architektur.
Hooks: PreUp/PreDown leer; PostUp legt MASQUERADE für VPN→LAN sowie breite UDP-INPUT-/wg0-FORWARD-ACCEPT-Regeln an; PostDown entfernt diese. **Per-Client Firewall deaktiviert.** Routen: Default über `.1`, Heimnetz auf eth0, VPN-Netz auf wg0. Forwarding aktiv. Die Fritzbox hat keine Rückroute zu `10.8.0.0/24`.
Die Fritzbox-Portweiterleitungen sind TCP 80/443→NPM `.10` und UDP 51820→WireGuard `.15`; die zwischenzeitlich vertauschte Betreiberangabe ist ausdrücklich korrigiert.
## 5. Korrekturen an früheren technischen Befunden
| früherer Befund | korrigierte Bewertung |
| --- | --- |
| Android akzeptiert nur `/32`, keine `/24` | ungetestete Behauptung eines LLM laut Betreiber; als allgemeine Einschränkung verworfen |
| CIDR plus einzelne `/32` nötig für Android | keine belastbare Begründung; innerhalb desselben `/24` sind diese `/32` im normalen Routing redundant |
| clientseitiges AllowedIPs-Profil isoliert die Rolle | kontrolliert Routing; serverseitige Firewall muss geänderte Clientprofile abfangen |
| PostUp-Hooks vollständig redundant | MASQUERADE wird mangels Rückroute benötigt; Filterregeln müssen mit Peer-Firewall geprüft werden |
| serverseitige AllowedIPs generell hartkodiert und unveränderlich | v14-Quellbefund nicht als pauschale v15-Aussage weiterführen; für Einzelgeräte eigenes VPN-IP-`/32` beibehalten |
| wg-quick ergänzt `wg-`, maximal 12 Zeichen im Profilnamen | kein Präfix; Basisname ist Interface, maximal 15 Zeichen |
| v14-Environment und `wg0.json` weiterhin aktiv | v15-Datenbank und aktuelle Container-Schalter verwenden; Altdateien allenfalls historischer Bestand |
| selfHOST kein DNS-Anbieter | verworfen; Fritzbox aktualisiert selfHOST-DynDNS laut Betreiber |
| Wildcard macht zusätzlichen A-Record immer harmlos | veraltete feste Records können Wildcard-Zuordnung übersteuern; tatsächlich vorhandenen Record und Update prüfen |
[wg-quick-Quelle](https://git.zx2c4.com/wireguard-tools/tree/src/wg-quick/linux.bash), [wg-easy-Clientreferenz](https://wg-easy.github.io/wg-easy/latest/guides/clients/)
## 6. Historisches Fehlerregister
| ID | Vorgang | gültige Einordnung |
| --- | --- | --- |
| F1 | Permission denied / nft nicht im PATH | sudo verwenden; unter Debian liegt nft üblicherweise in `/usr/sbin` |
| F2 | `wg-easy.container.service` nicht gefunden | generierte Unit heißt `wg-easy.service` |
| F3 | Inline-Escaping des bcrypt-Environment schlug fehl | ausschließlich v14; EnvironmentFile löste den damaligen Fehler |
| F4 | `POST /` lieferte 405 | falscher historischer v14-Loginpfad; keine v15-Anweisung |
| F5 | Download mit Name statt UUID lieferte 404 | historische v14-API; künftig GUI-Export |
| F6 | allowedIPs im v14-Create nicht übernommen | v14-Implementierungsbefund; neues Rollenmodell setzt Server-Firewall voraus |
| F7 | wg-Tool im LXC nicht gefunden | Serverstatus mit `sudo podman exec wg-easy wg show wg0` prüfen |
| F8 | sysctl nicht gefunden | procps/PATH prüfen; Forwarding unter `/proc/sys/net/ipv4/ip_forward` lesbar |
| F9 | wireguard-dkms in CachyOS nicht verfügbar | im getesteten Kernel WireGuard vorhanden; wireguard-tools genügte |
| F10 | zu langer Profil-/Interface-Name | `Laptop-FullAdmin` hat 16 Zeichen; auf `laptop` umbenannt, ohne Präfix |
| F11 | öffentliche IP-Abfrage lieferte IPv6 | `curl -4` für einen gezielten IPv4-Vergleich |
## 7. Lesender Live-Abgleich am 18.09.2026
Per SSH-Profil `lxc` wurde CT 105 ohne Konfigurationsänderung geprüft:
| Prüfung | Beobachtung |
| --- | --- |
| Host und Dienste | Hostname `wireguard`; `wg-easy` und `nftables` aktiv; `net.ipv4.ip_forward=1` |
| Container | `ghcr.io/wg-easy/wg-easy:15.4.0`, `host`-Netzwerk, Status `running`; WireGuard-Interface `wg0` vorhanden |
| nftables | INPUT-Policy `drop`, UDP 51820 erlaubt; TCP 22/51821 nur für Quellen aus `10.0.0.0/24` ausdrücklich erlaubt; FORWARD-Policy `drop` mit breiter Freigabe `wg0` → `10.0.0.0/24` |
| iptables | Standardaufruf meldet vorhandene Legacy-Tabellen; `iptables-legacy` zeigt FORWARD-ACCEPT für `wg0` in beide Richtungen und MASQUERADE für `10.8.0.0/24` über `eth0` |
| Listener | UDP 51820 auf IPv4 und IPv6; TCP 51821 auf allen IPv4-Adressen; SSH TCP 22 auf IPv4 und IPv6. Listener allein beweisen keine Erreichbarkeit aus dem Internet. |
| DNS-Abgleich | `vpn.ghostnet.selfhost.eu` und ausgehende Gateway-IPv4: `93.208.161.126`; `vpn.ghostnet.dyndns.eu`: `83.169.40.234`. Dieser Zeitpunkt belegt keine automatische Aktualisierung. |
Diese Beobachtungen bestätigen den breiten Netzpfad und die NAT-Abhängigkeit. Sie belegen keine Peer-spezifische Zugriffsbeschränkung; Per-Client Firewall und negative Rollentests bleiben offen. Die Prüfung erfasste weder die GUI-Einstellungen noch die Fritzbox-, IPv6-Perimeter- oder Clientseite.
## 8. Offene Umsetzung und Abnahme
| ID | Arbeit | Status |
| --- | --- | --- |
| O1 | Fritzbox-Portforward | bestätigt; Laptop-WAN-Handshake als Teilnachweis vorhanden |
| O2 | DynDNS-Aktualisierung nach WAN-IP-Wechsel und Fritzbox-Einstellung prüfen | aktueller selfhost-Endpoint am 18.09.2026 durch DNS-/WAN-Abgleich bestätigt; dyndns.eu zeigt auf andere Adresse |
| O3 | Altpeers neuen Rollen zuordnen | offen |
| O4 | Per-Client Firewall und Gateway-INPUT-Rollenrechte umsetzen | offen |
| O5 | Rollenisolierung bei geänderten lokalen AllowedIPs testen | offen |
| O6 | KI-Server, Proxmox-GUI und SSH testen | offen |
| O7 | WAN-/IPv6-Managementport-Isolation | offen |
| O8 | Reboot, Firewall-Reload und Restore | offen |
| O9 | wg-easy-GUI-HTTPS und lokales Gruppenmodell | geplant; Werte noch festzulegen |
Andere Sicherheitsbefunde werden im [Dokumentationsindex](GNAI-000-DOC_Index.md) geführt. Dieses Log hält nur WireGuard-Umsetzung und zugehörige Tests fest.