Ghost.net AI Struktur um Encoding erweitert.
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
# Standard Operating Procedure
|
||||
|
||||
**Dokumenten-ID:** GNAI-001-INFRA
|
||||
**Titel:** Initialisierung und OS-Installation: LLM-Server (Phase 1)
|
||||
**Status:** Installationsanleitung mit lesendem Teilabgleich; vollständige Abnahme offen
|
||||
**Referenzen:** -
|
||||
|
||||
---
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Beschreibung der Änderung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-08-24 | 1.0 | spektr | Erstellung des Initial-Dokuments (Hardware & OS) |
|
||||
| 2026-08-24 | 1.1 | spektr | Detaillierung der BIOS-ReBAR-Settings, Netinst-CLI-Schritte, Post-Installation & Abnahmekriterien hinzugefügt. |
|
||||
| 2026-09-16 | 1.2 | spektr | Benutzer- und Netzwerkaufgaben nach GNAI-002 verlagert; ungesicherte Downloadpfade und Domainvorgabe entfernt. |
|
||||
| 2026-09-18 | 1.3 | spektr | GPU-Abnahme auf nachweisbare Geräteerkennung begrenzt; Firmwarepaket präzisiert. |
|
||||
| 2026-09-19 | 1.4 | spektr | Getrennte SSH-Zugänge für `ghost` und `ghost-agent` als erfolgreich getestet übernommen. |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck und Geltungsbereich
|
||||
|
||||
Dieses Dokument beschreibt Hardware, BIOS und Debian-Installation des KI-Servers. Benutzer, statische Netzkonfiguration und SSH-Härtung werden in [GNAI-002](GNAI-002-INFRA_Users.md) eingerichtet. Die Schritte sind eine Anleitung, kein Nachweis ihrer Ausführung auf dem bestehenden Host.
|
||||
|
||||
---
|
||||
|
||||
## 2. Spezifikationen (Hardware-Konfiguration)
|
||||
|
||||
| Komponente | Spezifikation | Bemerkung |
|
||||
| --- | --- | --- |
|
||||
| **Gehäuse** | Silverstone SST-RM42-502 | Rackmount / Server-Chassis |
|
||||
| **Mainboard** | ASRock Z790 PG Lightning | Socket LGA1700 |
|
||||
| **CPU** | Intel Core i5-13600K | 14 Kerne (6P + 8E) |
|
||||
| **CPU-Kühler** | Thermalright Peerless Assassin 120 Mini | - |
|
||||
| **RAM** | Crucial Pro DDR5 RAM 64GB Kit (2x32GB) | Dimm Slot A2 & B2 |
|
||||
| **PSU** | Corsair RM1200e | 1200W ATX 3.0 |
|
||||
| **SSD** | 2 TB Samsung 970 EVO Plus | Primäre NVMe (Slot M2_1) |
|
||||
| **GPU 1** | Sapphire Nitro+ AMD Radeon RX 6900 XT OC 16GB | PCIe Slot 1 (x16) |
|
||||
| **GPU 2** | Sapphire Nitro+ AMD Radeon RX 6900 XT OC 16GB | PCIe Slot 2 (x8/x4 via PCH) |
|
||||
|
||||
### 2.1 BIOS-Konfiguration
|
||||
|
||||
Vor der Betriebssystem-Installation sind folgende Schritte im BIOS (Aufrufen via `DEL` oder `F2` beim Booten) durchzuführen:
|
||||
|
||||
1. **Firmware-Update (Instant Flash):**
|
||||
* BIOS-Datei auf einen FAT32-formatierten USB-Stick entpacken.
|
||||
* Im BIOS navigieren zu: `Tool` -> `Instant Flash`.
|
||||
* BIOS-Version auf **`19.02`** (oder neuer) aktualisieren.
|
||||
|
||||
2. **RAM-Performance:**
|
||||
* Navigieren zu: `OC Tweaker` -> `DRAM Configuration`.
|
||||
* **Load XMP Setting:** auf **XMP Profile 1** stellen.
|
||||
|
||||
3. **Virtualisierung & PCI-Einstellungen (Wichtig für GPU/ROCm):**
|
||||
* Navigieren zu: `Advanced` -> `CPU Configuration` -> **Intel Virtualization Technology** -> `Enabled`.
|
||||
* Navigieren zu: `Advanced` -> `PCI Configuration`:
|
||||
* **Above 4G Decoding:** `Enabled`
|
||||
* **Re-Size BAR Support:** `Enabled`; tatsächliche GPU-Zuordnung nach der Installation prüfen. Aus der BIOS-Option allein folgt noch kein nachgewiesener ROCm-Leistungsgewinn.
|
||||
|
||||
---
|
||||
|
||||
## 3. Installation des Betriebssystems
|
||||
|
||||
### 3.1 Vorbereitung des Installationsmediums (am Admin-PC)
|
||||
|
||||
1. **Debian ISO herunterladen:** Die gewünschte Debian-Version und die passende `amd64`-Netinst-ISO auf [Debian CD Images](https://cdimage.debian.org/debian-cd/) auswählen. ISO und `SHA512SUMS` aus demselben Release-Verzeichnis herunterladen; Dateinamen nicht aus dieser Anleitung ableiten.
|
||||
|
||||
2. **Checksum verifizieren:**
|
||||
```bash
|
||||
sha512sum --ignore-missing -c SHA512SUMS
|
||||
```
|
||||
Erwartet wird eine `OK`-Zeile für die tatsächlich heruntergeladene ISO. Bei einem Fehler Download und Prüfsummenquelle kontrollieren.
|
||||
|
||||
3. **Bootfähigen USB-Stick erstellen:**
|
||||
* [Ventoy](https://www.ventoy.net) auf dem USB-Stick installieren.
|
||||
* Die heruntergeladene ISO-Datei direkt per Dateimanager auf die Ventoy-Partition kopieren.
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Schritt-für-Schritt Installationsanleitung (Debian Netinst)
|
||||
|
||||
1. **Booten:**
|
||||
* USB-Stick einstecken, System starten und per `F11` das Boot-Menü öffnen.
|
||||
* USB-Stick auswählen -> Im Ventoy-Menü `debian-netinst.iso` wählen -> **Graphical Install** auswählen.
|
||||
|
||||
2. **Lokalisierung:**
|
||||
* **Language:** `German - Deutsch`
|
||||
* **Land/Territorium:** `Deutschland`
|
||||
* **Tastaturlayout:** `Deutsch`
|
||||
|
||||
3. **Netzwerk & Hostname:**
|
||||
* **Hostname:** `ghostnet-ki` (auf dem bestehenden KI-Server am 18.09.2026 per `hostnamectl` bestätigt).
|
||||
* **Domain-Name:** Nur eine tatsächlich konfigurierte lokale Domain eintragen; andernfalls leer lassen. `ghostnet.ki` ist in dieser Dokumentation lediglich ein optionaler SSH-Alias.
|
||||
* **Netzwerk:** Per DHCP konfigurieren lassen. *(Feste IP wird nach der Installation vergeben).*
|
||||
|
||||
4. **Benutzerverwaltung:**
|
||||
* **Root-Passwort:** Starkes Passwort aus dem Passwort-Manager eintragen.
|
||||
* **Neuer Benutzer:**
|
||||
* Vollständiger Name: `Admin`
|
||||
* Benutzername: vor der Installation festlegen. Der bestehende KI-Server verwendet `ghost` als initiales Administrationskonto; `admin` ist dort nicht vorhanden.
|
||||
* Passwort: Sicheres Kennwort vergeben.
|
||||
|
||||
5. **Partitionierung (Manuell / Geführt):**
|
||||
* Methode: `Geführt - gesamte Festplatte verwenden`.
|
||||
* Disk auswählen: `Samsung SSD 970 EVO Plus 2TB`.
|
||||
* Schema: `Alle Dateien auf eine Partition (für Anfänger empfohlen)`.
|
||||
* **Wichtig:** Änderungen auf die Festplatte schreiben -> `Ja`.
|
||||
|
||||
6. **Paketmanager-Konfiguration:**
|
||||
* Spiegelserver-Land: `Deutschland`
|
||||
* `deb.debian.org` wählen.
|
||||
* HTTP-Proxy: Leer lassen.
|
||||
|
||||
7. **Software-Auswahl (Software selection):**
|
||||
* [_] Debian desktop environment *(ABWÄHLEN)*
|
||||
* [_] GNOME / KDE / etc. *(ABWÄHLEN)*
|
||||
* [x] **SSH server** *(AUSWÄHLEN)*
|
||||
* [x] **standard system utilities** *(AUSWÄHLEN)*
|
||||
|
||||
8. **Bootloader (GRUB):**
|
||||
* GRUB-Bootloader in den primären Laufwerksbereich installieren: `Ja`
|
||||
* Gerät wählen: `/dev/nvme0n1` (Samsung SSD).
|
||||
|
||||
9. **Abschluss:**
|
||||
* USB-Stick entfernen und auf `Weiter` klicken, um das System neu zu starten.
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Grundlegende Werkzeuge und Firmware
|
||||
|
||||
Für die AMD-GPUs ist in Debian 13 das Paket [`firmware-amd-graphics`](https://packages.debian.org/trixie/firmware-amd-graphics) aus `non-free-firmware` vorgesehen. Das breitere Metapaket `firmware-linux-nonfree` zieht dieses Paket bereits als Abhängigkeit nach sich und wird für diesen Schritt nicht zusätzlich benötigt. Die folgende Anweisung gehört zu einer Neuinstallation oder zum späteren Ansible-Sprint, nicht zu diesem Dokumentationsabgleich:
|
||||
|
||||
```bash
|
||||
# Vorher prüfen, ob die Debian-Paketquellen die Komponente non-free-firmware enthalten.
|
||||
apt update
|
||||
apt install -y curl wget git htop tmux pciutils firmware-amd-graphics
|
||||
```
|
||||
|
||||
Für Sudo, Netzwerk und SSH mit [GNAI-002](GNAI-002-INFRA_Users.md) fortfahren. Vor Änderungen auf einem laufenden Host die dort dokumentierte Netzverwaltung prüfen.
|
||||
|
||||
---
|
||||
|
||||
## 4. Abnahmekriterien
|
||||
|
||||
Vor der Übergabe an das KI-Team (Phase 2) muss das System folgende Punkte bestehen:
|
||||
|
||||
* **RAM-Check:** `free -h` zeigt mindestens ~62 GB RAM an.
|
||||
* **GPU-Erkennung:** `lspci -nn | grep -Ei 'vga|display|3d'` listet **zwei** AMD-Grafikgeräte auf. Das genaue Kartenmodell anhand des Hardwareinventars oder der Geräte selbst prüfen; die PCI-Familienkennung allein genügt dafür nicht.
|
||||
* **Netzwerk:** Der Server ist nach GNAI-002 unter `10.0.0.90` erreichbar. Die getrennten SSH-Zugänge für `ghost` und `ghost-agent` wurden am 19.09.2026 erfolgreich getestet.
|
||||
* **Storage:** `lsblk -f` zeigt die vorgesehene Partitionierung der 2-TB-SSD; `df -h /` zeigt die nutzbare Dateisystemgröße (in binären Einheiten kleiner als 2 TB).
|
||||
* **Re-Size BAR:** BIOS-Einstellung und zugewiesene PCIe-BAR-Größen getrennt prüfen; ein bloßer `dmesg | grep -i BAR`-Treffer gilt nicht als Funktions- oder Leistungsnachweis.
|
||||
|
||||
---
|
||||
|
||||
## 5. Lesender Teilabgleich des bestehenden Hosts am 18.09.2026
|
||||
|
||||
Per SSH wurden Debian 13.6, Hostname `ghostnet-ki`, Intel Core i5-13600K, 62 GiB nutzbarer RAM und zwei AMD Navi-21-GPUs mit PCI-ID `1002:73bf` beobachtet. `lsblk` zeigt eine 1,8-TiB-NVMe mit EFI-, ext4-Root- und Swap-Partition; `df -h /` zeigte 1,8 TiB Dateisystemgröße. `lspci` bestätigt die Gerätefamilie, aber weder das genaue Kartenmodell noch ROCm-Funktion und ReBAR-Leistung. BIOS-Version, XMP, Firmwarestand und Restore wurden nicht geprüft.
|
||||
@@ -0,0 +1,202 @@
|
||||
# Standard Operating Procedure
|
||||
|
||||
**Dokumenten-ID:** GNAI-002-INFRA
|
||||
**Titel:** Benutzerverwaltung, SSH-Härtung & Netzwerkkonfiguration (Phase 2)
|
||||
**Status:** Betriebsanleitung; tatsächliche Netzverwaltung und Konten vor Anwendung prüfen
|
||||
|
||||
---
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Beschreibung der Änderung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-08-26 | 1.0 | spektr | Erstellung des Dokuments (Benutzer, Netzwerkkonfiguration, SSH-Härtung) |
|
||||
| 2026-09-15 | 1.1 | spektr | Kontenbestand, DNS-Verwaltung und SSH-Dienstnamen präzisiert; doppelte Basisschritte bereinigt. |
|
||||
| 2026-09-16 | 1.2 | spektr | Tatsächliche Konten, Gruppen, Netz- und SSH-Konfiguration sowie Grenzen des Login-Tests dokumentiert. |
|
||||
| 2026-09-18 | 1.3 | spektr | Workstation-spezifische Schlüsselpfade und Host-Fingerprint in den lokalen Arbeitskontext verlagert. |
|
||||
| 2026-09-19 | 1.4 | spektr | Persönlichen Login `ghost` und Agentenlogin `ghost-agent` als erfolgreich getestet dokumentiert. |
|
||||
| 2026-09-20 | 1.5 | spektr / Codex | Deployment- und getrennte rootless Workload-Konten mit festen IDs und Zuständigkeiten ergänzt. |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck und Geltungsbereich
|
||||
|
||||
Dieses Dokument beschreibt Benutzer, statische IP und SSH des KI-Servers. Der ursprüngliche lesende Kontenabgleich vom 18.09.2026 umfasste `ghost`, `debugofen` und `ghost-agent`; `admin` existiert auf diesem Host nicht. Am 19. und 20.09.2026 kamen der Ansible-Deployment-Account sowie drei gesperrte Workload-Konten hinzu. Die folgenden Befehle sind für Neuinstallation oder gezielte Änderung gedacht und ersetzen keine Prüfung des vorhandenen Systems. Der WireGuard-LXC besitzt ein separates Konto `admin`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Voraussetzungen & Berechtigungen
|
||||
|
||||
* Bereits installiertes Debian-Grundsystem gemäß [GNAI-001](GNAI-001-INFRA_BaseSystem.md).
|
||||
* Root-Zugriff oder Benutzer mit `sudo`-Rechten.
|
||||
* Admin-Workstation mit lokal installierter SSH-Suite (`ssh`, `ssh-keygen`); für den bestehenden Host ist die lokale Konsole oder ein bereits berechtigter Zugang zur Schlüsselaufnahme nötig.
|
||||
|
||||
---
|
||||
|
||||
## 3. Prozessbeschreibung
|
||||
|
||||
### 3.1 Benutzerverwaltung & Sudo-Berechtigungen (Server-Seite)
|
||||
|
||||
#### 1. Sudo-Paket installieren & prüfen (falls noch nicht geschehen)
|
||||
|
||||
Als `root` am Server anmelden:
|
||||
|
||||
```bash
|
||||
su -
|
||||
apt update && apt install -y sudo
|
||||
```
|
||||
|
||||
#### 2. Benutzer anlegen & Berechtigungen vergeben
|
||||
|
||||
Vor dem Anlegen prüfen, ob das Konto bereits existiert (`getent passwd <username>`). Konten und Home-Verzeichnisse nur nach Prüfung ihrer Daten und Berechtigungen entfernen.
|
||||
|
||||
Nur bei einer **Neuinstallation** einen vorher festgelegten Administrationsbenutzer anlegen und zur `sudo`-Gruppe hinzufügen. Auf dem bestehenden KI-Server besitzen `ghost` und `debugofen` bereits sudo-Gruppenmitgliedschaft. Das folgende Beispiel mit `ghost` dort nicht ausführen:
|
||||
|
||||
```bash
|
||||
# Nur auf einem neuen System ausführen.
|
||||
sudo adduser ghost
|
||||
sudo usermod -aG sudo ghost
|
||||
```
|
||||
|
||||
Weitere Konten nur nach Rollenentscheidung anlegen. Die sudo-Gruppenmitgliedschaft ist pro Konto ausdrücklich festzulegen; auf dem bestehenden Host keine bereits vorhandenen Konten erneut anlegen.
|
||||
|
||||
Die folgenden technischen Konten werden ausschließlich durch das
|
||||
Ansible-Projekt verwaltet:
|
||||
|
||||
| Konto | UID/GID | Zweck | interaktiver Login / sudo |
|
||||
| --- | --- | --- | --- |
|
||||
| `ansible-deploy` | 1003 | privilegierte Ansible-Ausführung | SSH-Key, gesperrtes Passwort, `NOPASSWD` gemäß eigener sudoers-Regel |
|
||||
| `gnai-production` | 980 | rootless AI Production | gesperrtes Passwort, `/usr/sbin/nologin`, kein sudo |
|
||||
| `gnai-testing` | 981 | rootless AI Testing | gesperrtes Passwort, `/usr/sbin/nologin`, kein sudo |
|
||||
| `gn-encoding` | 982 | rootless CPU-Encoding | gesperrtes Passwort, `/usr/sbin/nologin`, kein sudo |
|
||||
|
||||
Die drei Workload-Konten besitzen nicht überlappende SubUID-/SubGID-Bereiche,
|
||||
eigene Daten- und Podman-Stores sowie persistente systemd-User-Manager. Ihre
|
||||
rootverwalteten Quadlet-Verzeichnisse liegen unter
|
||||
`/etc/containers/systemd/users/<UID>`. Direkte SSH-Schlüssel werden dort nicht
|
||||
hinterlegt.
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Statische Netzwerkkonfiguration (Server-Seite)
|
||||
|
||||
#### 1. Netzschnittstelle ermitteln & anpassen
|
||||
|
||||
Primäre Netzwerkschnittstelle und zuständigen Netzwerkdienst ermitteln (z. B. `enp8s0`):
|
||||
|
||||
```bash
|
||||
ip addr show
|
||||
systemctl is-active networking NetworkManager systemd-networkd dhcpcd
|
||||
```
|
||||
|
||||
Nur falls `ifupdown` den Host tatsächlich verwaltet, `/etc/network/interfaces` bearbeiten. Bei NetworkManager, systemd-networkd oder dhcpcd deren Konfiguration verwenden; die Schnittstelle darf nicht von mehreren Diensten zugleich verwaltet werden.
|
||||
|
||||
```bash
|
||||
sudo nano /etc/network/interfaces
|
||||
```
|
||||
|
||||
Netzwerkkonfiguration für statische IP eintragen:
|
||||
|
||||
```text
|
||||
# Loopback Interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# Primary Network Interface
|
||||
allow-hotplug enp8s0
|
||||
iface enp8s0 inet static
|
||||
address 10.0.0.90/24
|
||||
gateway 10.0.0.1
|
||||
dns-nameservers 10.0.0.1 1.1.1.1
|
||||
```
|
||||
|
||||
#### 2. DNS-Resolver prüfen
|
||||
|
||||
`/etc/resolv.conf` kann von einem Netzwerk- oder Resolverdienst erzeugt werden. Den aktiven Dienst und die wirksamen Nameserver prüfen (`readlink -f /etc/resolv.conf`, `cat /etc/resolv.conf`); Änderungen in dessen Konfiguration vornehmen. Die aktuelle Solladresse des Heimnetz-DNS ist `10.0.0.1`.
|
||||
|
||||
#### 3. Netzwerkdienst neustarten & Funktion prüfen
|
||||
|
||||
```bash
|
||||
sudo systemctl restart networking # nur bei ifupdown und mit Konsolenzugang
|
||||
ip -4 addr
|
||||
ping -c 4 google.com
|
||||
```
|
||||
|
||||
Vor einem Remote-Neustart einen Rückweg über Konsole/Proxmox sicherstellen. Ein Reboot behebt keine widersprüchliche Netzkonfiguration.
|
||||
|
||||
---
|
||||
|
||||
### 3.3 SSH-Schlüssel und getrennte Konten
|
||||
|
||||
Für persönliche und automatisierte Zugriffe getrennte Konten und klar benannte Schlüsselpaare verwenden. Auf dem bestehenden KI-Server sind `ghost` und `ghost-agent` getrennt; `ghost-agent` hat keine sudo-Gruppenmitgliedschaft. Schlüsseldateien, lokale SSH-Aliase und der auf dieser Workstation bekannte Hostschlüssel-Fingerprint sind nur im lokalen, nicht versionierten Arbeitskontext vermerkt. Private Schlüssel und Passphrasen gehören weder in diese Dokumentation noch in ein Serverinventar. Ein Kommentar wie `@ghostnet-ki` im Public Key ist nur ein Label; die Zuordnung erfolgt über den Schlüsselinhalt und das jeweilige `authorized_keys`.
|
||||
|
||||
Neue öffentliche Schlüssel auf dem bestehenden Host über eine bereits berechtigte Sitzung oder die lokale Konsole in das **richtige Konto** unter `~/.ssh/authorized_keys` eintragen; bestehende Schlüssel dabei erhalten. Verzeichnis auf `700`, Datei auf `600` und Eigentümer auf das Zielkonto setzen. Passwort-SSH ist bereits deaktiviert, daher ist `ssh-copy-id` ohne bestehenden Schlüsselzugang hier kein Wiederherstellungsverfahren.
|
||||
|
||||
Vor Erstverbindung den Hostschlüssel-Fingerprint aus einer vertrauenswürdigen Konsole abgleichen. Die lokalen SSH-Aliase müssen auf `10.0.0.90`, das jeweils richtige Konto und Schlüsseldatei zeigen; `IdentitiesOnly yes` und strikte Hostschlüsselprüfung verwenden. Die folgenden Beispiele setzen entsprechend eingerichtete Aliase auf der Admin-Workstation voraus:
|
||||
|
||||
```bash
|
||||
ssh ghostnet-ai-ghost 'id -un; hostnamectl --static'
|
||||
ssh ghostnet-ai-agent 'id -un; hostnamectl --static'
|
||||
```
|
||||
|
||||
Für `ghost` ist auf der aktuellen Workstation eine Passphrase-Eingabe am Terminal erforderlich, sofern der Schlüssel nicht bereits im SSH-Agenten entsperrt wurde. Beide Profile sind getestet: `ghost-agent` wurde am 19.09.2026 erneut technisch geprüft; der Betreiber bestätigte am selben Tag den erfolgreichen interaktiven Login als `ghost`.
|
||||
|
||||
---
|
||||
|
||||
### 3.4 SSH-Dienst härten (Server-Seite)
|
||||
|
||||
Nur auf einem **neu eingerichteten System** nach erfolgreichem SSH-Key-Test die Passwort-Authentifizierung deaktivieren. Auf dem bestehenden KI-Server ist das folgende Drop-in bereits vorhanden; es wurde am 18.09.2026 lesend geprüft.
|
||||
|
||||
#### 1. Drop-in-Konfiguration für SSH erstellen
|
||||
|
||||
```bash
|
||||
sudo nano /etc/ssh/sshd_config.d/99-security.conf
|
||||
```
|
||||
|
||||
Den folgenden Inhalt einfügen:
|
||||
|
||||
```text
|
||||
# Root-Login über SSH komplett verbieten
|
||||
PermitRootLogin no
|
||||
|
||||
# Passwort-Authentifizierung deaktivieren (nur SSH-Keys erlauben)
|
||||
PasswordAuthentication no
|
||||
KbdInteractiveAuthentication no
|
||||
|
||||
# Leere Passwörter verbieten
|
||||
PermitEmptyPasswords no
|
||||
|
||||
# Nur explizite SSH-Key Methoden erlauben
|
||||
PubkeyAuthentication yes
|
||||
```
|
||||
|
||||
#### 2. SSH-Konfiguration prüfen und Dienst neustarten
|
||||
|
||||
> **Achtung:** Die bestehende SSH-Sitzung **nicht** schließen, bevor der Login in einem zweiten Terminalfenster erfolgreich verifiziert wurde!
|
||||
|
||||
```bash
|
||||
# Syntaktische Prüfung der Konfiguration
|
||||
sudo sshd -t
|
||||
|
||||
# Wenn sshd -t keine Fehler ausgibt, Dienst neustarten
|
||||
sudo systemctl restart ssh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Abnahmekriterien (Checkliste für den Junior-Admin)
|
||||
|
||||
* [ ] **Benutzerprüfung:** `ghost` und `debugofen` können ihre vorgesehenen sudo-Rechte nutzen; `ghost-agent` bleibt ohne sudo-Zuweisung.
|
||||
* [x] **Workload-Konten:** `gnai-production`, `gnai-testing` und `gn-encoding` besitzen getrennte rootless Podman-Stores und aktive persistente User-Manager; geprüft am 20.09.2026.
|
||||
* [ ] **Netzwerk:** Server ist unter der statischen IP `10.0.0.90` erreichbar. Ausgehender Datenverkehr funktioniert (`ping google.com`).
|
||||
* [x] **SSH-Aliase:** `ghostnet-ai-ghost` meldet `ghost`, `ghostnet-ai-agent` meldet `ghost-agent`. Beide Zugänge wurden am 19.09.2026 bestätigt. Die Passphrase des persönlichen Schlüssels ist keine Server-Passwortanmeldung.
|
||||
* [ ] **Root-Sperre:** Direct-Login als Root per SSH wird abgelehnt (`ssh root@10.0.0.90` -> *Permission denied*).
|
||||
* [ ] **Passwort-Sperre:** Login-Versuch ohne hinterlegten SSH-Key wird direkt abgelehnt (keine Passwort-Aufforderung mehr).
|
||||
|
||||
---
|
||||
|
||||
## 5. Lesender Ist-Abgleich am 18.09.2026
|
||||
|
||||
`ghost` (UID 1000) und `debugofen` (UID 1001) gehören zur Gruppe `sudo`; `ghost-agent` (UID 1002) gehört nicht dazu. Der technische Login als `ghost-agent` und der vom Betreiber interaktiv geprüfte Login als `ghost` funktionieren mit ihren jeweils eigenen Schlüsseln. Die Prüfung belegt die Kontentrennung und den Schlüsselzugang, aber keine noch offenen sudo-, Root-Sperr- oder Negativtests.
|
||||
|
||||
`enp8s0` hat `10.0.0.90/24`, die Default-Route führt über `10.0.0.1`. `networking` und `ssh` sind aktiv und aktiviert. `/etc/network/interfaces` enthält die statische Konfiguration; `/etc/resolv.conf` nennt `10.0.0.1` und `1.1.1.1` und trägt einen dhcpcd-Generierungskommentar. Ein aktuell laufender `dhcpcd`-Dienst wurde nicht beobachtet; vor Resolveränderungen die tatsächliche Verwaltung erneut prüfen. Das SSH-Drop-in deaktiviert Root-, Passwort- und Keyboard-Interactive-Anmeldung und aktiviert Public-Key-Anmeldung.
|
||||
@@ -0,0 +1,300 @@
|
||||
# Security & Access Control Specification
|
||||
|
||||
**Dokumenten-ID:** GNAI-004-SEC
|
||||
**Titel:** Homelab / LLM-Infrastruktur – Sicherheits-, Authentifizierungs- und Zugriffskonzept
|
||||
**Status:** Verbindliches Zielmodell; technische Durchsetzung teilweise offen
|
||||
**Vorgänger / Referenzen:** [Architektur](../ai/GNAI-003-INFRA_Architecture.md), [Gateway](GNAI-006-SEC_VPN.md), [GUI-SOP](GNAI-006-SEC_VPN_Client-Management.md), [Reverse Proxy](GNAI-005-SEC_Reverse-Proxy.md)
|
||||
|
||||
---
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Beschreibung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-08-28 | 1.0 | spektr | Erstellung des Sicherheits- und Zugriffskonzepts. |
|
||||
| 2026-09-15 | 1.1 | spektr | Familie, Server Admin und LLM Admin getrennt; serverseitige Zielrechte, NAT und Umsetzungsdefizite dokumentiert; OIDC-Ist präzisiert. |
|
||||
| 2026-09-16 | 1.2 | spektr | Fail2Ban-Pin `1.1.0-r2-ls43` und wieder laufenden Container als Ist-Stand übernommen; technische Abnahme bleibt in GNAI-005 geführt. |
|
||||
| 2026-09-18 | 1.3 | spektr | KI-Anwendungsdienste als Zielbild und bestehende Fail2Ban-Jails als dokumentierten Ist-Stand eingeordnet. |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck
|
||||
|
||||
Dieses Dokument definiert das verbindliche Zugriffs- und Authentifizierungsmodell für die öffentlich und intern erreichbaren Komponenten der Ghostnet-Infrastruktur.
|
||||
|
||||
Das Modell trennt bewusst:
|
||||
|
||||
- **Netzwerkzugang** über WireGuard,
|
||||
- **Benutzeridentität** über Keycloak/OIDC,
|
||||
- **Maschinen-/API-Zugriff** über API-Keys bzw. anwendungsbezogene Credentials,
|
||||
- **SSH-Administration** über SSH Public Keys.
|
||||
|
||||
Ziel ist Least Privilege bei gleichzeitig überschaubarer Administration.
|
||||
|
||||
---
|
||||
|
||||
## 2. Rollenmodell
|
||||
|
||||
### 2.1 Familie
|
||||
|
||||
Familienmitglieder (Betreiber und Bruder) dürfen das gesamte Heimnetz `10.0.0.0/24` einschließlich gewöhnlicher PCs und Clients erreichen. Das ist eine bewusste Vollzugriffsentscheidung für die Netzwerkebene. Proxmox, SSH und andere Anwendungen behalten eigene Authentifizierung und Autorisierung. Zugriff auf wg-easy und NPM-Administration ist vorgesehen.
|
||||
|
||||
### 2.2 Server Admin
|
||||
|
||||
Server Admins dürfen Proxmox `10.0.0.2`, aktuelle Service-LXCs und KI-Server `10.0.0.90` erreichen. NPM und wg-easy zählen zu den Service-LXCs. Allgemeine Heimnetz-PCs/Clients gehören nicht zu dieser Freigabe. Serverseitig eine Liste bestätigter Hosts pflegen; der statische Adressbereich bis `.99` ist keine pauschale Zugriffsfreigabe.
|
||||
|
||||
### 2.3 LLM Admin
|
||||
|
||||
LLM Admins dürfen ausschließlich KI-Server `10.0.0.90` erreichen. Proxmox, andere Service-LXCs, wg-easy/NPM und gewöhnliche Heimnetz-PCs sind gesperrt. Netzwerkzugriff auf den Host ersetzt keine SSH-/Anwendungsrechte. SSH bleibt schlüsselbasiert, ohne Passwort- oder Root-Login.
|
||||
|
||||
Die drei Gruppen sind VPN-Netzwerkrollen. Alte Full-Admin-Peers müssen ausdrücklich Familie oder Server Admin zugeordnet werden. Jeder Peer gehört zu einem einzelnen Gerät und einer dokumentierten Rolle.
|
||||
|
||||
### 2.4 LLM User (Anwendungsrolle)
|
||||
|
||||
Kein privilegierter Netzwerkzugang.
|
||||
|
||||
**Zugang:**
|
||||
|
||||
HTTPS über NPM zur LiteLLM-API.
|
||||
|
||||
**Authentifizierung:**
|
||||
|
||||
- API-Key
|
||||
|
||||
**Erlaubt:**
|
||||
|
||||
- Nutzung der von LiteLLM freigegebenen Modelle / Endpunkte
|
||||
- Nutzung nach den für den Benutzer gesetzten Quoten und Policies
|
||||
|
||||
**Nicht erlaubt:**
|
||||
|
||||
- SSH
|
||||
- Zugriff auf den LLM-Server allgemein
|
||||
- Zugriff auf `llama.cpp` direkt
|
||||
- Zugriff auf Proxmox
|
||||
- Zugriff auf andere interne Services
|
||||
|
||||
Ein normaler LLM User erhält **keinen WireGuard-Peer**, sofern für einen konkreten Anwendungsfall kein zusätzlicher privilegierter Zugriff erforderlich ist.
|
||||
|
||||
---
|
||||
|
||||
## 3. Zugriffsmatrix
|
||||
|
||||
| Ziel | Familie | Server Admin | LLM Admin | LLM User / öffentlich |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Heimnetz-PCs / DHCP-Clients | erlaubt | gesperrt | gesperrt | gesperrt |
|
||||
| Proxmox UI/SSH | erlaubt + Dienstauthentifizierung | erlaubt + Dienstauthentifizierung | gesperrt | gesperrt |
|
||||
| Service-LXCs / NPM / wg-easy | erlaubt + Dienstauthentifizierung | erlaubt + Dienstauthentifizierung | gesperrt | nur veröffentlichte Anwendungen |
|
||||
| KI-Server SSH/Management | erlaubt + Dienstauthentifizierung | erlaubt + Dienstauthentifizierung | erlaubt + Dienstauthentifizierung | gesperrt |
|
||||
| Keycloak Administration | intern, nach Dienstberechtigung | intern, nach Dienstberechtigung | gesperrt | Soll: gesperrt; Ist: öffentlich erreichbar |
|
||||
| benötigte OIDC-Endpunkte | anwendungsbezogen | anwendungsbezogen | anwendungsbezogen | öffentlich für Login |
|
||||
| LiteLLM API | nach API-Policy | nach API-Policy | nach API-Policy | Soll: HTTPS + individueller API-Key |
|
||||
| OpenWebUI / weitere Webanwendungen | nach Anwendungsrechten | nach Anwendungsrechten | nach Anwendungsrechten | Soll: HTTPS und geeignete Anmeldung |
|
||||
| llama.cpp / Datenbanken | nur nach Backend-/Dienstpolicy | nur nach Backend-/Dienstpolicy | nur KI-Server-bezogen nach Bedarf | nicht direkt öffentlich |
|
||||
|
||||
Das ist die Sollmatrix. Per-Client Firewall ist aktuell deaktiviert; Keycloak-Admin-Exposure ist durch einen externen Betreiber-Test bestätigt. Keine Sollfreigabe wird damit als bereits sicher implementiert behauptet.
|
||||
|
||||
---
|
||||
|
||||
## 4. Authentifizierungsmodell
|
||||
|
||||
### 4.1 WireGuard
|
||||
|
||||
WireGuard authentifiziert Peers kryptografisch über Public-/Private-Key-Paare.
|
||||
|
||||
Es besteht keine Kopplung zwischen WireGuard-Peer-Authentifizierung und Keycloak.
|
||||
|
||||
Grund:
|
||||
|
||||
- WireGuard kontrolliert **Netzwerkzugang**
|
||||
- Keycloak kontrolliert **Benutzer-/Anwendungsidentität**
|
||||
|
||||
Diese Trennung ist beabsichtigt.
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Keycloak / OIDC
|
||||
|
||||
Keycloak ist die zentrale Identitätsquelle für webbasierte Benutzeranwendungen.
|
||||
|
||||
Ziel:
|
||||
|
||||
Benutzer melden sich an der zentralen Keycloak-Identitätsquelle an. Die vorgesehenen Anwendungen binden diese per OIDC ein.
|
||||
|
||||
Administrative Keycloak-Funktionen müssen auf interne berechtigte Zugriffe beschränkt werden. Ist: externe Admin-Anmeldung möglich, Korrektur in GNAI-005 dokumentiert. Laut Betreiber wird OIDC produktiv nur für Vaultwarden genutzt; Nextcloud, Gitea, OpenWebUI und weitere Dienste sind geplant.
|
||||
|
||||
---
|
||||
|
||||
### 4.3 LiteLLM API
|
||||
|
||||
Die LLM-API ist ein anwendungsbezogener Dienst und wird deshalb nicht durch einen allgemeinen LAN-/VPN-Zugang für normale Benutzer bereitgestellt.
|
||||
|
||||
Ziel:
|
||||
|
||||
Der Client erreicht LiteLLM per HTTPS über NPM; LiteLLM nutzt intern llama.cpp.
|
||||
|
||||
Die Autorisierung erfolgt über API-Keys.
|
||||
|
||||
API-Keys sollen:
|
||||
|
||||
- individuell pro Benutzer bzw. Anwendung vergeben werden,
|
||||
- widerrufbar sein,
|
||||
- nach Möglichkeit mit Quoten / Rate Limits verbunden werden,
|
||||
- nicht als Ersatz für privilegierten Netzwerkzugriff dienen.
|
||||
|
||||
---
|
||||
|
||||
### 4.4 SSH
|
||||
|
||||
SSH wird auf dem LLM-Server schlüsselbasiert betrieben.
|
||||
|
||||
Zusätzliche Schutzschicht:
|
||||
|
||||
WireGuard-Zielberechtigung und eigener SSH-Public-Key-Login.
|
||||
|
||||
Passwort- und Root-Login über SSH bleiben deaktiviert.
|
||||
|
||||
---
|
||||
|
||||
## 5. Netzwerk-Autorisierung
|
||||
|
||||
Familie erhält ausdrücklich Heimnetz-Vollzugriff. Server Admins und LLM Admins erhalten nur die beschlossenen Zielhosts. Die **serverseitigen Firewall Allowed IPs** in wg-easy sollen diese Rechte durchsetzen, während clientseitige Allowed IPs nur Routing festlegen. Ein Benutzer darf die Serverbeschränkung nicht durch Änderungen an seinem lokalen Profil umgehen können. Für Gateway-eigene Dienste wird die INPUT-Chain separat geprüft und anhand zugeordneter VPN-Quellen begrenzt.
|
||||
|
||||
Aktuell fehlt die Per-Client-Durchsetzung. Negative Tests müssen mit absichtlich erweitertem Client-Routing und aktivem Zielservice stattfinden. Normale LLM-Anwendungsnutzer erhalten keinen Managementpeer. Geräteprofile werden durch Administratoren erstellt und geschützt verteilt. Die GUI ist für Familie und Server Admins vorgesehen.
|
||||
|
||||
MASQUERADE wird mangels Rückroute verwendet; es verbirgt gegenüber LAN-Diensten die ursprüngliche Peer-IP. Zielkontrolle muss daher am VPN-Gateway vor NAT erfolgen. Lokale LAN-Quellen lassen sich nicht allein durch die VPN-Rolle gruppengenau zuordnen; hierfür sind zusätzliche Regeln/Identitäten nötig.
|
||||
|
||||
---
|
||||
|
||||
## 6. Vorgesehene öffentliche und private Erreichbarkeit
|
||||
|
||||
Die folgende Einordnung ist das Zielmodell. LiteLLM und die Webanwendungen auf dem KI-Server werden erst im späteren Ansible-Sprint eingerichtet.
|
||||
|
||||
### Öffentlich
|
||||
|
||||
- HTTP/HTTPS auf NPM
|
||||
- für den VPN-Betrieb: WireGuard UDP-Port
|
||||
- OIDC-Endpunkte, soweit für Web-Login erforderlich
|
||||
- LiteLLM API über HTTPS
|
||||
- öffentliche Webanwendungen
|
||||
|
||||
### Privat
|
||||
|
||||
- Proxmox Management
|
||||
- SSH
|
||||
- NPM Admin
|
||||
- Keycloak Admin
|
||||
- `llama.cpp`
|
||||
- interne Datenbanken
|
||||
- interne Serviceports
|
||||
- Podman-/Container-Management
|
||||
- sonstige Infrastruktur-Interfaces
|
||||
|
||||
---
|
||||
|
||||
## 7. Fail2Ban-Rolle
|
||||
|
||||
Fail2Ban ist ein ergänzender Schutzmechanismus für die öffentliche NPM-Schicht.
|
||||
|
||||
Es soll insbesondere:
|
||||
|
||||
- eindeutige Scanner-/Exploit-Muster,
|
||||
- wiederholte Missbrauchsmuster,
|
||||
- geeignete Authentifizierungsangriffe
|
||||
|
||||
erkennen und dynamisch blockieren.
|
||||
|
||||
Nicht vorgesehen ist ein pauschales Blocking aller HTTP-Fehlercodes.
|
||||
|
||||
Insbesondere soll ein allgemeiner `404` nicht automatisch als Angriff gewertet werden.
|
||||
|
||||
Die vorhandenen NPM-Jails sind in [GNAI-005](GNAI-005-SEC_Reverse-Proxy.md) dokumentiert. Ihre Funktion nach dem Image-Pin sowie Neustart und Wiederanlauf müssen noch abgenommen werden.
|
||||
|
||||
---
|
||||
|
||||
## 8. Weitere Schutzmaßnahmen
|
||||
|
||||
Das Zugriffskonzept setzt zusätzlich voraus:
|
||||
|
||||
### Perimeter
|
||||
|
||||
- keine unnötigen Portweiterleitungen
|
||||
- IPv4-/IPv6-Exposure gleichwertig prüfen
|
||||
- keine direkte Veröffentlichung von Managementports
|
||||
|
||||
### Identität
|
||||
|
||||
- MFA für privilegierte Accounts
|
||||
- vorzugsweise WebAuthn/FIDO2, wo sinnvoll
|
||||
- individuelle Accounts statt gemeinsam genutzter Konten
|
||||
|
||||
### Systeme
|
||||
|
||||
- zeitnahes Patchmanagement
|
||||
- minimale installierte Dienste
|
||||
- minimale Container-/LXC-Capabilities
|
||||
- unprivileged LXCs, wo technisch möglich
|
||||
|
||||
### Recovery
|
||||
|
||||
- getrennte Backups
|
||||
- Schutz gegen versehentliches oder böswilliges Löschen
|
||||
- regelmäßige Restore-Tests
|
||||
|
||||
### Monitoring
|
||||
|
||||
- Uptime-/Health-Monitoring
|
||||
- regelmäßige Überprüfung der extern sichtbaren Ports und Dienste
|
||||
- Überwachung sicherheitsrelevanter Logs
|
||||
|
||||
---
|
||||
|
||||
## 9. Grundprinzip für zukünftige Services
|
||||
|
||||
Neue Services sind nach folgendem Entscheidungsmodell einzuordnen:
|
||||
|
||||
### Ist es ein öffentlicher Benutzer-/Anwendungsdienst?
|
||||
|
||||
→ HTTPS über NPM
|
||||
→ OIDC/Keycloak oder anwendungsspezifische Authentifizierung
|
||||
|
||||
### Ist es ein privilegierter Managementdienst?
|
||||
|
||||
→ nicht öffentlich
|
||||
→ Zugriff über WireGuard
|
||||
→ zusätzliche Dienstauthentifizierung
|
||||
|
||||
### Ist es ein Backend?
|
||||
|
||||
→ keine Internet-Exposure
|
||||
→ Zugriff ausschließlich von den benötigten internen Komponenten
|
||||
|
||||
### Ist es eine Maschinen-API?
|
||||
|
||||
→ HTTPS über NPM, wenn extern erforderlich
|
||||
→ API-Key oder geeignetes OAuth2-/Client-Credentials-Modell
|
||||
→ Rate Limits / Quotas
|
||||
|
||||
---
|
||||
|
||||
## 10. Sicherheitsziel
|
||||
|
||||
Die Zielarchitektur soll sicherstellen, dass ein kompromittierter Bestandteil möglichst nicht automatisch zu einem vollständigen Infrastrukturzugriff führt.
|
||||
|
||||
Beispiele:
|
||||
|
||||
| Ereignis / Berechtigung | darf keinen automatischen Zugriff geben auf |
|
||||
| --- | --- |
|
||||
| kompromittiertes Webkonto | Proxmox |
|
||||
| gestohlener API-Key | SSH |
|
||||
| kompromittierter LLM-Container | WireGuard-Administration |
|
||||
| LLM-Admin-Peer | Proxmox-Netzwerkzugang |
|
||||
| öffentliche NPM-Verbindung | direkte interne Backendports |
|
||||
|
||||
Das Sicherheitsmodell basiert damit nicht auf einem einzelnen „Security-Programm“, sondern auf der Kombination mehrerer voneinander unabhängiger Kontrollen.
|
||||
|
||||
---
|
||||
|
||||
## 11. Umsetzungsnachweise
|
||||
|
||||
Dieses Dokument definiert die Zugriffsziele. Der [Dokumentationsindex](../GNAI-000-DOC_Index.md) bündelt den aktuellen Projektstand. Konkrete Gateway-Regeln und Rollentests stehen in [GNAI-006](GNAI-006-SEC_VPN.md), der Keycloak-Adminpfad und Fail2Ban in [GNAI-005](GNAI-005-SEC_Reverse-Proxy.md). Offene Zielrechte gelten bis zu ihrer technischen Abnahme nicht als durchgesetzt.
|
||||
@@ -0,0 +1,422 @@
|
||||
# Betriebs- und Sicherheitsdokumentation – Reverse Proxy
|
||||
|
||||
**Dokumenten-ID:** GNAI-005-SEC
|
||||
**Titel:** Reverse Proxy und Fail2Ban – Konfiguration, Betrieb und Sicherheitsabnahme
|
||||
**Status:** NPM aktiv; Fail2Ban laut Betreiber fest gepinnt und wieder in Betrieb; Keycloak-Admin-Exposure bestätigt, Korrektur offen
|
||||
**Vorgänger / Referenzen:** [Architektur](../ai/GNAI-003-INFRA_Architecture.md), [Zugriffskonzept](GNAI-004-SEC_Access-Control.md), [WireGuard](GNAI-006-SEC_VPN.md)
|
||||
|
||||
---
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Beschreibung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-08-28 | 0.1 | spektr | Erstellung der ersten Baseline-Drafts. |
|
||||
| 2026-09-05 | 0.9 | spektr | Implementierung Fail2Ban Container & Test-Setup (F2B-01). |
|
||||
| 2026-09-07 | 1.0 | spektr | Korrektur Action-Syntax (`port="80,443"`), Behebung RegEx-Fehler (`npm-badbots`), E2E-Validierung in nftables abgeschlossen (F2B-02). Finales SOP erstellt. |
|
||||
| 2026-09-14 | 1.1 | spektr | Proxmox-Host-Version auf PVE 9.2.11 aktualisiert (Host-Update). |
|
||||
| 2026-09-15 | 1.2 | spektr | Version/Tabellen korrigiert; bestätigte Keycloak-Exposure und TLS-Widerspruch dokumentiert; Korrekturverfahren, Fail2Ban-Upgrade/Pin und bewusste HTTP-Client-Sperren ergänzt. |
|
||||
| 2026-09-16 | 1.3 | spektr | Fail2Ban-Image auf `1.1.0-r2-ls43` fest gepinnt; wieder laufenden Container bestätigt; verbleibende Funktions- und Wiederanlauftests getrennt ausgewiesen. |
|
||||
| 2026-09-18 | 1.4 | spektr | Wirkung der LAN-Freigaben auf VPN-Verkehr hinter MASQUERADE unmittelbar an der Port-Matrix erläutert. Zweck als Betriebs- und Sicherheitsdokumentation geklärt; veraltete Image-Digests aus dem Verfahren entfernt. |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck & Geltungsbereich
|
||||
|
||||
Dieses Dokument hält Konfiguration, Betrieb und Sicherheitsabnahme des zentralen Reverse Proxy und des logbasierten Fail2Ban auf Proxmox LXC 103 (`reverse-proxy`) fest. Angaben zum laufenden Zustand beruhen auf den jeweils datierten Betreiberbestätigungen und Tests; eine neue Live-Prüfung von CT 103 fand bei dieser Revision nicht statt.
|
||||
|
||||
**Umfang dieses Dokuments:**
|
||||
|
||||
* Betrieb von Nginx Proxy Manager (NPM) als zentraler Ingress-Controller
|
||||
* Containerisiertes Fail2Ban für logbasierte temporäre Sperren mit nftables-Integration auf dem LXC; kein allgemeines Netzwerk-IPS
|
||||
* Log-Parsing-Regeln und Filterdefinitionen für das NPM-spezifische Access-Log-Format
|
||||
* Gehärtete Firewall-Baseline und Zugriffssteuerung
|
||||
|
||||
---
|
||||
|
||||
## 2. System-Baseline (LXC 103)
|
||||
|
||||
| Parameter | Wert |
|
||||
| --- | --- |
|
||||
| Container-ID | CT 103 |
|
||||
| Hostname | `reverse-proxy` |
|
||||
| Betriebssystem | Debian GNU/Linux 13 (Trixie) |
|
||||
| Unprivileged | Ja |
|
||||
| Cores / RAM / Swap | 2 Cores / 1024 MB RAM / 512 MB Swap |
|
||||
| RootFS | 8 GB |
|
||||
| Netzwerkkonfiguration | `10.0.0.10/24`, Gateway `10.0.0.1`, Bridge `vmbr0` |
|
||||
| LXC Features | `nesting=1`, `keyctl=1` |
|
||||
| Proxmox Host | Proxmox VE 9.2.11 |
|
||||
|
||||
*Hinweis zur Proxmox-Firewall:* Laut bisheriger Implementierungsdokumentation sind Proxmox Cluster- und Node-Firewalls deaktiviert (`enable 0`); bei Änderungen den tatsächlichen Zustand prüfen. Die dokumentierte Filter-Baseline liegt lokal im LXC unter `nftables`. Effektive Regeln und weitere Netfilter-Tabellen vor Änderungen live prüfen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Netzwerk- & Firewall-Architektur (nftables)
|
||||
|
||||
Die lokale Paketfilterung basiert auf `nftables` mit einer strikten `INPUT policy drop`-Doktrin.
|
||||
|
||||
```nftables
|
||||
table inet filter {
|
||||
chain input {
|
||||
type filter hook input priority filter; policy drop;
|
||||
iifname "lo" accept
|
||||
ct state invalid drop
|
||||
ct state established,related accept
|
||||
ip protocol icmp accept
|
||||
ip saddr 10.0.0.0/24 tcp dport { 22, 81 } accept
|
||||
tcp dport { 80, 443 } accept
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority filter; policy accept;
|
||||
}
|
||||
|
||||
chain output {
|
||||
type filter hook output priority filter; policy accept;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Port-Matrix
|
||||
|
||||
| Port | Protokoll | Zweck | Erreichbarkeit |
|
||||
| --- | --- | --- | --- |
|
||||
| 80 | TCP | HTTP Ingress (NPM) | Öffentlich |
|
||||
| 443 | TCP | HTTPS Ingress (NPM) | Öffentlich |
|
||||
| 81 | TCP | NPM Web Admin Interface | Nur LAN (`10.0.0.0/24`) |
|
||||
| 22 | TCP | OpenSSH Management | Nur LAN (`10.0.0.0/24`) |
|
||||
| 3000 | TCP | NPM Node.js Backend | Intern / Nicht exponiert |
|
||||
|
||||
`10.0.0.0/24` in den Freigaben für 22/81 umfasst auch die Gateway-Adresse `10.0.0.15`. Durch das aktuelle VPN-MASQUERADE erscheinen VPN-Clients bei NPM unter dieser Adresse. Die Port-Matrix beschreibt deshalb **keine** bereits wirksame VPN-Rollentrennung; diese muss am Gateway vor NAT umgesetzt und getestet werden.
|
||||
|
||||
---
|
||||
|
||||
## 4. Container-Infrastruktur (Podman Quadlets)
|
||||
|
||||
Nginx Proxy Manager und Fail2Ban werden als rootful Podman-Container via systemd Quadlets mit `Network=host` betrieben.
|
||||
|
||||
### 4.1 Nginx Proxy Manager Quadlet
|
||||
|
||||
* **Datei:** `/etc/containers/systemd/nginx-proxy-manager.container`
|
||||
* **Image:** `docker.io/jc21/nginx-proxy-manager:2.11.1` *(ausdrücklich gepinnt)*
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nginx Proxy Manager
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=docker.io/jc21/nginx-proxy-manager:2.11.1
|
||||
ContainerName=nginx-proxy-manager
|
||||
Network=host
|
||||
Volume=/opt/nginx-proxy-manager/data:/data:rw
|
||||
Volume=/opt/nginx-proxy-manager/letsencrypt:/etc/letsencrypt:rw
|
||||
Environment=DISABLE_IPV6=true
|
||||
Environment=TZ=Europe/Berlin
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### 4.2 Fail2Ban IPS Quadlet
|
||||
|
||||
* **Datei:** `/etc/containers/systemd/fail2ban.container`
|
||||
* **Image, aktueller Ist-Stand:** `lscr.io/linuxserver/fail2ban:1.1.0-r2-ls43` *(fest gepinnt)*. Der Betreiber bestätigt, dass der Container nach der Umstellung wieder läuft. Der Image-Build enthält Fail2Ban 1.1.0; der Build-Suffix `r2-ls43` bezeichnet den LinuxServer-Image-Stand.
|
||||
* **Capabilities:** `NET_ADMIN`, `NET_RAW` *(kein `--privileged`)*
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Fail2Ban
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=lscr.io/linuxserver/fail2ban:1.1.0-r2-ls43
|
||||
ContainerName=fail2ban
|
||||
Network=host
|
||||
AddCapability=NET_ADMIN
|
||||
AddCapability=NET_RAW
|
||||
Volume=/opt/fail2ban/config:/config:rw
|
||||
Volume=/opt/nginx-proxy-manager/data/logs:/remotelogs/npm:ro
|
||||
Environment=TZ=Europe/Berlin
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. NPM Logformat & Parsing-Regeln
|
||||
|
||||
NPM nutzt ein eigenes Access-Log-Format, bei dem die eigentliche Client-IP nicht am Zeilenanfang steht.
|
||||
|
||||
**Beispielzeile:**
|
||||
|
||||
```text
|
||||
[03/Sep/2026:18:35:02 +0200] - 204 204 - POST https jellyfin.ghostnet.selfhost.eu "/Sessions/Playing/Progress" [Client 93.228.100.74] [Length 0] [Gzip -] [Sent-to 10.0.0.11] "JellyfinDesktop/2.0.0" "-"
|
||||
```
|
||||
|
||||
**Verbindliche Parser-Regeln:**
|
||||
|
||||
1. Die Client-IP muss zwingend aus dem Feld `[Client <HOST>]` extrahiert werden.
|
||||
2. URL-Pfade oder Host-Header dürfen nicht fälschlicherweise als IP-Quelle interpretiert werden.
|
||||
3. Statuscodes oder Response-Zeiten sind für automatisches Banning ungeeignet, da legitim nicht erreichbare Backends (502) False Positives auslösen würden.
|
||||
|
||||
---
|
||||
|
||||
## 6. Fail2Ban-Konfiguration & Jails
|
||||
|
||||
LinuxServer.io nutzt `/config/fail2ban/` als interne Konfigurationsstruktur. Sämtliche Konfigurationen liegen persistent auf dem Host unter `/opt/fail2ban/config/fail2ban/`.
|
||||
|
||||
### 6.1 Wichtige Erkenntnis zur Action-Syntax
|
||||
|
||||
Standardmäßig nutzt die Action `nftables-multiport` bei fehlenden Parametern Port 22 (SSH). **Sperrports müssen zwingend direkt in der `action`-Zeile des Jails in eckigen Klammern übergeben werden**, um Anfragen auf HTTP/HTTPS durchzusetzen:
|
||||
|
||||
```ini
|
||||
action = nftables-multiport[port="80,443", protocol=tcp]
|
||||
```
|
||||
---
|
||||
|
||||
### 6.2 Jail 1: Exploit & Scanner Protection (`npm-scanner`)
|
||||
|
||||
Gezielte Blockade von Pfad-Traversal-Versuchen, Secret-Abfragen und automatisierten Framework-Scans.
|
||||
|
||||
* **Filter:** `/opt/fail2ban/config/fail2ban/filter.d/npm-scanner.conf`
|
||||
|
||||
```ini
|
||||
[Definition]
|
||||
failregex = ^\[.*\] - [0-9]{3} [0-9]{3} - (GET|POST|HEAD) [^ ]+ [^ ]+ "/(?:[^"]*/)?(?:\.env[^"/]*|\.git/[^" ]*|\.aws/[^" ]*|wp-config\.php[^" ]*|wp-login\.php(?:\?[^" ]*)?|wp-admin(?:/[^" ]*)?|actuator(?:/[^" ]*)?|_ignition(?:/[^" ]*)?|storage/logs(?:/[^" ]*))" \[Client <HOST>\]
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
* **Jail:** `/opt/fail2ban/config/fail2ban/jail.d/npm-scanner.local`
|
||||
|
||||
```ini
|
||||
[npm-scanner]
|
||||
enabled = true
|
||||
filter = npm-scanner
|
||||
backend = auto
|
||||
logpath = /remotelogs/npm/proxy-host-*_access.log
|
||||
findtime = 10m
|
||||
maxretry = 3
|
||||
bantime = 1h
|
||||
ignoreip = 127.0.0.1/8 10.0.0.0/24
|
||||
action = nftables-multiport[port="80,443", protocol=tcp]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Jail 2: Bad User-Agents (`npm-badbots`)
|
||||
|
||||
Blockade bekannter Angriffs-Scanner und Reconnaissance-Tools.
|
||||
|
||||
* **Filter:** `/opt/fail2ban/config/fail2ban/filter.d/npm-badbots.conf`
|
||||
*(Wichtig: Nutzt lokale Case-Insensitivity `(?i:...)`, um Python-RegEx-Kompilierungsfehler zu vermeiden)*
|
||||
|
||||
```ini
|
||||
[Definition]
|
||||
failregex = ^\[.*\] - [0-9]{3} [0-9]{3} - (?:GET|POST|HEAD|OPTIONS) [^ ]+ [^ ]+ "[^"]*" \[Client <HOST>\] .* "[^"]*(?i:sqlmap|nikto|nmap|masscan|zgrab|nessus|openvas|dirbuster|gobuster|wpscan|python-requests|go-http-client|censys|whatweb|acunetix)[^"]*"
|
||||
ignoreregex =
|
||||
```
|
||||
|
||||
* **Jail:** `/opt/fail2ban/config/fail2ban/jail.d/npm-badbots.local`
|
||||
|
||||
```ini
|
||||
[npm-badbots]
|
||||
enabled = true
|
||||
filter = npm-badbots
|
||||
backend = auto
|
||||
logpath = /remotelogs/npm/proxy-host-*_access.log
|
||||
findtime = 10m
|
||||
maxretry = 2
|
||||
bantime = 24h
|
||||
ignoreip = 127.0.0.1/8 10.0.0.0/24
|
||||
action = nftables-multiport[port="80,443", protocol=tcp]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Aktive Proxy Hosts
|
||||
|
||||
Routen aus dem bisherigen Quelleninventar; Keycloak-Backend vom Betreiber erneut bestätigt. Bei Freigaben den tatsächlichen Bestand prüfen. Diese Tabelle beweist weder TLS-Konfiguration noch OIDC-Anbindung jeder Anwendung:
|
||||
|
||||
| ID | Hostname | Backend-Ziel | Dienst |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | `jellyfin.ghostnet.selfhost.eu` | `10.0.0.11:8096` | Jellyfin Media Server |
|
||||
| 3 | `nextcloud.ghostnet.selfhost.eu` | `10.0.0.12:8080` | Nextcloud Cloud Storage |
|
||||
| 4 | `git.ghostnet.selfhost.eu` | `10.0.0.17:3000` | Gitea Code Hosting |
|
||||
| 7 | `auth.ghostnet.selfhost.eu` | `10.0.0.4:8080` | Keycloak Identity Provider |
|
||||
| 10 | `japan.ghostnet.selfhost.eu` | `10.0.0.23:80` | Japanese Web App |
|
||||
| 12 | `vault.ghostnet.selfhost.eu` | `10.0.0.47:8080` | Vaultwarden Password Manager |
|
||||
|
||||
---
|
||||
|
||||
## 8. Betriebs- & Diagnosekommandos
|
||||
|
||||
Die folgenden Befehle auf CT 103 als root ausführen oder mit sudo ergänzen. Platzhalterwerte vor Verwendung ersetzen.
|
||||
|
||||
### Fail2Ban-Status
|
||||
|
||||
```bash
|
||||
# Gesamtstatus der aktiven Jails
|
||||
podman exec fail2ban fail2ban-client status
|
||||
|
||||
# Spezifischen Jail prüfen
|
||||
podman exec fail2ban fail2ban-client status npm-scanner
|
||||
podman exec fail2ban fail2ban-client status npm-badbots
|
||||
```
|
||||
|
||||
### Filter mit echten Logs testen
|
||||
|
||||
```bash
|
||||
podman exec fail2ban fail2ban-regex \
|
||||
/remotelogs/npm/proxy-host-10_access.log \
|
||||
/config/fail2ban/filter.d/npm-scanner.conf
|
||||
```
|
||||
|
||||
### nftables-Regeln & aktive Bans auf dem Host verifizieren
|
||||
|
||||
```bash
|
||||
nft list ruleset | grep -A 10 "table inet f2b-table"
|
||||
```
|
||||
|
||||
### Manuelle Sperre / Freigabe
|
||||
|
||||
```bash
|
||||
# Gewählte IP eintragen, Platzhalter nicht unverändert verwenden.
|
||||
BAN_IP="<ZU-SPERRENDE-IP>"
|
||||
|
||||
# IP manuell sperren
|
||||
podman exec fail2ban fail2ban-client set npm-scanner banip "$BAN_IP"
|
||||
|
||||
# IP manuell freigeben
|
||||
podman exec fail2ban fail2ban-client set npm-scanner unbanip "$BAN_IP"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Sicherheits- & Betriebsregeln für Administrierende
|
||||
|
||||
1. **Kein generisches Statuscode-Banning:** Generische HTTP `4xx`- oder `5xx`-Fehler dürfen nicht als pauschales Ban-Kriterium verwendet werden.
|
||||
2. **Geprüfte Upgrades:** NPM ist im Quellenstand auf `2.11.1` festgeschrieben. Fail2Ban ist auf `1.1.0-r2-ls43` festgeschrieben. Beide Pins regelmäßig auf Updates prüfen; Änderungen mit Backup, Tests und Rückfallplan durchführen.
|
||||
3. **Privilegien-Minimierung:** Der Fail2Ban-Container wird strikt ohne `--privileged` betrieben (`NET_ADMIN` und `NET_RAW` reichen aus).
|
||||
4. **Whitelist-Pflicht:** Das Subnetz `10.0.0.0/24` sowie `127.0.0.1/8` müssen in allen Jails in `ignoreip` hinterlegt bleiben, um Aussperrungen zu verhindern.
|
||||
5. **Syntax-Check vor Reload:** Jede Änderung an Fail2Ban-Konfigurationen ist vorab mit `podman exec fail2ban fail2ban-client -t` auf Gültigkeit zu prüfen.
|
||||
|
||||
---
|
||||
|
||||
## 10. Backup & Disaster Recovery
|
||||
|
||||
Im bisherigen Quellenstand ist ein Proxmox-vzdump-Backup von CT 103 dokumentiert:
|
||||
|
||||
* **Backup-Datei:** `/var/lib/vz/dump/vzdump-lxc-103-2026_08_31-19_11_10.tar.zst`
|
||||
|
||||
Vor strukturellen Änderungen an nftables, Proxy-Konfiguration oder Quadlets ein aktuelles konsistentes Proxmox-Backup erstellen. Ein Snapshot kann ergänzen, ersetzt aber kein unabhängiges Backup. Der genannte Archivpfad ist historischer Quellenstand, kein Nachweis eines aktuellen oder getesteten Backups.
|
||||
|
||||
---
|
||||
|
||||
## 11. Keycloak: bestätigte öffentliche Administration und Korrekturverfahren
|
||||
|
||||
### 11.1 Bestätigter Ist-Stand
|
||||
|
||||
Der Betreiber konnte **von extern** `https://auth.ghostnet.selfhost.eu/admin` öffnen und sich anmelden. Das widerspricht GNAI-004. Die Korrektur wurde bei dieser Dokumentationsrevision noch nicht auf dem System durchgeführt.
|
||||
|
||||
| NPM-Einstellung | Betreiberangabe |
|
||||
| --- | --- |
|
||||
| Domain | `auth.ghostnet.selfhost.eu` |
|
||||
| Backend | HTTP, `10.0.0.4:8080` |
|
||||
| Access List | Publicly Accessible; keine Listen definiert |
|
||||
| Custom Locations | keine |
|
||||
| Optionen | Cache Assets, Block Common Exploits, Websocket Support |
|
||||
| SSL-Einstellungen | alle aus |
|
||||
|
||||
Custom Config enthält aktuell:
|
||||
|
||||
```nginx
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
```
|
||||
|
||||
**TLS-Widerspruch:** Externer HTTPS-Login funktionierte, obwohl für diesen Proxy Host SSL als ausgeschaltet angegeben ist. Effektiven Listener, Zertifikat und vHost-Zuordnung prüfen, bevor eine vollständige HTTPS-Bereitstellung behauptet wird. Auf CT 103 etwa:
|
||||
|
||||
```bash
|
||||
sudo podman exec nginx-proxy-manager nginx -t
|
||||
sudo ss -lntp
|
||||
sudo grep -REn 'auth\.ghostnet\.selfhost\.eu|listen|ssl_certificate|location|allow|deny' \
|
||||
/opt/nginx-proxy-manager/data/nginx/proxy_host/
|
||||
```
|
||||
|
||||
Generierte Dateien nur lesen, nicht direkt ändern; NPM würde Änderungen überschreiben. `Block Common Exploits` ersetzt keine Administrative-Pfadbeschränkung. Die vorhandenen X-Forwarded-Header ebenfalls in der effektiven Nginx-Konfiguration prüfen. Unvertrauenswürdige Client-Header dürfen nicht zur Quelle einer Managementfreigabe werden.
|
||||
|
||||
### 11.2 Sofortschutz für den öffentlichen Adminpfad
|
||||
|
||||
1. Aktuelle Proxy-Einstellungen sichern. Über Proxmox-Konsole Zugriff auf Keycloak behalten und einen funktionierenden internen Administrationsweg prüfen; mögliche Redirects auf den öffentlichen Namen beachten.
|
||||
2. Im NPM den Proxy Host **auth.ghostnet.selfhost.eu → Advanced** öffnen. Im server-Kontext zusätzlich folgenden Schutz ergänzen, ohne bestehende Konfiguration blind zu ersetzen:
|
||||
|
||||
```nginx
|
||||
location ~* ^/admin(?:/|$) {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
Der Schutz sperrt `/admin`, `/admin/` und darunterliegende Admin-API-/GUI-Pfade auf diesem Proxy Host für alle Quellen, auch LAN. Das ist ein vorläufiger Schutz des öffentlichen Hosts; der dauerhafte interne Adminzugang wird separat eingerichtet. Bestehende Regex-Locations und `^~`-Locations auf Prioritätskonflikte prüfen.
|
||||
3. Speichern. NPM-Status und `nginx -t` prüfen. Die aktive Konfiguration kontrollieren, damit der Block sowohl für HTTP als auch für den tatsächlich verwendeten HTTPS-Listener greift. Keine Wirkung nur aufgrund eines gespeicherten Textfelds annehmen.
|
||||
4. Aus einem fremden Netz mit deaktiviertem VPN `/admin`, `/admin/` und `/admin/master/console/` prüfen; Erwartung **403**, keine nutzbare Administration. IPv4 und vorhandenes IPv6 separat prüfen. Kontrollierte Admin-API-Zugriffe müssen ebenfalls gesperrt sein. HTTP darf nicht weiterhin Zugriff erlauben.
|
||||
5. Vaultwarden-Login einschließlich tatsächlichem Keycloak-Redirect und Tokenaustausch prüfen. Bei Änderungen nicht den gesamten auth-Host hinter eine Access List setzen, da öffentliches OIDC weiter benötigt wird.
|
||||
|
||||
Auf der Admin-Oberfläche können schematisch Redirects vorkommen; für Prüfungen HTTP-Status **und Redirectziel** festhalten. Ein 302 auf eine Admin-Anmeldung ist keine erfolgreiche Sperre. Der öffentliche Adminpfad wird erst nach externem Gegencheck als korrigiert geführt.
|
||||
|
||||
### 11.3 Dauerhafte Trennung
|
||||
|
||||
Einen internen Admin-Proxy Host mit separat bestätigtem Hostnamen, Zertifikat und interner Namensauflösung planen. Netzwerkzugang nur für Familie und Server Admins erlauben, am Gateway vor NAT durchsetzen und direkte Backend-Erreichbarkeit berücksichtigen. Bei Keycloak `hostname-admin`/Frontend-Hostname passend zur **installierten Version** konfigurieren. Ein Adminhostname allein schützt die Admin-REST-API auf dem öffentlichen Frontend nicht; öffentliche Pfade weiterhin sperren. [Hostname-Konfiguration](https://www.keycloak.org/server/hostname)
|
||||
|
||||
Auch den tatsächlichen Administrationsrealm erfassen. Falls das `master` ist, `/realms/master/` ebenfalls ausschließlich intern bereitstellen. Zuerst Vaultwardens produktiven OIDC-Issuer prüfen, damit ein pauschaler Realm-Block dessen Anmeldung nicht unbemerkt unterbricht. Public benötigt geeignete Anwendungsrealm-Endpunkte und Ressourcen. Health/Metrics/Managementport nicht veröffentlichen. [Keycloak-Proxy-Pfade](https://www.keycloak.org/server/reverseproxy)
|
||||
|
||||
Aktuell bestätigt ist nur Vaultwarden-OIDC. Zusätzliche Dienste sind geplant. Die tatsächliche lokale Realm-/Client-Struktur und der interne Adminhostname bleiben offen.
|
||||
|
||||
## 12. Fail2Ban: fester Image-Pin und verbleibende Abnahme
|
||||
|
||||
Der Betreiber bestätigt am 16.09.2026 die Umstellung auf:
|
||||
|
||||
```ini
|
||||
Image=lscr.io/linuxserver/fail2ban:1.1.0-r2-ls43
|
||||
```
|
||||
|
||||
Der Fail2Ban-Container läuft nach der Umstellung wieder. Damit ist die frühere Abweichung durch den beweglichen Tag `latest` behoben. Der Tag bezeichnet den LinuxServer-Container-Build; die darin enthaltene Anwendung meldet Fail2Ban v1.1.0. Das ist nicht mit einem Upstream-Upgrade auf Fail2Ban 1.1.1 gleichzusetzen.
|
||||
|
||||
Für die technische Abnahme sind noch Nachweise zu erfassen; aus „läuft wieder“ werden keine weitergehenden Testergebnisse abgeleitet:
|
||||
|
||||
1. Effektiven Image-Namen und Anwendungsversion prüfen: `podman inspect fail2ban --format '{{.ImageName}}'` sowie `podman exec fail2ban fail2ban-client --version`.
|
||||
2. Konfiguration und Jails prüfen: `podman exec fail2ban fail2ban-client -t`, `fail2ban-client status` und Status der NPM-Jails.
|
||||
3. Kontrollierte HTTP-/HTTPS-Treffer bis zum Ban auslösen, Eintrag im nftables-Regelsatz verifizieren und Test-IP anschließend wieder freigeben.
|
||||
4. Dienstneustart und später LXC-/Host-Neustart prüfen; danach Containerstatus, Jails und Filter erneut kontrollieren.
|
||||
5. Laufenden Image-Digest und ein aktuelles konsistentes Backup als Rückfallstand festhalten. Ein Digest-Pin kann nach Manifest-/Architekturprüfung den Tag-Pin zusätzlich härten.
|
||||
|
||||
Upstream-Anwendung und Container-Build bleiben getrennte Versionsachsen. Vor einem späteren Upgrade sind LinuxServer-Release, enthaltene Fail2Ban-Version, Architektur und lokale Filter/Jails erneut zu prüfen. [Fail2Ban-Releases](https://github.com/fail2ban/fail2ban/releases), [LinuxServer-Images](https://docs.linuxserver.io/images/docker-fail2ban/)
|
||||
|
||||
## 13. Bewusste Betriebsentscheidung: generische HTTP-Clients bleiben gesperrt
|
||||
|
||||
**Entscheidung des Betreibers:** `python-requests` und `go-http-client` verbleiben im npm-badbots-Filter. Legitimer automatisierter Verkehr kann dadurch nach dem konfigurierten Schwellwert ebenfalls einen Ban auslösen. User-Agent ist keine starke Authentifizierung; er kann geändert werden. Dieser Filter ist eine zusätzliche Heuristik, keine vollständige Abuse-Erkennung.
|
||||
|
||||
Bei Bedarf darf ein berechtigter Nutzer einen erlaubten Dienst über WireGuard verwenden. Voraussetzung sind passende Rollenrechte, Routing und ein tatsächlich interner Zielpfad; nur das Aktivieren des VPN umgeht eine öffentliche Route nicht automatisch. Mit dem bestehenden MASQUERADE sieht NPM VPN→LAN-Verkehr typischerweise von `10.0.0.15`, das im LAN-ignoreip liegt. Ein öffentlicher Hostname kann weiterhin zur WAN-IP auflösen und direkt benutzt werden; DNS-/Zielpfad und NPM-Quelladresse im Log prüfen.
|
||||
|
||||
LLM Admins dürfen nur `.90` erreichen und haben keinen allgemeinen NPM-/LXC-Zugriff. API-Clients ohne passende VPN-Rolle bekommen durch diese Ausweichoption keine zusätzlichen Rechte. Bei Supportfällen diese bewusste Ban-Entscheidung ausdrücklich mitprüfen.
|
||||
|
||||
## 14. Noch offene Abnahme
|
||||
|
||||
| Befund | Abschlussnachweis |
|
||||
| --- | --- |
|
||||
| Keycloak Admin extern nutzbar | externe Sperre von GUI und API über tatsächliche HTTP/HTTPS-/IPv6-Pfade, interner Adminzugang und Vaultwarden-OIDC weiter funktionsfähig |
|
||||
| TLS-Zuordnung des auth-Hosts unklar | effektiver Listener, Zertifikat, Redirects und Backend-Pfad dokumentiert |
|
||||
| Fail2Ban auf `1.1.0-r2-ls43` gepinnt und Container wieder laufend | effektives Image und Version dokumentiert; Jail-/Filter-/Ban-/Dienstneustart-/Reboottests bestanden |
|
||||
@@ -0,0 +1,321 @@
|
||||
# Technische Architekturbeschreibung – WireGuard-Gateway
|
||||
|
||||
**Dokumenten-ID:** GNAI-006-SEC
|
||||
**Status:** Dokumentation bereinigt; technische Umsetzung und Abnahme teilweise offen
|
||||
**Referenzen:** [Zielarchitektur](../ai/GNAI-003-INFRA_Architecture.md), [Zugriffskonzept](GNAI-004-SEC_Access-Control.md), [GUI-SOP](GNAI-006-SEC_VPN_Client-Management.md), [Implementation-Log](GNAI-006-SEC_VPN_Implementation-Log.md)
|
||||
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Änderung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-09-09 | 1.0–1.5 | spektr | Aufbau und Migration von v14 auf v15; historische Details im Implementation-Log |
|
||||
| 2026-09-15 | 2.0 | spektr | Rollen Familie/Server Admin/LLM Admin; bestätigtes LXC und Hooks; NAT-Abhängigkeit; v15-Bereinigung; getrennte SOPs und belastbarer Abnahmestatus |
|
||||
| 2026-09-18 | 2.1 | spektr | Lesenden Gateway-Abgleich, iptables-legacy-Befund und DNS-Abgleich ergänzt; Betriebshinweise entsprechend korrigiert. |
|
||||
|
||||
## 1. Zweck und dokumentierter Stand
|
||||
|
||||
Das Gateway ermöglicht administrativen und familiären Fernzugriff auf das Heimnetz. WireGuard authentifiziert Geräte durch Schlüssel; die Zielsysteme verlangen weiterhin ihre eigene Anmeldung. Ein Peer wird pro Gerät vergeben. Eine gemeinsame Konfiguration für mehrere gleichzeitig verwendete Geräte ist nicht vorgesehen.
|
||||
|
||||
Das WireGuard-Gateway läuft bereits. Die nachfolgende Installation beschreibt seinen reproduzierbaren Aufbau; neue Sicherheitsmaßnahmen sind als **Soll** gekennzeichnet. Grundlage sind die Quellen, die Tests vom 12.09.2026, die vom Betreiber bereitgestellte Konfiguration und der lesende Gateway-Abgleich vom 18.09.2026. Es wurden keine Systemkonfigurationen geändert und keine neuen Client- oder Rollentests durchgeführt.
|
||||
|
||||
**Wesentliche offene Umsetzung:** Per-Client Firewall ist deaktiviert. Die bisherige breite Forward-Regel erzwingt keine Rollenisolierung. HTTPS für die wg-easy-GUI ist noch nicht eingerichtet. Der dokumentierte Endpoint `vpn.ghostnet.selfhost.eu` stimmte am 18.09.2026 mit der ausgehenden IPv4 des Gateways überein; die DynDNS-Aktualisierung nach einem Adresswechsel ist noch nicht nachgewiesen.
|
||||
|
||||
## 2. Architektur und Adressplan
|
||||
|
||||
| Komponente | Adresse / Konfiguration |
|
||||
| --- | --- |
|
||||
| Fritzbox 7530 | `10.0.0.1`, Gateway, DNS und DynDNS-Updater |
|
||||
| Proxmox / Mediaserver | `10.0.0.2` |
|
||||
| NPM, CT 103 | `10.0.0.10`; TCP 80/443 öffentlich, TCP 81 administrativ |
|
||||
| WireGuard, CT 105 | `10.0.0.15/24`, Hostname `wireguard` |
|
||||
| KI-Server | `10.0.0.90`, Hostname `ghostnet-ki` |
|
||||
| Statischer Server-/LXC-Adressbereich | bis `.99`; konkrete Belegung siehe GNAI-003 |
|
||||
| DHCP-Clients | `10.0.0.100–10.0.0.200` |
|
||||
| VPN-Netz / Gateway | `10.8.0.0/24` / `10.8.0.1` |
|
||||
| WireGuard-Port | UDP 51820 |
|
||||
| wg-easy-GUI, Ist | `http://10.0.0.15:51821` |
|
||||
|
||||
Die Fritzbox leitet **TCP 80/443 an `10.0.0.10`** und **UDP 51820 an `10.0.0.15`** weiter. NPM ist nicht am WireGuard-Datenpfad beteiligt. Es gibt keine Fritzbox-Rückroute zum VPN-Netz; wg-easy verwendet deshalb MASQUERADE auf dem LAN-Ausgang.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
W["Externe Clients"] --> F["Fritzbox 7530"]
|
||||
F -->|"TCP 80/443"| N["NPM · 10.0.0.10"]
|
||||
F -->|"UDP 51820"| V["wg-easy · 10.0.0.15"]
|
||||
N --> A["Öffentliche Anwendungen"]
|
||||
V --> R["Peer-Firewall · Soll; NAT · Ist"]
|
||||
R --> S["Proxmox, LXCs und KI-Server"]
|
||||
R -->|"nur Familie"| C["Heimnetz-PCs und Clients"]
|
||||
```
|
||||
|
||||
Die Adressgruppierung im selben `/24` bildet keine Netzwerksegmentierung. Server-, Heim- und Gästenetz können später in einem eigenen Netzwerk-Sprint durch separate Netze, Routing und passende Hardware geordnet werden. Für diesen Sprint werden weder neue Subnetze noch VLAN-IDs angenommen.
|
||||
|
||||
### 2.1 Rollen und Durchsetzung
|
||||
|
||||
| Rolle | Erlaubte Ziele | Client-Routing und serverseitige Firewall |
|
||||
| --- | --- | --- |
|
||||
| Familie | gesamtes Heimnetz einschließlich PCs und Clients | Heimnetz `10.0.0.0/24`; Zugriff auf das Gateway zusätzlich nach Bedarf explizit festlegen |
|
||||
| Server Admin | Proxmox, aktuelle Service-LXCs und KI-Server; wg-easy-GUI eingeschlossen | einzelne freigegebene Hostadressen aus dem Inventar; kein pauschales Heimnetz-`/24` |
|
||||
| LLM Admin | KI-Server `10.0.0.90` | `10.0.0.90/32`; keine Freigabe für Proxmox, NPM oder wg-easy |
|
||||
|
||||
Diese Vorgaben erlauben Netzwerkzugriff auf die genannten Hosts. Anwendungs-, SSH- und Betriebssystemrechte werden separat vergeben. Ein statischer Adressbereich ist kein ausreichender Nachweis, dass jede Adresse darin ein Server ist: Erweiterungen benötigen einen Inventareintrag und die passende Peer-Freigabe.
|
||||
|
||||
**Soll:** In wg-easy die Per-Client Firewall aktivieren und für jeden Peer **Firewall Allowed IPs** ausdrücklich setzen. **Allowed IPs** im exportierten Profil steuert weiter das Split-Tunnel-Routing. **Server Allowed IPs** bezeichnet die Netze, die der Server zum Peer routet; für ein einzelnes Endgerät bleibt das dessen eigene VPN-IP `/32`. Diese drei Felder dürfen nicht miteinander verwechselt werden. [Client-Felder](https://wg-easy.github.io/wg-easy/latest/guides/clients/)
|
||||
|
||||
Die Funktion ist laut offizieller Dokumentation experimentell. Abnahme muss absichtliche Erweiterungen der clientseitigen AllowedIPs auf gesperrte Ziele einschließen. Insbesondere muss der Zugriff auf **lokale Gateway-Dienste** geprüft werden, da dieser die INPUT- statt FORWARD-Chain durchläuft. [Per-Client Firewall](https://wg-easy.github.io/wg-easy/latest/guides/admin/)
|
||||
|
||||
## 3. Installation im Proxmox-LXC
|
||||
|
||||
### 3.1 LXC erstellen und Netzwerk konfigurieren
|
||||
|
||||
In Proxmox ein unprivileged Debian-13-LXC mit diesen Werten erstellen:
|
||||
|
||||
| Parameter | bestätigter Wert |
|
||||
| --- | --- |
|
||||
| CT-ID / Hostname | 105 / `wireguard` |
|
||||
| Betriebssystem / Architektur | Debian 13 Trixie / amd64 |
|
||||
| CPU / RAM / Swap | 1 Core / 512 MiB / 512 MiB |
|
||||
| RootFS | 4 GiB, `local-lvm` |
|
||||
| Features | `nesting=1,keyctl=1` |
|
||||
| Netz | `eth0`, `vmbr0`, `10.0.0.15/24`, Gateway `10.0.0.1` |
|
||||
| Start / Zeitzone | `onboot: 1` / `Europe/Berlin` |
|
||||
| Proxmox-Version, Quellenstand | 9.2.11; bei Reproduktion installierte Version festhalten |
|
||||
|
||||
Auf dem Proxmox-Host in `/etc/pve/lxc/105.conf` ergänzen, ohne vorhandene Einträge doppelt anzulegen:
|
||||
|
||||
```text
|
||||
lxc.cgroup2.devices.allow: c 10:200 rwm
|
||||
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
|
||||
```
|
||||
|
||||
Nach einer Änderung CT 105 neu starten. Im LXC prüfen:
|
||||
|
||||
```bash
|
||||
ls -l /dev/net/tun
|
||||
ip -4 addr show eth0
|
||||
ip -4 route show
|
||||
```
|
||||
|
||||
WireGuard im Kernel verwendet ein WireGuard-Netzinterface. TUN ist Teil der bestätigten LXC-Baseline und unterstützt mögliche Userspace-Implementierungen; sein Vorhandensein allein beweist keine funktionierende WireGuard-Kernelunterstützung. Fehlende Kernelmodule werden auf dem **Proxmox-Host** untersucht, nicht durch pauschale SYS_MODULE- oder privileged-Freigaben im LXC ersetzt.
|
||||
|
||||
### 3.2 Pakete, Administrator und persistente Verzeichnisse
|
||||
|
||||
Im LXC als root bzw. mit sudo installieren:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install podman nftables iptables iproute2 procps curl sudo openssh-server
|
||||
sudo install -d -m 700 /opt/wg-easy/data
|
||||
sudo install -d -m 755 /etc/containers/systemd
|
||||
sudo install -m 600 /dev/null /opt/wg-easy/environment
|
||||
```
|
||||
|
||||
Der letzte Befehl ist ausschließlich für eine **Neuinstallation**: ein vorhandenes Environment-File nicht überschreiben. Dokumentiert ist Podman 5.4.2. Die durch Debian bereitgestellte Version mit `podman --version` festhalten und Quadlet-Unterstützung prüfen.
|
||||
|
||||
Den Benutzer `admin` nur anlegen, wenn er noch nicht existiert. SSH-Key hinterlegen und Rechte testen. Für die SSH-Härtung die allgemeinen Prüfschritte aus [GNAI-002](GNAI-002-INFRA_Users.md) auf diesen LXC übertragen; dessen KI-Server-Konten und Netzwerte nicht übernehmen. Im bestehenden WireGuard-LXC ist `admin ALL=(ALL) NOPASSWD: ALL` eingerichtet; das ist der bestätigte Ist-Stand und keine allgemeine Vorgabe für alle LLM-Benutzer. Änderungen an SSH immer mit einer offenen zweiten Sitzung oder Proxmox-Konsole absichern.
|
||||
|
||||
### 3.3 IP-Forwarding
|
||||
|
||||
`/etc/sysctl.d/99-ipforward.conf`:
|
||||
|
||||
```ini
|
||||
net.ipv4.ip_forward=1
|
||||
```
|
||||
|
||||
Anwenden und prüfen:
|
||||
|
||||
```bash
|
||||
sudo sysctl --system
|
||||
sysctl net.ipv4.ip_forward
|
||||
```
|
||||
|
||||
Erwartet: `net.ipv4.ip_forward = 1`. Die bestätigten LXC-Routen sind:
|
||||
|
||||
```text
|
||||
default via 10.0.0.1 dev eth0 proto kernel onlink
|
||||
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.15
|
||||
10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.1
|
||||
```
|
||||
|
||||
Die VPN-Route entsteht erst mit dem Interface. Bei Neuinstallation vor dem ersten wg-easy-Start ist sie noch nicht vorhanden.
|
||||
|
||||
### 3.4 nftables-Baseline: Ist und erforderliche Erweiterung
|
||||
|
||||
Die Quellen dokumentieren folgende Baseline in `/etc/nftables.conf`. Ein lesender Live-Abgleich der entscheidenden INPUT- und FORWARD-Regeln am 18.09.2026 bestätigt weiterhin die breite VPN→LAN-Freigabe; das vollständige Regelwerk ist im [Implementation-Log](GNAI-006-SEC_VPN_Implementation-Log.md) nicht als neue Gesamtabnahme ausgewiesen:
|
||||
|
||||
```nft
|
||||
#!/usr/sbin/nft -f
|
||||
flush ruleset
|
||||
|
||||
table inet filter {
|
||||
chain input {
|
||||
type filter hook input priority filter; policy drop;
|
||||
iifname "lo" accept
|
||||
ct state invalid drop
|
||||
ct state established,related accept
|
||||
icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept
|
||||
udp dport 51820 accept
|
||||
ip saddr 10.0.0.0/24 tcp dport { 22, 51821 } accept
|
||||
limit rate 4/second burst 8 packets log prefix "nft-input-dropped: "
|
||||
drop
|
||||
}
|
||||
chain forward {
|
||||
type filter hook forward priority filter; policy drop;
|
||||
ct state invalid drop
|
||||
ct state established,related accept
|
||||
iifname "wg0" ip daddr 10.0.0.0/24 ct state new accept
|
||||
oifname "wg0" ip saddr 10.0.0.0/24 ip daddr 10.8.0.0/24 ct state new accept
|
||||
drop
|
||||
}
|
||||
chain output {
|
||||
type filter hook output priority filter; policy accept;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Diese Baseline ist keine fertige Rollen-Firewall.** Die breite FORWARD-Freigabe muss gemeinsam mit Per-Client Firewall getestet werden. Die INPUT-Regel erlaubt LAN-Quellen, aber noch keine neuen Verbindungen von VPN-Quellen `10.8.0.x` auf TCP 22/51821. Für Familie und Server Admins muss am Gateway eine ausdrückliche INPUT-Freigabe anhand ihrer zugewiesenen VPN-IP oder einer gepflegten Peer-IP-Menge hinzukommen. LLM Admins dürfen diese Ports auch nach einer lokalen Routingänderung nicht erreichen. Die Rollenzuordnung vorhandener Peers ist noch offen; daher wird keine angeblich fertige IP-Regel erfunden.
|
||||
|
||||
`flush ruleset` löscht dynamisch angelegte nftables-/iptables-nft-Regeln. Der Live-Abgleich am 18.09.2026 zeigte jedoch wg-easy-Hooks in **iptables-legacy**; diese werden durch einen nftables-Flush nicht automatisch mit gelöscht. Beide Regelwerke und ihre gemeinsame Wirkung müssen nach Reload oder Neustart geprüft werden. Bei einer Neuinstallation zuerst die Baseline laden, danach wg-easy starten. Im laufenden Betrieb vor einem Reload Regelzustand sichern und Änderung über die Proxmox-Konsole ausführen. Dauerhafte Regeln und dynamische Regeln brauchen eine getestete Start-/Reload-Reihenfolge; diese Abnahme steht noch aus.
|
||||
|
||||
```bash
|
||||
sudo nft -c -f /etc/nftables.conf
|
||||
sudo nft -f /etc/nftables.conf
|
||||
sudo systemctl enable nftables.service
|
||||
sudo nft list ruleset
|
||||
```
|
||||
|
||||
Diese Befehle sind Installationsschritte, keine Empfehlung zum ungeprüften Reload einer laufenden Umgebung. IPv6 im LXC und am Perimeter separat prüfen. `DISABLE_IPV6=true` in wg-easy ersetzt keine Prüfung der IPv6-Erreichbarkeit anderer Dienste.
|
||||
|
||||
### 3.5 Rootful Podman-Quadlet
|
||||
|
||||
Bestätigter `/opt/wg-easy/environment`-Stand aus dem v15-Hauptdokument; bei Installation mit dem tatsächlichen Environment abgleichen:
|
||||
|
||||
```ini
|
||||
INSECURE=true
|
||||
DISABLE_IPV6=true
|
||||
DISABLE_VERSION_CHECK=true
|
||||
```
|
||||
|
||||
`INSECURE=true` erlaubt derzeit HTTP. Die VPN-Konfiguration und Administratoranmeldung liegen in v15 in der SQLite-Datenbank, nicht in den alten v14-Variablen `WG_HOST`, `WG_ALLOWED_IPS` oder `PASSWORD_HASH`. Ein fester Image-Pin verhindert unkontrollierte Versionswechsel; eine dauerhafte Aussage über den veränderlichen `latest`-Tag wird nicht vorausgesetzt. [Konfiguration](https://wg-easy.github.io/wg-easy/latest/advanced/config/optional-config/)
|
||||
|
||||
Bestätigter `/etc/containers/systemd/wg-easy.container`:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
Image=ghcr.io/wg-easy/wg-easy:15.4.0
|
||||
ContainerName=wg-easy
|
||||
Network=host
|
||||
AddCapability=NET_ADMIN
|
||||
AddCapability=NET_RAW
|
||||
EnvironmentFile=/opt/wg-easy/environment
|
||||
Volume=/opt/wg-easy/data:/etc/wireguard:rw
|
||||
|
||||
[Service]
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
`Network=host` bezieht sich auf den Netzwerknamespace des LXC, nicht auf den Proxmox-Host. Das Quadlet läuft rootful im LXC. Quadlet generiert **`wg-easy.service`**; die generierte Unit wird nicht direkt bearbeitet oder wie eine normale statische Unit enabled.
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start wg-easy.service
|
||||
sudo systemctl status wg-easy.service
|
||||
sudo podman ps
|
||||
sudo journalctl -u wg-easy.service -n 100 --no-pager
|
||||
```
|
||||
|
||||
Nach Quadlet-Änderungen `daemon-reload` und `restart` ausführen. Autostart von LXC, nftables und wg-easy sowie persistentes Forwarding gemeinsam durch einen geplanten Reboot testen. Die bisherige Dokumentation ist kein Nachweis dieser vollständigen Wiederanlaufprüfung.
|
||||
|
||||
## 4. wg-easy erstmalig konfigurieren
|
||||
|
||||
1. Aus dem vertrauenswürdigen LAN `http://10.0.0.15:51821` öffnen. Im vorhandenen System ist der Wizard bereits abgeschlossen.
|
||||
2. Bei Neuinstallation Administrator-Benutzername und Passwort im Wizard setzen. Zugangsdaten im Passwortmanager hinterlegen; keine Secrets in Dokumente kopieren.
|
||||
3. Für Neuinstallation **kein vorhandenes v14-Backup importieren**. Der historische v14→v15-Import ist ausschließlich im Implementation-Log dokumentiert.
|
||||
4. Als Host `vpn.ghostnet.selfhost.eu` und als Port `51820` eintragen; vor Ausgabe neuer Profile DNS-Auflösung und aktuelle WAN-IP erneut vergleichen.
|
||||
5. Interface-Adressraum `10.8.0.0/24`, Gateway `10.8.0.1` und IPv4-Betrieb prüfen. In Admin Panel → Interface das LAN-Ausgangsgerät `eth0` prüfen.
|
||||
6. Neue Client-Defaults so wählen, dass neue Peers keine ungeprüften Vollzugriffsrechte erhalten. Für jede Freigabe gilt die separate GUI-SOP; ein Default ist keine Rollenzuordnung.
|
||||
7. DNS rollenabhängig setzen: Familie kann die Fritzbox `10.0.0.1` über das Heimnetz erreichen. Server Admins und LLM Admins verwenden zunächst System-DNS, sofern keine gesonderte DNS-Freigabe beschlossen wird. Historischer Laptop-DNS `10.0.0.1` ist kein pauschaler neuer Default.
|
||||
8. Per-Client Firewall für die neue Rollenpolitik aktivieren und abnehmen. Vor Aktivierung vorhandene Peers erfassen, Änderungen über LAN durchführen und unzugeordnete Peers während der Umstellung gesperrt halten.
|
||||
|
||||
[Offizieller Setup-Ablauf](https://wg-easy.github.io/wg-easy/latest/guides/setup/)
|
||||
|
||||
### 4.1 Bestätigte Server-Hooks und NAT-Abhängigkeit
|
||||
|
||||
PreUp und PreDown sind leer. Bestätigter PostUp:
|
||||
|
||||
```bash
|
||||
iptables -t nat -A POSTROUTING -s {{ipv4Cidr}} -o {{device}} -j MASQUERADE; iptables -A INPUT -p udp -m udp --dport {{port}} -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT;
|
||||
```
|
||||
|
||||
Bestätigter PostDown:
|
||||
|
||||
```bash
|
||||
iptables -t nat -D POSTROUTING -s {{ipv4Cidr}} -o {{device}} -j MASQUERADE; iptables -D INPUT -p udp -m udp --dport {{port}} -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT;
|
||||
```
|
||||
|
||||
Das sind wg-easy-Templates; nicht unverändert als Terminalbefehle ausführen. Prüfen, dass die Platzhalter auf `10.8.0.0/24`, `eth0` und `51820` aufgelöst werden. MASQUERADE wird beibehalten, solange keine getestete Rückroute eingerichtet ist. Das Entfernen aller Hooks würde den dokumentierten LAN-Zugriff gefährden. Die ACCEPT-Regeln sind breit; ihre Reihenfolge und Wirkung mit den Per-Client-Regeln müssen geprüft werden.
|
||||
|
||||
```bash
|
||||
sudo podman exec wg-easy iptables -V
|
||||
sudo podman exec wg-easy iptables -S
|
||||
sudo podman exec wg-easy iptables -t nat -S
|
||||
sudo nft list ruleset
|
||||
sudo iptables-legacy -S FORWARD
|
||||
sudo iptables-legacy -t nat -S POSTROUTING
|
||||
sudo podman exec wg-easy wg show wg0
|
||||
```
|
||||
|
||||
Mit iptables-nft werden Regeln in nftables sichtbar; bei iptables-legacy zusätzlich dessen eigenen Zustand berücksichtigen. Der Standardaufruf `iptables -S` zeigte am 18.09.2026 nur die nft-Ansicht und warnte vor vorhandenen Legacy-Tabellen. Ein ACCEPT in einer Base-Chain garantiert keine Freigabe gegenüber anderen Base-Chains; ein DROP ist abschließend. Eine pauschale Aussage „kein Konflikt“ ist deshalb kein Ersatz für Regel- und Verkehrstests. [nftables-Verarbeitung](https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains)
|
||||
|
||||
## 5. HTTPS und Erreichbarkeit der Verwaltungs-GUI
|
||||
|
||||
**Ist:** HTTP auf TCP 51821, laut Baseline nur aus LAN-Quellen. **Soll:** Zugriff nur für Familie und Server Admins; Administrator erstellt und verteilt alle Profile.
|
||||
|
||||
HTTPS über einen internen, zugriffsbeschränkten NPM-Proxy Host ist eine mögliche Erweiterung. Hostname, Zertifikatsverfahren und interne Namensauflösung sind noch festzulegen. Keine öffentliche Freigabe allein wegen HTTPS oder eines internen DNS-Namens annehmen. Bei Proxy-Betrieb den direkten Port 51821 auf die benötigten Quellen begrenzen und LLM-Admin-Zugriffe über den Gateway-INPUT-Pfad separat sperren. Hinter einem HTTP-Backend-Proxy kann `INSECURE=true` weiterhin nötig sein; externe TLS-Terminierung verschlüsselt den NPM→wg-easy-Pfad nicht automatisch.
|
||||
|
||||
MASQUERADE lässt LAN-Dienste VPN-Verkehr unter der Quelladresse `10.0.0.15` sehen. Eine NPM-Freigabe für diese Adresse unterscheidet Familie, Server Admin und LLM Admin nicht. Rollentrennung muss vor NAT am Gateway funktionieren. Eine pauschale LAN-Freigabe gewährt außerdem lokalen Heimnetz-Clients Zugriff; eine gruppengenaue Beschränkung lokaler Geräte erfordert zusätzliche Zuordnung oder Authentifizierung und ist noch offen.
|
||||
|
||||
## 6. Betrieb, Backup und Wiederherstellung
|
||||
|
||||
| Artefakt | Zweck |
|
||||
| --- | --- |
|
||||
| `/etc/pve/lxc/105.conf` | LXC-Konfiguration auf Proxmox |
|
||||
| `/etc/containers/systemd/wg-easy.container` | Quadlet |
|
||||
| `/opt/wg-easy/environment` | allgemeine Container-Schalter, root, Modus 600 |
|
||||
| `/opt/wg-easy/data/wg-easy.db` | v15-Konfiguration, Clients und Secrets |
|
||||
| `/opt/wg-easy/data/wg0.conf` | erzeugte Serverkonfiguration; nicht manuell bearbeiten |
|
||||
| `/etc/nftables.conf` | lokale Firewall |
|
||||
| `/etc/sysctl.d/99-ipforward.conf` | Forwarding |
|
||||
|
||||
Vor Änderungen ein konsistentes Proxmox-Backup erstellen. Ein Snapshot allein ist kein unabhängiges Backup. Für ein Dateibackup wg-easy in einem Wartungsfenster stoppen, **das gesamte Datenverzeichnis** einschließlich etwaiger SQLite-WAL-Dateien sowie Quadlet, Environment, Firewall und sysctl sichern; anschließend Dienst wieder starten. Backups enthalten PrivateKeys und PresharedKeys und sind entsprechend zu schützen. Wiederherstellung einschließlich Rollenregeln, NAT, externem Handshake und gesperrten Zielen testen. Restore kann inzwischen widerrufene Peers wieder aktivieren; Widerrufsliste abgleichen.
|
||||
|
||||
## 7. Abnahme und Evidenz
|
||||
|
||||
| Prüfung | Ergebnis / Status |
|
||||
| --- | --- |
|
||||
| Laptop-Handshake von WAN | bestanden am 12.09.2026 |
|
||||
| Laptop → `10.8.0.1` und Ping `10.0.0.2` | bestanden am 12.09.2026 |
|
||||
| Laptop-Internet bleibt direkt | IPv4-Test bestanden am 12.09.2026 |
|
||||
| Zugriff auf KI-Server | offen; im letzten Test ausgeschaltet |
|
||||
| Proxmox-GUI / SSH-Diensttests | offen; Ping ersetzt keinen Diensttest |
|
||||
| Familie → Heimnetz-PC | offen, einschließlich Host-Firewall und Authentifizierung |
|
||||
| Server Admin → Server erlaubt, DHCP-Client gesperrt | offen, Per-Client Firewall noch aus |
|
||||
| LLM Admin → KI-Server erlaubt, Proxmox/NPM/Gateway-GUI gesperrt | offen, auch bei erweiterten lokalen AllowedIPs prüfen |
|
||||
| WAN → TCP 22/51821 und IPv6-Exposure | offen |
|
||||
| Reboot / Firewall-Reload / Restore | offen |
|
||||
|
||||
Tests von einem fremden Netz ausführen, nicht nur aus dem Heimnetz. Für Isolation zuerst sicherstellen, dass das gesperrte Ziel von einem erlaubten Peer tatsächlich erreichbar ist. Handshake und VPN-Routen prüfen, dann bewusst clientseitiges Routing zu einem gesperrten Ziel ergänzen. Timeout allein ist ohne aktiven Zielservice und nachvollziehbare Firewallwirkung kein ausreichender Isolationsnachweis. Ergebnisse mit Datum, Quellnetz, Peer, Ziel, Port und Regelzählern dokumentieren; Secrets auslassen.
|
||||
|
||||
## 8. Offene Angaben und Abschlussbedingungen
|
||||
|
||||
| Punkt | erforderliche Klärung / Umsetzung |
|
||||
| --- | --- |
|
||||
| VPN-DynDNS | Am 18.09.2026 löste `vpn.ghostnet.selfhost.eu` zur ausgehenden Gateway-IPv4 `93.208.161.126` auf; `vpn.ghostnet.dyndns.eu` zeigte auf `83.169.40.234`. Profile nutzen den selfhost-Namen. Automatische Aktualisierung nach WAN-IP-Wechsel und tatsächliche Fritzbox-DynDNS-Einstellung noch prüfen. |
|
||||
| Vorhandene Peers | `Laptop-FullAdmin` (`10.8.0.2`) und `Android-LLMAdmin` (`10.8.0.3`) sind historisch. Laptop der neuen Familie-/Server-Admin-Rolle ausdrücklich zuordnen; Android bleibt außerhalb der neuen Client-SOPs. |
|
||||
| Gateway-Management | INPUT-Regeln für zugeordnete Familie-/Server-Admin-Peers ergänzen; lokale Zugangsgruppen festlegen. |
|
||||
| Per-Client Firewall | aktivieren, erzeugte Regeln samt Hooks prüfen, negative Tests und Wiederanlauf abnehmen. |
|
||||
| GUI-HTTPS | Hostname, Zertifikat und Namensauflösung entscheiden und implementieren. |
|
||||
@@ -0,0 +1,99 @@
|
||||
# Standard Operating Procedure
|
||||
|
||||
**Dokumenten-ID:** GNAI-006-SEC-SOP-01
|
||||
**Titel:** Clients in der wg-easy-GUI einrichten und verwalten
|
||||
**Status:** Betriebsverfahren dokumentiert; Rollen-Firewall noch nicht umgesetzt oder abgenommen
|
||||
**Referenzen:** [Gateway-Architektur](GNAI-006-SEC_VPN.md), [Rollenmodell](GNAI-004-SEC_Access-Control.md), [Windows](GNAI-006-SEC_VPN_Clients_Windows11.md), [Linux](GNAI-006-SEC_VPN_Clients_Linux.md)
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Änderung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-09-15 | 1.0 | spektr | Eigenständige SOP für Rollenzuordnung, Profilausgabe, Änderung, Widerruf und Abnahme angelegt. |
|
||||
| 2026-09-18 | 1.1 | spektr | Offenen Umsetzungsstand der Rollen-Firewall, Gateway-INPUT-Regeln und negative Rollentests präzisiert. |
|
||||
|
||||
## 1. Zweck und Voraussetzungen
|
||||
|
||||
Administratoren erstellen, ändern, verteilen und widerrufen WireGuard-Profile. Nutzer erhalten ausschließlich ihr eigenes Geräteprofil und benötigen keinen Zugriff auf wg-easy. GUI-Zugang ist für Familie und Server Admins vorgesehen, LLM Admins erhalten keinen Zugang.
|
||||
|
||||
Benötigt werden ein Administratorlogin, Zugriff auf `http://10.0.0.15:51821` aus einem erlaubten Netz und ein aktuelles Serverinventar. Der dokumentierte Endpoint ist `vpn.ghostnet.selfhost.eu`; vor Profilausgabe seine DNS-Auflösung mit der aktuellen WAN-IP vergleichen. HTTPS ist geplant, noch nicht eingerichtet. Ein eigener Peer pro Gerät ermöglicht gezielten Widerruf.
|
||||
|
||||
Vor Rollenvergabe müssen Per-Client Firewall und Gateway-INPUT-Regeln nach der Architektur eingerichtet und geprüft werden. Der derzeitige Serverzustand bietet noch keine nachgewiesene Rollenisolierung. Diese SOP dokumentiert die Umstellung und den anschließenden Regelbetrieb; sie erklärt bestehende Peers nicht rückwirkend für sicher.
|
||||
|
||||
## 2. Rollenwerte festlegen
|
||||
|
||||
| Rolle | Allowed IPs im Profil | Firewall Allowed IPs auf dem Server | DNS |
|
||||
| --- | --- | --- | --- |
|
||||
| Familie | `10.0.0.0/24` | `10.0.0.0/24` | `10.0.0.1` |
|
||||
| Server Admin | freigegebene Server jeweils `/32` | dieselben Serveradressen ausdrücklich eintragen | zunächst leer / System-DNS |
|
||||
| LLM Admin | `10.0.0.90/32` | `10.0.0.90/32` | leer / System-DNS |
|
||||
|
||||
Für Server Admins enthält das Quelleninventar derzeit Proxmox `.2` sowie `.4`, `.10`, `.11`, `.12`, `.15`, `.17`, `.23`, `.47` und KI-Server `.90`. Vor Vergabe in Proxmox mit der tatsächlichen Belegung abgleichen. Beispiel nach bestätigtem Inventarabgleich:
|
||||
|
||||
```text
|
||||
10.0.0.2/32, 10.0.0.4/32, 10.0.0.10/32, 10.0.0.11/32, 10.0.0.12/32, 10.0.0.15/32, 10.0.0.17/32, 10.0.0.23/32, 10.0.0.47/32, 10.0.0.90/32
|
||||
```
|
||||
|
||||
Das ist eine Inventarliste, keine behauptete vollständige LXC-Erfassung. Neue Server einzeln ergänzen. Der geplante statische Bereich bis `.99` wird nicht automatisch freigegeben. Die Fritzbox `.1` ist keine implizite Server-Admin-Freigabe. DNS über die Fritzbox für diese Rolle benötigt eine separate Entscheidung und Freigabe, gegebenenfalls gezielt TCP/UDP 53.
|
||||
|
||||
Zugriff auf `10.8.0.1` oder andere VPN-Peers ist in diesen Basislisten nicht enthalten. Bei Bedarf gesondert beschließen und sowohl Routing als auch Firewall ergänzen. Familie hat mit `10.0.0.0/24` Zugriff auf Heimnetz-Clients, nicht automatisch auf sämtliche anderen VPN-Peers.
|
||||
|
||||
## 3. Einmalige Umstellung auf Per-Client Firewall
|
||||
|
||||
1. Vor Änderung konsistentes Backup und aktuelle Regeln sichern; Arbeiten über LAN/Proxmox-Konsole durchführen.
|
||||
2. Bestehende Peers, ihre VPN-IP, Gerät und Rolle erfassen. Der alte Name „FullAdmin“ unterscheidet Familie und Server Admin nicht. Unzugeordnete Peers deaktivieren.
|
||||
3. In **Admin Panel → Interface** **Per-Client Firewall** einschalten und speichern. Sichtbarkeit und Funktion im installierten v15.4.0 prüfen. Falls das Feld fehlt oder eine Fehlermeldung erscheint, nicht auf clientseitiges Routing als Ersatz ausweichen.
|
||||
4. Die zugeordneten Peers nacheinander bearbeiten und ausdrückliche **Firewall Allowed IPs** setzen. Die Fallback-Wirkung leerer Felder nicht als Rollenpolitik verwenden.
|
||||
5. Gateway-INPUT-Zugriff für Familie und Server Admin anhand der bestätigten VPN-IP-Zuordnung ergänzen. wg-easy-Port 51821 und SSH-Port 22 für LLM Admin prüfen und sperren; GUI-Einstellungen allein beweisen diese INPUT-Beschränkung nicht.
|
||||
6. Serverregeln und Hooks prüfen. Positive und negative Tests aus Abschnitt 7 ausführen. Erst danach Peers für die neue Rollenpolitik freigeben.
|
||||
|
||||
Die offizielle Dokumentation kennzeichnet Per-Client Firewall als experimentell; sie benötigt eine funktionierende iptables-Umgebung. [Admin Panel](https://wg-easy.github.io/wg-easy/latest/guides/admin/)
|
||||
|
||||
## 4. Neuen Geräteclient anlegen und Profil verteilen
|
||||
|
||||
1. In wg-easy anmelden und über die Funktion zum Hinzufügen eines Clients einen neuen Eintrag erstellen. Die konkrete Schaltflächenbeschriftung kann je nach Sprache abweichen.
|
||||
2. Einen eindeutigen Gerätenamen setzen und Besitzer, Rolle, Datum und Zweck im Peer-Verzeichnis erfassen. Kurze technische Profilnamen verwenden, beispielsweise `gnai-laptop`; Linux-Interface-Namen sind auf 15 Zeichen begrenzt.
|
||||
3. Den Eintrag bis zur abgeschlossenen Konfiguration deaktiviert halten. Falls die GUI das Anlegen nur aktiviert ermöglicht, direkt deaktivieren und noch kein Profil verteilen.
|
||||
4. Zugewiesene IPv4-Adresse im VPN-Netz prüfen: Server `.1`, Endgeräte eindeutige freie Adressen. Adressen bestehender Peers nicht versehentlich wiederverwenden.
|
||||
5. Client-Details öffnen. **Allowed IPs**, **Firewall Allowed IPs** und **DNS** gemäß Rolle setzen. **Server Allowed IPs** bei einem einfachen Endgerät auf dessen eigene VPN-IP `/32` belassen.
|
||||
6. Endpoint kontrollieren: `vpn.ghostnet.selfhost.eu`, UDP-Port `51820`, DNS-Abgleich mit aktueller WAN-IP. MTU zunächst beim geprüften Default belassen. Keepalive ist im Altbestand `0`; bei Bedarf für Geräte hinter NAT gezielt `25` Sekunden konfigurieren und testen.
|
||||
7. Client-Hooks leer lassen, damit das Profil auch in Windows und NetworkManager importierbar bleibt. Server-Hooks für NAT nicht mit diesen Client-Hooks verwechseln.
|
||||
8. Änderungen speichern. Über die Download-Funktion das aktualisierte `.conf` exportieren. Für die vorgesehenen Windows-/Linux-Verfahren wird die Datei verwendet.
|
||||
9. Lokal prüfen: eigene `Address`, richtiger Endpoint, rollenabhängige AllowedIPs/DNS, kein unbeabsichtigtes `0.0.0.0/0` oder `::/0`. PrivateKey und PresharedKey dabei nicht in Dokumente oder Nachrichten kopieren.
|
||||
10. Profil über einen geschützten, für den Empfänger bestimmten Kanal verteilen. Das Profil ist ein Zugangsschlüssel. Keine öffentlichen Links, gemeinsamen Ordner oder offenen E-Mail-/Chat-Verteiler verwenden.
|
||||
11. Peer kontrolliert aktivieren und mit dem Nutzer die Client-SOP und rollenabhängigen Abnahmen durchführen. Danach Status und Datum eintragen; ungeschützte Downloadkopien entfernen.
|
||||
|
||||
Die Unterscheidung von Routing, serverseitigen Zielrechten und Client-Hooks wird in der [offiziellen Feldreferenz](https://wg-easy.github.io/wg-easy/latest/guides/clients/) erläutert. Das Server-Firewallfeld ist kein Bestandteil des exportierten WireGuard-Profils.
|
||||
|
||||
## 5. Bestehenden Client ändern
|
||||
|
||||
Vor Änderung aktuelle Rolle und Freigaben erfassen. Bei Rollensenkung den Peer zunächst deaktivieren, Serverrechte einschränken und aktualisiertes Routingprofil verteilen; erst nach Prüfung wieder aktivieren. Änderungen an AllowedIPs, DNS, Endpoint, MTU oder Keepalive benötigen einen neuen Export und eine Aktualisierung auf dem Endgerät. Server-Firewalländerungen wirken serverseitig, werden aber ebenfalls getestet und dokumentiert.
|
||||
|
||||
Ein Serverneuzugang erweitert nur die Server-Admin-Profile, die diesen Host tatsächlich benötigen. Namen ändern widerruft keine Schlüssel. Änderungen an erzeugten `wg0.conf`-Dateien oder direkte SQLite-Manipulation gehören nicht zum Regelbetrieb.
|
||||
|
||||
## 6. Deaktivieren, löschen und Schlüssel ersetzen
|
||||
|
||||
**Temporäre Sperre:** Client über seinen Aktivierungsstatus deaktivieren. Prüfen, dass der Peer aus der aktiven Serverkonfiguration entfernt wurde und keine neue Verbindung mehr funktioniert. Reaktivieren nur nach Prüfung des Sperrgrunds.
|
||||
|
||||
**Geräteverlust oder vermutete Schlüsseloffenlegung:** Betroffenen Peer sofort deaktivieren bzw. löschen. Einen neuen Client mit neuen Schlüsseln erstellen, konfigurieren und verteilen. Ein neuer Dateiname oder erneuter Download desselben Peers ist keine Schlüsselrotation. Ein gesperrter oder gelöschter Peer wird nicht durch bloßes Entfernen der Datei auf dem Client widerrufen.
|
||||
|
||||
**Dauerhaft entfernen:** Besitzer informieren, Peer löschen, Inventar und Widerrufsliste aktualisieren, Clientprofil entfernen und alte Exporte vernichten. Keine vollständigen geheimen Profile zur Nachvollziehbarkeit archivieren. Nach Restore die Widerrufsliste anwenden.
|
||||
|
||||
## 7. Rollenprüfung und Betriebsabnahme
|
||||
|
||||
| Test | Familie | Server Admin | LLM Admin |
|
||||
| --- | --- | --- | --- |
|
||||
| KI-Server-Dienst auf `.90` | erlaubt | erlaubt | erlaubt |
|
||||
| Proxmox `10.0.0.2:8006` | erlaubt | erlaubt | gesperrt |
|
||||
| wg-easy `10.0.0.15:51821` | erlaubt | erlaubt | gesperrt |
|
||||
| NPM Admin `10.0.0.10:81` | erlaubt | erlaubt | gesperrt |
|
||||
| aktiver Heimnetz-PC im DHCP-Bereich | erlaubt, soweit Hostdienst freigegeben | gesperrt | gesperrt |
|
||||
| normales Internet | direkt | direkt | direkt |
|
||||
|
||||
Für Sperrtests die clientseitigen AllowedIPs bewusst um ein verbotenes Ziel ergänzen oder ein kontrolliertes Testprofil mit breiterem Routing nutzen. Derselbe Zielservice muss von einem erlaubten Peer erreichbar sein. Auf dem Gateway Regeln und Zähler kontrollieren; nur fehlendes Routing oder ein ausgeschalteter Zielhost sind kein Firewallnachweis. Testprofil danach zurückbauen.
|
||||
|
||||
Im Status prüfen: letzter Handshake und steigende Transferwerte unter erzeugtem Verkehr. Ein eingeschalteter Client allein beweist keine Verbindung. Vor der Produktionsabnahme auch Dienstneustart, Firewall-Reload und LXC-/Host-Wiederanlauf prüfen.
|
||||
|
||||
## 8. Nachweis und Abschluss
|
||||
|
||||
Pro Peer Besitzer, Gerät, neue Rolle, VPN-IP, Freigaben, Aktivierungsstatus, Ausgabedatum und Abnahme erfassen. PrivateKeys, PresharedKeys, GUI-Passwörter und QR-Codes nicht aufnehmen. Neue Rollen sind erst nach erfolgreicher serverseitiger Durchsetzung freigegeben. Die vorhandenen Altpeers und ihre neuen Rollen sind noch mit dem Betreiber abzugleichen.
|
||||
@@ -0,0 +1,168 @@
|
||||
# SOP – WireGuard unter Linux einrichten und verwenden
|
||||
|
||||
**Dokumenten-ID:** GNAI-006-SEC-SOP-03
|
||||
**Plattformen:** Debian, Arch/CachyOS und Fedora; Fedora Kinoite gesondert berücksichtigt
|
||||
**Status:** Anleitung bereinigt; bisheriger CachyOS-CLI-Test teilweise bestanden, übrige Varianten nicht abgenommen
|
||||
**Referenzen:** [Gateway](GNAI-006-SEC_VPN.md), [Profilverwaltung](GNAI-006-SEC_VPN_Client-Management.md)
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Änderung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-09-09 | 1.0 | spektr | Erste Clientanleitung für Linux mit KDE Plasma erstellt. |
|
||||
| 2026-09-15 | 2.0 | spektr | Debian, Arch/CachyOS, Fedora und Kinoite getrennt beschrieben; NetworkManager und wg-quick, Geheimnisschutz, Fehlersuche und belegten Teiltest überarbeitet. |
|
||||
|
||||
## 1. Voraussetzungen und Begriffe
|
||||
|
||||
Du benötigst ein eigenes `.conf`-Profil vom Administrator, sudo-Berechtigung für die Einrichtung und Internetzugang. Der Administrator nennt deine Rolle und ein erreichbares Testziel. Du benötigst keine wg-easy-Anmeldung.
|
||||
|
||||
Das Profil enthält geheime Schlüssel: **PrivateKey und PresharedKey** dürfen nicht geteilt werden. PublicKeys sind öffentlich, die vollständige Datei ist dennoch geheim. Jeder Rechner verwendet einen eigenen Peer. Serverdienste verlangen weiterhin ihre eigene Anmeldung.
|
||||
|
||||
Bei Split-Tunneling gehen nur freigegebene Ziele durch WireGuard, normale Internetverbindungen bleiben direkt. Wähle **eine** der Methoden: NetworkManager oder wg-quick. Beide dürfen dasselbe Profil nicht gleichzeitig aktivieren.
|
||||
|
||||
## 2. Software bereitstellen
|
||||
|
||||
| Distribution | Installation der WireGuard-Werkzeuge |
|
||||
| --- | --- |
|
||||
| Debian | `sudo apt update`, anschließend `sudo apt install wireguard-tools` |
|
||||
| Arch / CachyOS | `sudo pacman -S wireguard-tools` |
|
||||
| Fedora, klassisch | `sudo dnf install wireguard-tools` |
|
||||
| Fedora Kinoite | falls Werkzeuge fehlen: `sudo rpm-ostree install wireguard-tools`, anschließend in die neue Deployment-Version neu starten |
|
||||
|
||||
Die offiziellen Distributionsbefehle stehen auf der [WireGuard-Installationsseite](https://www.wireguard.com/install/). Aktuelle Standardkernel dieser Distributionen unterstützen WireGuard; bei angepassten Kerneln muss der Administrator dies prüfen. DKMS nicht pauschal installieren.
|
||||
|
||||
Für NetworkManager muss dessen Dienst vorhanden und aktiv sein; auf KDE wird die Netzwerkoberfläche durch `plasma-nm` bereitgestellt, nicht durch ein automatisch von wireguard-tools erzeugtes Tray-Icon. Desktop-Installationen bringen das häufig bereits mit:
|
||||
|
||||
```bash
|
||||
nmcli --version
|
||||
systemctl is-active NetworkManager
|
||||
```
|
||||
|
||||
Wenn NetworkManager fehlt, klärt der Administrator zunächst, welcher Dienst dein Netzwerk verwaltet. Auf einem Debian-Server nicht parallel zur vorhandenen ifupdown-Konfiguration blind einen weiteren Netzwerkmanager einschalten.
|
||||
|
||||
## 3. Profilname und Aufbewahrung
|
||||
|
||||
Für diese Anleitung heißt die lokale Datei `gnai-laptop.conf`. Vom Administrator anders benannte Dateien gegebenenfalls im Dateimanager umbenennen. Der tatsächliche Name muss bei folgenden Befehlen passen. Linux-wg-quick verwendet den Dateinamen ohne `.conf` als Interface-Namen, **ohne `wg-`-Präfix**, maximal 15 Zeichen. [wg-quick-Implementierung](https://git.zx2c4.com/wireguard-tools/tree/src/wg-quick/linux.bash)
|
||||
|
||||
```bash
|
||||
chmod 600 "$HOME/Downloads/gnai-laptop.conf"
|
||||
```
|
||||
|
||||
## 4. Methode A: NetworkManager und Desktop
|
||||
|
||||
Für Desktop-Nutzer eignet sich die bestehende NetworkManager-Verwaltung. Unter KDE **Systemeinstellungen → Verbindungen** öffnen und die Funktion zum Importieren einer Verbindung verwenden, sofern deine Version WireGuard-Dateiimport anbietet. Wenn die Oberfläche diese Funktion nicht anbietet, ist der folgende Import eindeutig; danach erscheint die Verbindung in der Desktop-Netzwerkverwaltung:
|
||||
|
||||
```bash
|
||||
sudo nmcli connection import type wireguard file "$HOME/Downloads/gnai-laptop.conf"
|
||||
nmcli connection show
|
||||
```
|
||||
|
||||
Den beim Import gemeldeten Verbindungsnamen verwenden. Bei abweichendem Namen in folgenden Befehlen `gnai-laptop` ersetzen:
|
||||
|
||||
```bash
|
||||
sudo nmcli connection modify gnai-laptop connection.autoconnect no
|
||||
sudo nmcli connection up gnai-laptop
|
||||
nmcli connection show --active
|
||||
ip -br addr
|
||||
```
|
||||
|
||||
Zum Trennen:
|
||||
|
||||
```bash
|
||||
sudo nmcli connection down gnai-laptop
|
||||
```
|
||||
|
||||
Alternativ über die Desktop-Netzwerkverwaltung verbinden/trennen. Verbindung erst nach Absprache automatisch starten lassen; Autoconnect-Verhalten wird beim Import nicht vorausgesetzt. NetworkManager speichert das Profil in seiner eigenen Verwaltung; die Downloaddatei ist danach nur eine zusätzliche Geheimniskopie. [NetworkManager-CLI](https://networkmanager.dev/docs/api/latest/nmcli.html)
|
||||
|
||||
## 5. Methode B: wg-quick, Terminal und systemd
|
||||
|
||||
Diese Methode verwendet die Datei `/etc/wireguard/gnai-laptop.conf`. Nur verwenden, wenn Methode A für dieses Profil nicht aktiv ist:
|
||||
|
||||
```bash
|
||||
sudo install -d -m 700 /etc/wireguard
|
||||
sudo install -m 600 "$HOME/Downloads/gnai-laptop.conf" /etc/wireguard/gnai-laptop.conf
|
||||
sudo wg-quick up gnai-laptop
|
||||
sudo wg show gnai-laptop
|
||||
ip -br addr show gnai-laptop
|
||||
```
|
||||
|
||||
Erwartet: Interface `gnai-laptop`, eigene Adresse `10.8.0.x`, ein Handshake nach Verkehr zu einem freigegebenen Ziel. Nicht pauschal `wg0` abfragen; das ist der Interface-Name auf dem Server.
|
||||
|
||||
**DNS-Abhängigkeit:** Wenn das Profil `DNS = ...` enthält, ruft Linux-wg-quick `resolvconf` auf. Vorher prüfen:
|
||||
|
||||
```bash
|
||||
command -v resolvconf
|
||||
```
|
||||
|
||||
Bei fehlendem Befehl nicht die DNS-Zeile ungeprüft entfernen. Der Administrator installiert eine zum vorhandenen Resolver passende resolvconf-Implementierung oder nutzt NetworkManager. Debian/Arch/Fedora verwenden nicht in jeder Installation denselben Resolver; deshalb wird kein pauschaler Paketwechsel vorgeschrieben. Profile mit leerem DNS-Feld verwenden System-DNS.
|
||||
|
||||
Zum Trennen:
|
||||
|
||||
```bash
|
||||
sudo wg-quick down gnai-laptop
|
||||
```
|
||||
|
||||
Optionaler Autostart, erst nach erfolgreicher Prüfung und Absprache:
|
||||
|
||||
```bash
|
||||
sudo systemctl enable wg-quick@gnai-laptop.service
|
||||
```
|
||||
|
||||
Dies richtet den Bootstart ein. Für systemd-Verwaltung nach einem manuellen `wg-quick down`:
|
||||
|
||||
```bash
|
||||
sudo systemctl start wg-quick@gnai-laptop.service
|
||||
sudo systemctl status wg-quick@gnai-laptop.service
|
||||
```
|
||||
|
||||
Autostart entfernen und systemd-verwaltete Verbindung stoppen:
|
||||
|
||||
```bash
|
||||
sudo systemctl disable --now wg-quick@gnai-laptop.service
|
||||
```
|
||||
|
||||
## 6. Verbindung prüfen
|
||||
|
||||
Die erste Abnahme von einem fremden Netz ausführen, beispielsweise Smartphone-Hotspot. Zuerst einen tatsächlich freigegebenen Dienst aufrufen:
|
||||
|
||||
| Rolle | Testziel |
|
||||
| --- | --- |
|
||||
| Familie | Proxmox `https://10.0.0.2:8006` und ein bekannter Heimnetz-PC |
|
||||
| Server Admin | Proxmox oder bekannter freigegebener LXC-Dienst |
|
||||
| LLM Admin | bekannter Dienst auf `10.0.0.90`, gegebenenfalls SSH mit eigenem SSH-Key |
|
||||
|
||||
Ein Ping ist ergänzend möglich, aber Host-Firewalls können ihn sperren. Ein ausgeschalteter KI-Server ist kein geeignetes Testziel. `10.8.0.1` ist nur dann ein Testziel, wenn der Administrator Zugriff darauf ausdrücklich freigegeben hat.
|
||||
|
||||
```bash
|
||||
ip -4 route get 10.0.0.90
|
||||
sudo wg show
|
||||
```
|
||||
|
||||
Der Routenbefehl ist für Rollen geeignet, denen `.90` freigegeben wurde. Für Rollenprüfungen am Server reicht fehlendes Client-Routing nicht als Sperrnachweis.
|
||||
|
||||
Öffentliche IPv4-Adresse vor und nach der Aktivierung im selben fremden Netz vergleichen:
|
||||
|
||||
```bash
|
||||
curl -4 https://ifconfig.co/ip
|
||||
```
|
||||
|
||||
Erwartet: Außenadresse des verwendeten Netzes bleibt gleich, normale Internetnutzung bleibt direkt. `-4` erzwingt einen IPv4-Test. Ein direkter IPv6-Internetpfad ist im vorgesehenen IPv4-Split-Tunnel keine zusätzliche VPN-Route. Bei Internetproblemen auch DNS prüfen: DNS kann über das VPN laufen, obwohl der übrige Internetverkehr direkt bleibt.
|
||||
|
||||
## 7. Fehlersuche
|
||||
|
||||
| Symptom | nächster Schritt |
|
||||
| --- | --- |
|
||||
| Datei nicht gefunden / ungültiger Interface-Name | Pfad, `.conf`-Endung und maximal 15 Zeichen im Basisnamen prüfen |
|
||||
| kein Handshake | Internet prüfen, erlaubtes Ziel aufrufen; Administrator kontrolliert tatsächlichen Endpoint-DNS und UDP-Weiterleitung |
|
||||
| Handshake, aber Dienst unerreichbar | Zielstatus, Rolle, Routen, Server-Firewall und NAT vom Administrator prüfen lassen |
|
||||
| `resolvconf: command not found` | bei wg-quick DNS-Abhängigkeit aus Abschnitt 5 klären |
|
||||
| `Operation not permitted` | sudo bzw. Systemrechte prüfen; Datei-ACLs oder Gruppenzugehörigkeit ersetzen keine benötigten Netzwerkprivilegien |
|
||||
| Interface bereits vorhanden | andere Verwaltung oder zweite Aktivierung desselben Profils prüfen; Methoden nicht mischen |
|
||||
| KDE-Verbindung fehlt | NetworkManager und plasma-nm sowie Import prüfen; kein pauschaler Plasma-Neustart erforderlich |
|
||||
| fremdes Netz verwendet ebenfalls `10.0.0.0/24` | Adressüberschneidung melden und über anderes Netz gegenprüfen |
|
||||
|
||||
Bei neuem Profil erst die alte Verbindung trennen. Bei NetworkManager nach Absprache den alten Eintrag entfernen und neu importieren; bei wg-quick Datei geschützt ersetzen und wieder starten. Exporte nicht unter offen lesbaren Pfaden belassen. Geräteverlust oder Offenlegung sofort melden, damit der Administrator den Peer serverseitig widerruft.
|
||||
|
||||
## 8. Abnahmestand
|
||||
|
||||
Am 12.09.2026 wurde ein CachyOS-Laptop mit wg-quick von außerhalb des Heimnetzes getestet: Handshake, Ping auf das VPN-Gateway und Proxmox sowie direkter IPv4-Internetpfad bestanden. KI-Server war ausgeschaltet. Dieser historische Test bestätigt weder NetworkManager-/Fedora-/Debian-Verfahren noch die neue Rollen-Firewall; diese Abnahmen stehen aus.
|
||||
@@ -0,0 +1,95 @@
|
||||
# SOP – WireGuard unter Windows 11 einrichten und verwenden
|
||||
|
||||
**Dokumenten-ID:** GNAI-006-SEC-SOP-02
|
||||
**Status:** Anleitung bereinigt; Windows-Praxistest noch offen
|
||||
**Referenzen:** [Gateway](GNAI-006-SEC_VPN.md), [Profilverwaltung für Administratoren](GNAI-006-SEC_VPN_Client-Management.md)
|
||||
|
||||
## Änderungsverlauf
|
||||
|
||||
| Datum | Version | Autor | Änderung |
|
||||
| --- | --- | --- | --- |
|
||||
| 2026-09-09 | 1.0 | spektr | Erste Clientanleitung für Windows 11 erstellt. |
|
||||
| 2026-09-15 | 2.0 | spektr | Installation, Profilimport, Split-Tunneling, Geheimnisschutz, Fehlersuche und noch offene Praxisabnahme überarbeitet. |
|
||||
|
||||
## 1. Was du benötigst
|
||||
|
||||
WireGuard verbindet deinen Rechner mit den für dich freigegebenen Geräten im Heimnetz. Es ersetzt weder Windows-Anmeldungen noch SSH-Schlüssel oder Passwörter für Serverdienste. Normale Internetverbindungen bleiben bei diesem Projekt außerhalb des VPN-Tunnels; das heißt Split-Tunneling.
|
||||
|
||||
Du benötigst Windows 11, Administratorrechte für die Installation, Internetzugang und eine eigene `.conf`-Datei vom Administrator. Der Administrator nennt dir deine Rolle und ein erreichbares Testziel. Du meldest dich zum Beziehen des Profils nicht an der wg-easy-Verwaltungsoberfläche an.
|
||||
|
||||
Jedes Gerät erhält ein eigenes Profil. Die Datei enthält den PrivateKey und gegebenenfalls einen PresharedKey. Beide sind geheim; behandle die vollständige Datei wie ein Passwort. Lege sie nicht in öffentlichen oder gemeinsam genutzten Ordnern ab.
|
||||
|
||||
## 2. Offiziellen Client installieren
|
||||
|
||||
1. [WireGuard-Installationsseite](https://www.wireguard.com/install/) öffnen und den **Windows Installer** herunterladen.
|
||||
2. Installer ausführen und die Windows-Rückfrage zu Administratorrechten bestätigen.
|
||||
3. WireGuard öffnen. Der Installer installiert auch den benötigten WireGuardNT-Treiber. Hyper-V oder ein angebliches optionales „Windows Internal WireGuard“-Feature sind nicht erforderlich. [Offizieller Windows-Client](https://github.com/WireGuard/wireguard-windows/blob/master/README.md)
|
||||
|
||||
## 3. Eigenes Profil importieren
|
||||
|
||||
1. Vom Administrator erhaltene Profil-Datei lokal in deinem persönlichen Benutzerordner speichern. Als kurzen Namen beispielsweise `gnai-laptop.conf` verwenden; Dateiendung `.conf` beibehalten.
|
||||
2. WireGuard öffnen und **Tunnel hinzufügen → Tunnel aus Datei importieren** wählen; englisch **Add Tunnel → Import tunnel(s) from file**.
|
||||
3. Deine `.conf` auswählen. Der Tunnel erscheint in der Liste.
|
||||
4. Den Eintrag auswählen. Name und freigegebene Zielnetze mit den Angaben des Administrators abgleichen. Schlüssel nicht in Screenshots oder Supportnachrichten zeigen.
|
||||
|
||||
Falls beim Import ein Fehler erscheint, den genauen Fehlertext und die Clientversion an den Administrator geben; keine vollständige Profil-Datei in einen offenen Chat kopieren. Eine neue Datei vom Administrator kann eine ältere importierte Verbindung ersetzen; dafür den alten Tunnel zuerst deaktivieren und nach Absprache entfernen.
|
||||
|
||||
## 4. Verbinden und trennen
|
||||
|
||||
1. Für die erste Prüfung ein anderes Netz verwenden, etwa einen Smartphone-Hotspot. Ein Test im eigenen Heimnetz beweist keinen funktionierenden Fernzugriff.
|
||||
2. Tunnel in WireGuard auswählen und **Aktivieren / Activate** anklicken.
|
||||
3. Ein freigegebenes Ziel aufrufen. Die Verbindung erzeugt dann Verkehr; anschließend sollten ein aktueller Handshake und steigende Transferwerte angezeigt werden.
|
||||
4. Zum Trennen **Deaktivieren / Deactivate** anklicken.
|
||||
|
||||
„Aktiv“ bedeutet zunächst, dass der lokale Tunnel eingeschaltet ist. Erst erfolgreicher Verkehr zu einem erlaubten Ziel bzw. ein Handshake beweist die VPN-Verbindung. WireGuard benötigt keinen besonderen Schildindikator im Windows-Netzwerksymbol.
|
||||
|
||||
## 5. Verbindung prüfen
|
||||
|
||||
| Rolle | geeigneter Test | erwartetes Verhalten |
|
||||
| --- | --- | --- |
|
||||
| Familie | `https://10.0.0.2:8006` und ein vom Administrator genannter Heimnetz-PC | freigegebene Dienste erreichbar |
|
||||
| Server Admin | `https://10.0.0.2:8006` oder ein bekannter LXC-Dienst | Server erreichbar; gewöhnliche Heimnetz-PCs nicht freigegeben |
|
||||
| LLM Admin | vom Administrator genannter Dienst auf `10.0.0.90` | KI-Server erreichbar; Proxmox/NPM/wg-easy nicht freigegeben |
|
||||
|
||||
Ein Zertifikatshinweis bei einer Server-IP ist getrennt vom VPN zu behandeln: den Fingerprint bzw. vorgesehenen Hostnamen beim Administrator verifizieren, nicht wahllos Ausnahmen bestätigen. Ein fehlender Ping kann an einer Host-Firewall liegen; ein ausgeschalteter Server ist kein VPN-Testziel.
|
||||
|
||||
Optional in PowerShell, am Beispiel eines vom Administrator freigegebenen SSH-Ziels:
|
||||
|
||||
```powershell
|
||||
Test-NetConnection -ComputerName 10.0.0.90 -Port 22
|
||||
Get-NetIPAddress -AddressFamily IPv4 |
|
||||
Where-Object { $_.IPAddress -like '10.8.0.*' }
|
||||
```
|
||||
|
||||
Für den Split-Tunnel-Test die öffentliche IPv4-Adresse vor und nach dem Aktivieren im **gleichen fremden Netz** vergleichen:
|
||||
|
||||
```powershell
|
||||
curl.exe -4 https://ifconfig.co/ip
|
||||
```
|
||||
|
||||
Sie soll weiterhin die Außenadresse des verwendeten Netzes anzeigen. Eine private `10.0.0.x`-Adresse wird von einem öffentlichen IP-Abfragedienst ohnehin nicht angezeigt. Ein Wechsel auf die öffentliche Heimnetz-Adresse wäre ein Hinweis auf unerwartetes Full-Tunnel-Routing. Während des Vergleichs nicht zwischen WLAN und Mobilfunk wechseln.
|
||||
|
||||
Die technische Rollenisolierung wird vom Administrator zusätzlich mit absichtlich verändertem Client-Routing geprüft. Ein bei dir fehlender Routeneintrag allein beweist keine serverseitige Sperre.
|
||||
|
||||
## 6. Alltag und Netzwerkwechsel
|
||||
|
||||
Ein aktivierter Tunnel läuft als Windows-Tunneldienst; das Schließen des GUI-Fensters ist nicht dasselbe wie Deaktivieren. Nach einem Neustart und nach Netzwechsel den tatsächlichen Tunnelzustand prüfen. Ein automatischer Start wird nur nach Absprache eingerichtet und separat getestet; diese SOP setzt keinen erfundenen GUI-Autostartschalter voraus.
|
||||
|
||||
Bei einem Netzwerkwechsel kurz warten und Verkehr zu einem erlaubten Ziel erzeugen. Bleibt die Verbindung aus, einmal deaktivieren und aktivieren. Gleichzeitige weitere VPN-Clients können Routen oder DNS verändern; dem Administrator deren Namen nennen.
|
||||
|
||||
## 7. Fehlersuche und Sicherheit
|
||||
|
||||
| Symptom | nächster Schritt |
|
||||
| --- | --- |
|
||||
| kein Handshake | Internetzugang prüfen, Tunnel neu aktivieren; Administrator prüft Endpoint-DNS und UDP-Portweiterleitung |
|
||||
| Handshake vorhanden, Dienst nicht erreichbar | richtige Rolle, Ziel-IP, Port und Serverzustand mit Administrator prüfen |
|
||||
| Internet funktioniert, interne Namen nicht | DNS-Verhalten melden; ohne ausdrückliche DNS-Freigabe System-DNS verwenden |
|
||||
| Import-/Treiberfehler | offiziellen Installer reparieren bzw. neu installieren; Fehlertext melden, kein Hyper-V-Feature aktivieren |
|
||||
| Aktivierung verweigert | Windows-Berechtigungen prüfen lassen; Firewall nicht pauschal deaktivieren |
|
||||
| fremdes WLAN nutzt ebenfalls `10.0.0.0/24` | mögliche Adressüberschneidung melden und etwa per Hotspot gegenprüfen; Routen nicht auf Verdacht ändern |
|
||||
|
||||
Nach erfolgreichem Import ungeschützte Downloadkopien löschen. Unterstützte interne Profilspeicherung ersetzt keine Rechteprüfung für eigene Backups. Bei Geräteverlust oder Profiloffenlegung sofort den Administrator informieren; nur serverseitiger Widerruf sperrt den Zugang zuverlässig. [Windows-Dienstmodell](https://github.com/WireGuard/wireguard-windows/blob/master/docs/enterprise.md)
|
||||
|
||||
## 8. Abnahme
|
||||
|
||||
Administrator und Nutzer dokumentieren Profilname, Gerät, Rolle, Datum, fremdes Testnetz, Handshake, erreichbaren Dienst und Split-Tunnel-Ergebnis. PrivateKey und PresharedKey bleiben aus dem Nachweis ausgeschlossen. Für Windows liegt bislang kein praktischer Abnahmenachweis vor.
|
||||
@@ -0,0 +1,138 @@
|
||||
# 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/platform/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.
|
||||
@@ -0,0 +1,4 @@
|
||||
# Secrets: WireGuard PrivateKeys/PresharedKeys – niemals committen
|
||||
*
|
||||
!.gitignore
|
||||
!README.md
|
||||
@@ -0,0 +1,21 @@
|
||||
# Plattform- und Hostdokumentation
|
||||
|
||||
Dieser Bereich enthält die gemeinsame Infrastruktur, auf der KI- und
|
||||
Encoding-Workloads aufbauen. Dazu gehören Hostinstallation, Benutzer und SSH,
|
||||
das übergreifende Zugriffsmodell, Reverse Proxy und VPN. Workload-spezifische
|
||||
Architektur und Nutzerverfahren liegen in den jeweiligen Nachbarverzeichnissen.
|
||||
|
||||
| Dokument | Inhalt |
|
||||
| --- | --- |
|
||||
| [GNAI-001](GNAI-001-INFRA_BaseSystem.md) | Hardware und Debian-Basisinstallation des KI-Servers |
|
||||
| [GNAI-002](GNAI-002-INFRA_Users.md) | Hostbenutzer, Netzwerk, Resolver und SSH |
|
||||
| [GNAI-004](GNAI-004-SEC_Access-Control.md) | Rollen- und Zugriffsziel für die Infrastruktur |
|
||||
| [GNAI-005](GNAI-005-SEC_Reverse-Proxy.md) | Reverse Proxy, Keycloak-Adminpfad und Fail2Ban |
|
||||
| [GNAI-006](GNAI-006-SEC_VPN.md) | WireGuard-Gateway und Rollen-Firewall |
|
||||
| [VPN-Client-Verwaltung](GNAI-006-SEC_VPN_Client-Management.md) | Profile ausgeben, ändern und widerrufen |
|
||||
| [Windows 11](GNAI-006-SEC_VPN_Clients_Windows11.md) | WireGuard-Client unter Windows 11 |
|
||||
| [Linux](GNAI-006-SEC_VPN_Clients_Linux.md) | WireGuard-Client unter unterstützten Linux-Varianten |
|
||||
| [VPN-Implementation-Log](GNAI-006-SEC_VPN_Implementation-Log.md) | historische Umsetzung, Tests und Evidenzkorrekturen |
|
||||
|
||||
Der übergreifende Projektstand steht im
|
||||
[zentralen Dokumentationsindex](../GNAI-000-DOC_Index.md).
|
||||
Reference in New Issue
Block a user