Add reproducible Docker and WireGuard host bootstrap
This commit is contained in:
+67
-92
@@ -1,107 +1,82 @@
|
||||
# Architektur
|
||||
# Zielarchitektur des neuen KI-Hosts
|
||||
|
||||
## Ziel
|
||||
## Grundsatz
|
||||
|
||||
Die Plattform stellt eine private, lokal betriebene OpenAI-kompatible API
|
||||
bereit. Jede Komponente hat genau eine Aufgabe und kann unabhängig ersetzt
|
||||
werden. Ein Neuaufbau darf keine Dateien vom alten Host voraussetzen, die nicht
|
||||
in diesem Repository oder im Modellmanifest beschrieben sind.
|
||||
Der Host läuft auf Debian 13. Das Betriebssystem darf im Universitätsnetz
|
||||
administrierbar bleiben; die KI-Plattform wird ausschließlich an die
|
||||
WireGuard-Adresse gebunden. KI-Container erreichen Heimnetz und Internet über
|
||||
den Heim-WireGuard-Peer. Bei Tunnelausfall verhindert eine Blackhole-Route den
|
||||
unbeabsichtigten Rückfall auf das Universitätsgateway.
|
||||
|
||||
## Komponenten
|
||||
```text
|
||||
Heimnetz / VPN-Clients
|
||||
|
|
||||
WireGuard
|
||||
|
|
||||
10.77.0.2:8080 Open WebUI
|
||||
10.77.0.2:8081 Profile Router API
|
||||
|
|
||||
Docker-intern
|
||||
+-- Profile Controller -- Docker Socket (feste Allowlist)
|
||||
+-- llama-fast --\
|
||||
+-- llama-medium > exakt einer aktiv
|
||||
+-- llama-long --/
|
||||
+-- llama-experimental
|
||||
+-- SearXNG + Web-MCP
|
||||
```
|
||||
|
||||
| Komponente | Port | Ausführung | Aufgabe |
|
||||
|---|---:|---|---|
|
||||
| AI Profile Router | 8081 | systemd, gehärtet | zentrale Client-API und Orchestrierung |
|
||||
| llama.cpp | 8080 | systemd | Textmodell, Tool Calling und MCP |
|
||||
| Whisper | 8084, nur localhost | systemd | Speech-to-Text |
|
||||
| XTTS | 8085, nur localhost | systemd | Text-to-Speech |
|
||||
| TinySearch | 8000, nur localhost | Docker | kompakte Websuche |
|
||||
| SearXNG | intern | Docker | Suchmaschinen-Metasuche |
|
||||
| LLama-GUI | 5240, optional | systemd | manuelle Administration |
|
||||
| Glances | lokal, optional | systemd | Systemmetriken |
|
||||
## Container und Vertrauensgrenzen
|
||||
|
||||
## Request-Fluss
|
||||
| Komponente | Außen erreichbar | Aufgabe |
|
||||
|---|---|---|
|
||||
| Open WebUI | nur WireGuard, Port 8080 | Chat-Oberfläche |
|
||||
| Profile Router | nur WireGuard, Port 8081 | OpenAI-API und Profilwahl |
|
||||
| Profile Controller | nein | startet ausschließlich vier bekannte Profile |
|
||||
| llama.cpp Profile | nein | Inferenz, Tool Calling, integrierte Vision |
|
||||
| SearXNG | nein | Websuche für den lokalen Web-MCP |
|
||||
|
||||
1. Ein Client verwendet ausschließlich Port 8081.
|
||||
2. Der Router veröffentlicht `qwen-fast`, `qwen-medium` und `qwen-long`.
|
||||
3. Passt das aktive Profil nicht zum virtuellen Modell, wird llama.cpp kontrolliert
|
||||
mit dem passenden Profil neu gestartet.
|
||||
4. Der Router wartet auf Modellname und erwartete Kontextgröße.
|
||||
5. Erst dann wird die Anfrage an Port 8080 weitergeleitet.
|
||||
|
||||
Profilwahl und Weiterleitung bilden dabei eine atomare Modell-Lease. Ein
|
||||
zweiter Request kann das Profil nicht mehr zwischen Auswahl und Inferenz
|
||||
wechseln. Laufende Requests werden vor einem GPU-Hotswap vollständig beendet;
|
||||
bei Überschreiten des Drain-Timeouts wird der Wechsel abgebrochen, nicht der
|
||||
Chat.
|
||||
Nur der Profile Controller erhält den Docker-Socket. Der Router erhält weder
|
||||
Socket noch Shell-Zugriff und kann dem Controller nur `fast`, `medium`, `long`
|
||||
oder `experimental` übergeben. Die llama-Container laufen ohne UI,
|
||||
Capabilities und Schreibzugriff auf die Modelldateien.
|
||||
|
||||
## Profilprinzip
|
||||
|
||||
Die Profile sind vollständige systemd-Overrides. Ein Profilwechsel kopiert die
|
||||
gewählte Datei atomar auf `override.conf`, lädt systemd neu und startet genau
|
||||
einen llama.cpp-Dienst neu. Es gibt niemals mehrere Textmodelle gleichzeitig.
|
||||
Das unabhängige Register `/etc/mike-ai/router-profiles.json` definiert Kontext
|
||||
und erwarteten Modellalias. Readiness gilt nur, wenn beides exakt passt; eine
|
||||
abweichende oder fehlende Registry verhindert den Start.
|
||||
Alle Profile verwenden dasselbe selbst gebaute llama.cpp-Image. Separate,
|
||||
normalerweise gestoppte Containerdefinitionen halten Parameter wie Kontext,
|
||||
MTP und CPU-Offload reproduzierbar. Ein Wechsel stoppt das alte Profil und
|
||||
startet genau einen bereits angelegten Container. Dadurch lassen sich Profile
|
||||
einzeln verändern oder duplizieren, ohne vier Modelle parallel im VRAM zu
|
||||
halten.
|
||||
|
||||
## GPU-Hotswap
|
||||
| Profil | Ausgangswert | Zweck |
|
||||
|---|---:|---|
|
||||
| fast | 76.800 Kontext, MTP | mindestens ungefähr 80 Token/s anstreben |
|
||||
| medium | 94.208 Kontext | mehr Kontext ohne CPU-FFN-Offload |
|
||||
| long | 131.072 Kontext | maximale Nutzbarkeit, CPU-Offload erlaubt |
|
||||
| experimental | 76.800 Kontext | isolierte Tests ohne Produktion zu ändern |
|
||||
|
||||
Vision und Bildgenerierung teilen sich die RTX mit dem Textmodell. Der Router:
|
||||
Diese Werte sind reproduzierbare Startwerte, keine Garantie. Nach Einbau der
|
||||
RTX 3060 werden sie auf dem Zielhost erneut gemessen. Die zweite Karte wird
|
||||
nicht automatisch in die Produktionsprofile aufgenommen.
|
||||
|
||||
1. sperrt die GPU-Orchestrierung,
|
||||
2. merkt sich das aktive Textprofil,
|
||||
3. stoppt llama.cpp,
|
||||
4. startet vorübergehend Vision oder FLUX,
|
||||
5. beendet den Hilfsprozess vollständig,
|
||||
6. stellt das ursprüngliche Textprofil wieder her,
|
||||
7. prüft Modell und Kontext vor der Freigabe.
|
||||
## Netzwerk
|
||||
|
||||
Der zuletzt stabile Zustand und temporäre Worker-PIDs werden atomar unter
|
||||
`/var/lib/mike-ai-profile-router/state.json` festgehalten. Beim Routerstart
|
||||
werden ausschließlich dort erfasste Prozesse nach zusätzlicher
|
||||
Kommandozeilenprüfung beendet und das letzte Profil wiederhergestellt.
|
||||
- Docker-Netze liegen ausschließlich unter `172.30.0.0/16`.
|
||||
- Open WebUI und Router binden an `AI_BIND_ADDRESS`, die WireGuard-IP.
|
||||
- Quellrouting schickt KI-Container in Tabelle 51820 über WireGuard.
|
||||
- Eine Blackhole-Default-Route bleibt als Fail-Closed-Fallback bestehen.
|
||||
- Firewallregeln gestatten aus dem VPN nur die beiden veröffentlichten Ports.
|
||||
- Der Host routet weder Universitätsverkehr ins Heimnetz noch Heimverkehr ins
|
||||
Universitätsnetz.
|
||||
- Das Heimnetz muss die Rückroute zur WireGuard-Adresse kennen. Soll auch der
|
||||
Internetzugang der KI über zuhause laufen, braucht der Heim-Peer zusätzlich
|
||||
IP-Forwarding und NAT ins Heim-WAN.
|
||||
|
||||
## Vertrauensgrenzen
|
||||
## Nicht automatisch installiert
|
||||
|
||||
- Port 8081 verlangt einen eigenen API-Key; nur `/health` und `/ready` sind
|
||||
absichtlich anonym und enthalten keine privaten Daten.
|
||||
- Der Client-Key wird vor dem lokalen Upstream entfernt.
|
||||
- Bild-Uploads sind begrenzt. Remote-Bild-URLs sind standardmäßig aus, damit
|
||||
der Vision-Pfad nicht als Zugriff auf Intranet oder Metadatenendpunkte dient.
|
||||
- Maximal 16 Requests werden gleichzeitig bearbeitet; weitere erhalten 429.
|
||||
- Der Dienst benötigt derzeit wegen systemd-Profilwechsel und GPU-Hotswap noch
|
||||
Root-Rechte. Die systemd-Sandbox begrenzt diese, ersetzt aber keine künftige
|
||||
Aufteilung in unprivilegierten Proxy und eng begrenzten Root-Helper.
|
||||
|
||||
## Verzeichnislayout auf dem Zielhost
|
||||
|
||||
```text
|
||||
/opt/mike-ai/
|
||||
ai-profile-router/ Routercode und eigenes Venv
|
||||
llama.cpp/ exakt ein produktiver Build
|
||||
models/ Modelle nach Manifest
|
||||
whisper.cpp/ Speech-to-Text Runtime
|
||||
xtts/ XTTS Runtime und Cache
|
||||
web-search/ Docker Compose für TinySearch/SearXNG
|
||||
|
||||
/etc/mike-ai/
|
||||
mcp-servers.json lokale, geheime produktive Konfiguration
|
||||
*.env Credentials, niemals im Git
|
||||
|
||||
/etc/systemd/system/
|
||||
mike-ai-*.service
|
||||
mike-ai-llama-ui.service.d/
|
||||
override.conf
|
||||
profile-fast.conf.disabled
|
||||
profile-medium.conf.disabled
|
||||
profile-long.conf.disabled
|
||||
```
|
||||
|
||||
## Nicht Teil der Zielarchitektur
|
||||
|
||||
- parallele llama.cpp-Builds
|
||||
- allgemeiner Shell-MCP im Standardprofil
|
||||
- doppelte Unraid-MCPs
|
||||
- RX-spezifische Dienste ohne eingebaute RX
|
||||
- automatisch startende Benchmark-Dienste
|
||||
- Modellkopien außerhalb des dokumentierten Modellverzeichnisses
|
||||
Bildgenerierung, Whisper, TTS sowie Home-Assistant-, ARR- und Unraid-MCPs sind
|
||||
Erweiterungen. Sie benötigen eigene Modelle, Rechte oder Secrets und bleiben
|
||||
im sauberen Basissystem deaktiviert. Multimodale Bildanalyse erfolgt direkt
|
||||
über Qwen plus Projektor. Nicht installierte Worker-Endpunkte antworten klar
|
||||
mit `feature_disabled`, statt alte systemd-Pfade aufzurufen.
|
||||
|
||||
@@ -36,6 +36,10 @@ Zielplattform.
|
||||
### Aktives Fast-Profil
|
||||
|
||||
- Qwen3.8-27B IQ4-MIX
|
||||
- Dateigröße: 14.111.614.400 Bytes
|
||||
- SHA256: `54879ae8738d5938f46cb3b8cbf16bf42b8c85b7d68d7c73f062b612ec183e36`
|
||||
- Öffentliche Herkunft ist noch nicht ausreichend dokumentiert; für eine
|
||||
bitgenaue Migration muss die geprüfte Datei vom Referenzhost gesichert werden.
|
||||
- Kontext 76.800
|
||||
- vollständig auf CUDA0
|
||||
- Flash Attention
|
||||
|
||||
+63
-76
@@ -1,97 +1,84 @@
|
||||
# Saubere Installation
|
||||
# Installation auf einem frischen Debian-Host
|
||||
|
||||
Diese Anleitung beschreibt den Neuaufbau. Sie löscht oder migriert keine Daten
|
||||
automatisch.
|
||||
Der automatisierte Weg ist `install.sh`. Das Skript ist für **Debian 12/13
|
||||
amd64** gedacht, installiert Docker CE, NVIDIA-Treiber/Container-Toolkit,
|
||||
WireGuard, baut llama.cpp reproduzierbar, lädt Modelle mit SHA256-Prüfung und
|
||||
startet den Stack.
|
||||
|
||||
## 1. Voraussetzungen
|
||||
## Vorher klären
|
||||
|
||||
- Debian 13 oder kompatibles Linux
|
||||
- NVIDIA-Treiber und funktionierendes `nvidia-smi`
|
||||
- Build-Werkzeuge, CMake, Git und CUDA Toolkit
|
||||
- Python 3.13 für Router/FLUX und Python 3.11 für XTTS
|
||||
- Docker plus Compose für Websuche
|
||||
- ausreichend freier Speicher; mindestens 15 Prozent auf `/`
|
||||
1. Die Universität muss den ausgehenden WireGuard-Tunnel erlauben.
|
||||
2. Heimnetz, Universitätsnetz und Docker-Netz dürfen sich nicht überschneiden.
|
||||
3. Der WireGuard-Heim-Peer braucht eine feste öffentliche Adresse oder DNS.
|
||||
4. Für KI-Internetzugang über zuhause: Forwarding und NAT am Heim-Peer.
|
||||
5. Das private Repository muss auf dem neuen Host lesbar sein.
|
||||
|
||||
## 2. Benutzer und Verzeichnisse
|
||||
## Debian installieren
|
||||
|
||||
Für produktive Dienste sollen eigene Systembenutzer verwendet werden. Der
|
||||
Router benötigt kontrollierte Berechtigung zum Neustart des llama.cpp-Dienstes;
|
||||
er sollte nicht dauerhaft als root laufen.
|
||||
- Debian 13 minimal, amd64, OpenSSH-Server, kein Desktop erforderlich.
|
||||
- Einen normalen Administrationsbenutzer mit sudo anlegen.
|
||||
- Optional bei physischem Fremdzugriff: LUKS-Verschlüsselung.
|
||||
- BIOS: Above 4G Decoding aktiv; beide GPUs sichtbar machen.
|
||||
|
||||
```text
|
||||
/opt/mike-ai/models
|
||||
/opt/mike-ai/ai-profile-router
|
||||
/etc/mike-ai
|
||||
## Konfiguration
|
||||
|
||||
```bash
|
||||
git clone <PRIVATE-REPOSITORY-URL> AI-Profile-Router
|
||||
cd AI-Profile-Router
|
||||
cp config/install.env.example config/install.env
|
||||
chmod 600 config/install.env
|
||||
editor config/install.env
|
||||
```
|
||||
|
||||
Geheimnisse werden mit Modus `0600` unter `/etc/mike-ai` abgelegt.
|
||||
Mindestens `ADMIN_USER`, `AI_BIND_ADDRESS`, `WG_ADDRESS`,
|
||||
`WG_PEER_PUBLIC_KEY`, `WG_ENDPOINT` und `WG_HOME_SUBNET` anpassen. Private
|
||||
WireGuard-, Router- und WebUI-Schlüssel werden lokal erzeugt und nur unter
|
||||
`/etc/mike-ai` gespeichert.
|
||||
|
||||
## 3. llama.cpp bauen
|
||||
## Installation starten
|
||||
|
||||
`platform/llama/build-llama-cpp.sh` checkt exakt den in
|
||||
`platform/llama/LLAMA_CPP_COMMIT` hinterlegten Commit aus. Vor einem Upgrade:
|
||||
|
||||
1. neuen Commit in einem separaten Build testen,
|
||||
2. Standardbenchmark ausführen,
|
||||
3. MCP-Grammatik und Tool Calls prüfen,
|
||||
4. Commitdatei erst danach aktualisieren.
|
||||
|
||||
## 4. Modelle bereitstellen
|
||||
|
||||
Modelldateien werden nicht in Git gespeichert. Die erwarteten Rollen und
|
||||
Zielpfade stehen in `platform/models/manifest.example.yaml`. Für die lokale
|
||||
Installation wird daraus eine nicht eingecheckte `manifest.local.yaml` mit
|
||||
SHA256-Prüfsummen erstellt.
|
||||
|
||||
## 5. llama.cpp-Dienst und Profile
|
||||
|
||||
Die Dateien aus `platform/systemd` und `platform/profiles` installieren. Danach:
|
||||
|
||||
```text
|
||||
llama-profile fast
|
||||
```bash
|
||||
sudo ./install.sh --config config/install.env
|
||||
```
|
||||
|
||||
Der Befehl muss Port 8080 erst freigeben, wenn Modell und Kontext korrekt sind.
|
||||
Wenn erstmals ein NVIDIA-Treiber installiert wurde, endet das Skript bewusst
|
||||
mit Code 20. Dann neu starten und denselben Befehl erneut ausführen. Das Skript
|
||||
ist auf Wiederholung ausgelegt und löscht keine vorhandenen Modelldateien.
|
||||
|
||||
## 6. MCP-Konfiguration
|
||||
Der Installer zeigt nur den öffentlichen WireGuard-Schlüssel. Diesen am
|
||||
Heim-Peer eintragen:
|
||||
|
||||
`platform/mcp/mcp-servers.example.json` nach `/etc/mike-ai/mcp-servers.json`
|
||||
kopieren und nur benötigte Server aktivieren. Zugangsdaten werden ausschließlich
|
||||
über lokale Environment-Dateien oder einen Secret Broker referenziert.
|
||||
```ini
|
||||
[Peer]
|
||||
PublicKey = <AUSGABE-DES-INSTALLERS>
|
||||
AllowedIPs = 10.77.0.2/32
|
||||
```
|
||||
|
||||
## 7. Router installieren
|
||||
Erst wenn der Tunnel steht, kann der Bootstrap fortfahren. API-Schlüssel
|
||||
werden nicht ausgegeben. Sie liegen root-only unter `/etc/mike-ai`.
|
||||
|
||||
Das bestehende `deploy/install.sh` installiert Router, Vision/Bild-Worker,
|
||||
Whisper und XTTS. Vor produktiver Verwendung müssen Modellpfade in der
|
||||
systemd-Datei gegen das lokale Manifest geprüft werden.
|
||||
## Ergebnis und Abnahme
|
||||
|
||||
Der Installer erzeugt `/etc/mike-ai/router-api-key` (0600), installiert das
|
||||
Profilregister und legt die atomare Zustandsablage an. Danach wird der Key
|
||||
einmal manuell in die Secret-Stores der erlaubten Clients übernommen. Er darf
|
||||
nicht im Terminal-Log, in Screenshots oder in Git dokumentiert werden.
|
||||
- Open WebUI: `http://<WIREGUARD-IP>:8080`
|
||||
- Router: `http://<WIREGUARD-IP>:8081`
|
||||
- llama.cpp-WebUI: absichtlich deaktiviert und nicht veröffentlicht
|
||||
|
||||
Der Router läuft aktuell als gehärteter Root-Dienst, weil er den
|
||||
llama.cpp-Systemdienst und temporäre GPU-Worker kontrolliert. Das ist eine
|
||||
bewusste Restabweichung. Ein späterer V3-Schritt soll den HTTP-Proxy als eigenen
|
||||
Benutzer ausführen und nur Profil-/Hotswap-Befehle an einen fest
|
||||
parametrisierten Root-Helper delegieren.
|
||||
```bash
|
||||
sudo systemctl status wg-quick@wg0 mike-ai-network-guard
|
||||
sudo docker compose --env-file /etc/mike-ai/stack.env \
|
||||
-f /opt/mike-ai/stack/compose.yaml ps
|
||||
curl http://<WIREGUARD-IP>:8081/health
|
||||
```
|
||||
|
||||
## 8. Websuche
|
||||
Zusätzlich prüfen: Uni-LAN sieht keine KI-Ports; Heimnetz erreicht beide;
|
||||
gestopptes WireGuard lässt KI-Container nicht ins Internet; jeder Profilwechsel
|
||||
startet exakt einen llama-Container; Text, Tool Call und Bild funktionieren.
|
||||
|
||||
TinySearch und SearXNG bleiben als einziges Docker-Teilsystem isoliert. Die
|
||||
Suchdienste sollen nur an localhost gebunden werden; nur der Web-MCP greift
|
||||
darauf zu.
|
||||
Die öffentliche Standardkonfiguration nutzt `UD-IQ4_XS`. Das bislang schnellste
|
||||
Referenzprofil nutzt dagegen die lokal vorhandene `IQ4-MIX`-Datei. Für eine
|
||||
bitgenaue Migration diese Datei anhand der in `CURRENT_REFERENCE.md`
|
||||
dokumentierten SHA256 in das Modellverzeichnis kopieren und die drei
|
||||
`*_MODEL_FILE`-Werte anpassen. Der Installer löscht vorhandene Modelle nicht.
|
||||
|
||||
## 9. Verifikation
|
||||
|
||||
`platform/checks/verify-platform.sh` kontrolliert:
|
||||
|
||||
- freien Plattenplatz,
|
||||
- GPU und VRAM,
|
||||
- aktive Dienste,
|
||||
- Ports,
|
||||
- Routermodelle und aktives Profil,
|
||||
- llama.cpp-Health,
|
||||
- unerwartete RX- und Benchmark-Dienste.
|
||||
|
||||
Erst nach erfolgreicher Prüfung werden Clients auf Port 8081 umgestellt.
|
||||
Open-WebUI-Daten liegen in einem Docker-Volume und müssen separat gesichert
|
||||
werden. Geheimnisse und Chatdaten gehören nie in Git.
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Roadmap: sauberer KI-Host
|
||||
|
||||
## Phase 0 – Entscheidungen und Freigaben
|
||||
|
||||
- VPN-Nutzung mit der Universität abstimmen.
|
||||
- Eindeutige Netze und Heim-WireGuard-Peer festlegen.
|
||||
- Festplattenverschlüsselung und Remote-Unlock entscheiden.
|
||||
- Repository- und Secret-Backup prüfen.
|
||||
|
||||
## Phase 1 – Grundsystem
|
||||
|
||||
- Debian 13 minimal und OpenSSH installieren.
|
||||
- Firmware/BIOS und beide NVIDIA-Karten prüfen.
|
||||
- Updates, Zeitsynchronisation und administrativen Zugang testen.
|
||||
|
||||
## Phase 2 – automatischer Bootstrap
|
||||
|
||||
- `config/install.env` ausfüllen.
|
||||
- `install.sh` ausführen, bei Treiberinstallation neu starten und wiederholen.
|
||||
- WireGuard-Peer zuhause ergänzen.
|
||||
- Docker-, GPU- und Fail-Closed-Netztest bestehen.
|
||||
|
||||
## Phase 3 – Inferenz abnehmen
|
||||
|
||||
- Fast/Medium/Long mit derselben Testserie messen.
|
||||
- Kontext, Prompt-Speed, Ausgabe-Speed und VRAM dokumentieren.
|
||||
- RTX 3060 zuerst nur im Experimentalprofil testen.
|
||||
- Erst nach Qualitäts- und Geschwindigkeitsvergleich Produktionswerte ändern.
|
||||
|
||||
## Phase 4 – optionale Fähigkeiten
|
||||
|
||||
- Home-Assistant-MCP mit kleinsten Rechten.
|
||||
- ARR-MCP zunächst read-only, Schreibaktionen mit Preview/Approval.
|
||||
- Unraid-/Docker-Zugriff über begrenzte Broker statt Shell-MCP.
|
||||
- Whisper, TTS oder Bildgenerierung jeweils als eigener Container.
|
||||
|
||||
## Phase 5 – Betrieb
|
||||
|
||||
- Open-WebUI-Volume, Konfigurationen und Secrets verschlüsselt sichern.
|
||||
- Image- und llama.cpp-Upgrades im Experimentalprofil testen.
|
||||
- Logs ohne Prompts/Secrets, Metriken für GPU, RAM und Tokenraten.
|
||||
- Recovery auf leerem Testsystem regelmäßig proben.
|
||||
|
||||
Fertig ist der Host erst, wenn er sich aus Repository und Secret-Backup neu
|
||||
erzeugen lässt, das Uni-Netz keine KI-Ports sieht, ein Tunnelverlust
|
||||
fail-closed ist und alle drei Profile den Standardbenchmark bestehen.
|
||||
@@ -55,16 +55,15 @@ Jede Komponente bekommt zusätzlich:
|
||||
- benötigte Environment-Namen ohne Werte
|
||||
- Liste read-only und schreibender Werkzeuge
|
||||
|
||||
## 3. Basissystem-Bootstrap – offen
|
||||
## 3. Basissystem-Bootstrap – umgesetzt, Praxistest offen
|
||||
|
||||
Ein idempotentes Bootstrap-Skript muss noch erstellen:
|
||||
`install.sh` erstellt inzwischen:
|
||||
|
||||
- Paketquellen und benötigte Debian-Pakete
|
||||
- NVIDIA-Treiber und exakte Version
|
||||
- CUDA Toolkit und Buildabhängigkeiten
|
||||
- Docker und Compose
|
||||
- Python 3.13 und Python 3.11/uv
|
||||
- Dienstbenutzer und Gruppen
|
||||
- die benötigten Container-Runtimes und Dienstbenutzer in Images
|
||||
- Verzeichnisse, Eigentümer und Dateirechte
|
||||
- Firewallregeln
|
||||
- Journalgrößenlimit
|
||||
@@ -91,7 +90,7 @@ Noch festzulegen:
|
||||
- Restore ohne Ausgabe der Werte in Terminal- oder Modellkontext
|
||||
- Funktionstest mit ausschließlich Statuscode, niemals Tokenanzeige
|
||||
|
||||
## 5. Netzwerk und DNS – offen
|
||||
## 5. Netzwerk und DNS – Vorlage umgesetzt, Standortwerte offen
|
||||
|
||||
Dokumentiert werden müssen:
|
||||
|
||||
@@ -157,9 +156,9 @@ Festlegen, welche Daten persistent sein sollen:
|
||||
- Benchmarkresultate: eigenes Repository
|
||||
- Logs: ohne Prompt- und Tool-Antwortinhalte
|
||||
|
||||
## 9. Ende-zu-Ende-Installer – offen
|
||||
## 9. Ende-zu-Ende-Installer – implementiert, Hardware-Abnahme offen
|
||||
|
||||
Der gewünschte Endzustand ist:
|
||||
Der Ablauf ist jetzt in `install.sh` zusammengeführt:
|
||||
|
||||
```text
|
||||
bootstrap-host
|
||||
|
||||
+50
-60
@@ -1,73 +1,63 @@
|
||||
# Sicherheitsmodell
|
||||
|
||||
## Grundsatz
|
||||
## Netzgrenze
|
||||
|
||||
Das lokale Modell erhält nur die Werkzeuge, die es für den aktuellen Modus
|
||||
benötigt. Lokalität allein ersetzt keine Zugriffskontrolle.
|
||||
- KI-Ports binden ausschließlich an die WireGuard-IP.
|
||||
- Docker-Netze `172.30.0.0/16` verwenden eine eigene Routingtabelle.
|
||||
- Heimnetz- und optionaler Internetverkehr laufen über WireGuard.
|
||||
- Eine Blackhole-Default-Route verhindert Fail-open bei Tunnelverlust.
|
||||
- `DOCKER-USER` erlaubt nur etablierte Verbindungen, KI→WireGuard und
|
||||
WireGuard→Open-WebUI/Router.
|
||||
- Der Host ist kein Router zwischen Universitäts- und Heimnetz.
|
||||
|
||||
## MCP-Profile
|
||||
Docker-publizierte Ports können gewöhnliche Host-Firewallregeln umgehen.
|
||||
Darum setzt der Installer seine Regeln ausdrücklich in `DOCKER-USER` und
|
||||
verlässt sich nicht allein auf UFW.
|
||||
|
||||
Empfohlene Trennung:
|
||||
## Containergrenzen
|
||||
|
||||
| Modus | Werkzeuge |
|
||||
- llama.cpp: read-only, keine Capabilities, Modelle read-only, keine Ports.
|
||||
- Router: unprivilegierter Benutzer, kein Docker-Socket, feste API-Oberfläche.
|
||||
- Profile Controller: einzige Socket-Ausnahme; feste Profile und nur
|
||||
List/Start/Stop, keine frei wählbaren Images, Befehle oder Mounts.
|
||||
- Open WebUI: einziges persistentes Chat-Volume.
|
||||
- SearXNG: intern, Suchanfragen ohne Chatverlauf.
|
||||
|
||||
Ein Docker-Socket bleibt grundsätzlich privilegiert. Der Controller reduziert
|
||||
die erreichbare Funktion stark, ersetzt aber keine zusätzliche Socket-Proxy-
|
||||
Sandbox. Er ist klein, testbar und nicht von Clients direkt erreichbar.
|
||||
|
||||
## Secrets und private Daten
|
||||
|
||||
- Keine Secrets in Git, Prompts, MCP-Schemas, Logs oder Screenshots.
|
||||
- Installer-Konfiguration und `/etc/mike-ai/*` haben restriktive Rechte.
|
||||
- Router-, Controller- und WebUI-Schlüssel sind getrennt und zufällig.
|
||||
- Das Modell bekommt keine Schlüsselwerte zurück; spätere Integrationen nutzen
|
||||
lokale Broker/Environment-Dateien.
|
||||
- Open-WebUI-Volume kann Chats enthalten und wird nur verschlüsselt gesichert.
|
||||
|
||||
## Werkzeugprofile
|
||||
|
||||
| Modus | Erlaubte Werkzeuge |
|
||||
|---|---|
|
||||
| Standard | Websuche, harmlose lokale Hilfsfunktionen |
|
||||
| Home Assistant | HA-Administration plus Websuche |
|
||||
| ARR | Sonarr/Radarr plus Websuche |
|
||||
| Unraid Read-only | Diagnose, Logs, Status |
|
||||
| Unraid Write | nur bewusst aktiviert, mit Vorschau und Approval Ticket |
|
||||
| Standard | lokale Websuche, harmlose Hilfsfunktionen |
|
||||
| Home Assistant | eigener begrenzter HA-MCP |
|
||||
| ARR | Sonarr/Radarr, zuerst read-only |
|
||||
| Unraid Diagnose | Status und eng begrenzte Logs |
|
||||
| Administration | Vorschau, Approval-Ticket, Verifikation |
|
||||
|
||||
## Nicht im Standardprofil
|
||||
|
||||
- allgemeine Shell
|
||||
- `python3`, `ssh`, `scp` oder beliebiges `curl`
|
||||
- Container erstellen, verändern oder löschen
|
||||
- Registry-/Storage-Direktzugriff
|
||||
- uneingeschränkte Dateisuche
|
||||
|
||||
## Secrets
|
||||
|
||||
- Keine Secrets in Git, Prompts, MCP-Schemas oder Logs.
|
||||
- Konfiguration referenziert nur Namen lokaler Environment-Dateien.
|
||||
- Dateien mit Secrets: Eigentümer root oder Dienstbenutzer, Modus `0600`.
|
||||
- Tokens werden pro Dienst getrennt und minimal berechtigt.
|
||||
- Ein Secret Broker oder Wrapper stellt Verbindungen her, ohne Tokens an das
|
||||
Modell zurückzugeben.
|
||||
|
||||
## Netzwerk
|
||||
|
||||
- Port 8080 nur localhost oder administratives VLAN.
|
||||
- Clients verwenden Port 8081.
|
||||
- Whisper, XTTS, TinySearch und SearXNG nur localhost.
|
||||
- Firewall erlaubt nur bekannte Quellnetze.
|
||||
- Externe Suche erhält nur die tatsächliche Suchanfrage, keine Chat-Historie.
|
||||
|
||||
## Router-Grenze
|
||||
|
||||
- Alle fachlichen Endpunkte verlangen einen mindestens 32 Zeichen langen,
|
||||
zufälligen Router-Key. Der Dienst startet ohne gültigen Key nicht.
|
||||
- `/health` und `/ready` sind die einzigen anonymen Endpunkte und geben nur
|
||||
groben Betriebszustand aus.
|
||||
- Authentifizierungsheader werden niemals an llama.cpp weitergereicht.
|
||||
- Remote-Bild-URLs sind standardmäßig gesperrt. Data-URLs werden auf MIME-Typ,
|
||||
Base64-Gültigkeit und 20 MiB Maximalgröße geprüft.
|
||||
- Die Zahl gleichzeitiger Requests ist begrenzt; große Uploads sind global
|
||||
begrenzt und generierte Bilder werden nach Alter, Anzahl und Größe bereinigt.
|
||||
- Crash-Recovery beendet keine PID nur aufgrund einer Zahl, sondern verlangt
|
||||
zusätzlich einen erwarteten Prozessmarker in `/proc/<pid>/cmdline`.
|
||||
Allgemeine Shell, beliebiges SSH/SCP, freies `curl`, Docker-Administration und
|
||||
Dateisystemsuche gehören nicht ins Standardprofil.
|
||||
|
||||
## Schreibaktionen
|
||||
|
||||
Jede destruktive oder persistente Aktion verwendet:
|
||||
Persistente oder destruktive Änderungen folgen immer: Bestandsaufnahme,
|
||||
exakte Vorschau, an die Vorschau gebundene Freigabe, unveränderte Ausführung,
|
||||
anschließende Verifikation.
|
||||
|
||||
1. read-only Bestandsaufnahme,
|
||||
2. exakte Vorschau,
|
||||
3. an diese Vorschau gebundenes Approval Ticket,
|
||||
4. unveränderte Ausführung,
|
||||
5. anschließende Verifikation.
|
||||
## Vor jedem Push
|
||||
|
||||
## Repository-Prüfung vor jedem Push
|
||||
|
||||
- Suche nach Token-, Passwort- und Private-Key-Mustern.
|
||||
- Keine `.env`, Zertifikate, Logs, Bilder, Audio oder Modellartefakte.
|
||||
- Keine echten internen API-Schlüssel in Beispielen.
|
||||
- Private-Key-, Token-, Passwort- und API-Key-Muster suchen.
|
||||
- Keine `.env`, Zertifikate, Logs, Bilder, Audio oder Modelle einchecken.
|
||||
- Beispiele enthalten nur Platzhalter; interne Hostnamen nur wenn bewusst.
|
||||
- Änderungen am Controller und Netzwerkguard mit Tests und Review versehen.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# WireGuard-Heimseite
|
||||
|
||||
Der Installer kann nur den KI-Host konfigurieren. Einmalig muss der vorhandene
|
||||
WireGuard-Router im Heimnetz den neuen Peer kennen. Ohne diesen externen Schritt
|
||||
kann kein automatisches Skript auf dem Uni-Host den Tunnel fertigstellen.
|
||||
|
||||
## Peer ergänzen
|
||||
|
||||
Beispiel mit KI-WireGuard-Adresse `10.77.0.2/32`:
|
||||
|
||||
```ini
|
||||
[Peer]
|
||||
PublicKey = <PUBLIC-KEY-DES-KI-HOSTS>
|
||||
AllowedIPs = 10.77.0.2/32
|
||||
```
|
||||
|
||||
Das Heimgerät muss das LAN `192.168.1.0/24` zum Tunnel routen können. Geräte im
|
||||
Heimnetz benötigen entweder eine Route für `10.77.0.2/32` über den
|
||||
WireGuard-Router oder der Router maskiert den VPN-Verkehr passend.
|
||||
|
||||
## KI-Internetzugang über zuhause
|
||||
|
||||
Wenn `WG_ROUTE_AI_INTERNET=true` gesetzt ist, muss der Heim-Peer IPv4-Forwarding
|
||||
und NAT ins WAN erlauben. Das wird auf dem Heimrouter eingerichtet, nicht auf
|
||||
dem Universitätsnetz. Beispielprinzip für nftables:
|
||||
|
||||
```nft
|
||||
table inet mike_ai {
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy accept;
|
||||
iifname "wg0" ip saddr 10.77.0.2 accept
|
||||
oifname "wg0" ip daddr 10.77.0.2 ct state established,related accept
|
||||
}
|
||||
}
|
||||
|
||||
table ip mike_ai_nat {
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100; policy accept;
|
||||
ip saddr 10.77.0.2 oifname "<HEIM-WAN-INTERFACE>" masquerade
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Die tatsächlichen Interface-Namen und die bestehende Firewall des Heimrouters
|
||||
gehen vor. Regeln nicht blind neben eine bereits verwaltete Firewall kopieren.
|
||||
|
||||
## Sicherheitsprüfung
|
||||
|
||||
1. Vom Heimnetz `10.77.0.2` erreichen.
|
||||
2. Open WebUI auf `10.77.0.2:8080` erreichen.
|
||||
3. Aus dem Universitäts-LAN Port 8080/8081 nicht erreichen.
|
||||
4. `wg0` am KI-Host stoppen: KI-Container dürfen nun weder Heimnetz noch
|
||||
Internet erreichen.
|
||||
5. Der Debian-Host selbst darf weiterhin nur die ausdrücklich gewünschte
|
||||
Administration über das Uni-LAN anbieten.
|
||||
Reference in New Issue
Block a user