feat(vpn): expose Athena services directly over WireGuard

This commit is contained in:
Mikei386
2026-08-24 07:33:16 +02:00
parent b997fcb9f7
commit c402ea79f7
13 changed files with 130 additions and 56 deletions
+7 -6
View File
@@ -55,17 +55,18 @@ Neustart an; danach wird derselbe Befehl erneut ausgeführt.
| llama.cpp | nur Docker-intern | Inferenz und integrierte Vision | | llama.cpp | nur Docker-intern | Inferenz und integrierte Vision |
| Profile Controller | nur Docker-intern | eng begrenzter Profil-/FLUX-Hot-Swap | | Profile Controller | nur Docker-intern | eng begrenzter Profil-/FLUX-Hot-Swap |
| FLUX Worker | nur Docker-intern, normalerweise gestoppt | Bildgenerierung auf RTX 5080 | | FLUX Worker | nur Docker-intern, normalerweise gestoppt | Bildgenerierung auf RTX 5080 |
| XTTS-v2 | nur Docker-intern, RTX 3060 | primäre mehrsprachige Sprachausgabe | | XTTS-v2 | `<WG-IP>:8092`, RTX 3060 | primäre mehrsprachige Sprachausgabe |
| TTS Gateway | nur Docker-intern | Annmarie Nele, Queue und Piper-Fallback | | TTS Gateway | `<WG-IP>:8085` | Annmarie Nele, Queue und Piper-Fallback |
| Piper | nur Docker-intern, CPU | ausfallsichere deutsche Ersatzstimme | | Piper | `<WG-IP>:8091`, CPU | ausfallsichere deutsche Ersatzstimme |
| MCP-Tool-Stack | nur Docker-intern | Athena-Kontext, Athena Operator, Web, GitHub, Home Assistant, ARR, Unraid und Navidrome | | MCP-Tool-Stack | `<WG-IP>:8201-8208` | Athena-Kontext, Athena Operator, Web, GitHub, Home Assistant, ARR, Unraid und Navidrome |
XTTS-v2, TTS-Gateway, Piper-Fallback und der FLUX.2-Klein-Hot-Swap sind XTTS-v2, TTS-Gateway, Piper-Fallback und der FLUX.2-Klein-Hot-Swap sind
reproduzierbare Kerndienste; STT reproduzierbare Kerndienste; STT
bleibt optional. Web-, Home-Assistant-, bleibt optional. Web-, Home-Assistant-,
GitHub-, ARR-, Unraid- und Navidrome-Werkzeuge besitzen dagegen bereits getrennte Container unter GitHub-, ARR-, Unraid- und Navidrome-Werkzeuge besitzen dagegen bereits getrennte Container unter
`platform/mcp/`. Open WebUI erreicht sie ausschließlich über das interne `platform/mcp/`. Open WebUI erreicht sie über das interne `mike-ai-tools`-Netz;
`mike-ai-tools`-Netz; llama.cpp erhält keine MCP-Konfiguration und keine Pi, Hermes und andere Clients verwenden die direkten WireGuard-Ports aus
`docs/VPN_SERVICE_PORTS.md`. llama.cpp erhält keine MCP-Konfiguration und keine
Infrastruktur-Secrets. Die Bildanalyse ist Bestandteil des multimodalen Infrastruktur-Secrets. Die Bildanalyse ist Bestandteil des multimodalen
Qwen-Modells. Qwen-Modells.
+2
View File
@@ -48,6 +48,8 @@ services:
networks: networks:
frontend: frontend:
ipv4_address: 172.30.10.254 ipv4_address: 172.30.10.254
tools:
ipv4_address: 172.30.40.254
tools-egress: tools-egress:
ipv4_address: 172.30.50.254 ipv4_address: 172.30.50.254
security_opt: ["no-new-privileges:true"] security_opt: ["no-new-privileges:true"]
+2
View File
@@ -33,6 +33,8 @@ SSH_KEY_ONLY=true
WIREGUARD_MODE=container WIREGUARD_MODE=container
WIREGUARD_CONFIG_FILE=/etc/mike-ai/wireguard/fritz-athena.conf WIREGUARD_CONFIG_FILE=/etc/mike-ai/wireguard/fritz-athena.conf
WIREGUARD_ENABLE=false WIREGUARD_ENABLE=false
# Stable Fritzbox/WireGuard address used by direct VPN clients such as Pi or Hermes.
VPN_SERVICE_IP=192.168.1.212
# The values below are only used by the legacy host-terminated mode. The # The values below are only used by the legacy host-terminated mode. The
# default container mode takes address, peer and routes from the Fritzbox file. # default container mode takes address, peer and routes from the Fritzbox file.
AI_BIND_ADDRESS=10.77.0.2 AI_BIND_ADDRESS=10.77.0.2
+10 -12
View File
@@ -15,6 +15,7 @@ Heimnetz / VPN-Clients
| |
<Fritz-VPN-IP>:8080 Open WebUI <Fritz-VPN-IP>:8080 Open WebUI
<Fritz-VPN-IP>:8081 Profile Router API <Fritz-VPN-IP>:8081 Profile Router API
<Fritz-VPN-IP>:8201-08 direkte MCP-Endpunkte
| |
Docker-intern Docker-intern
+-- Profile Controller -- Docker Socket (feste Allowlist) +-- Profile Controller -- Docker Socket (feste Allowlist)
@@ -39,7 +40,7 @@ Heimnetz / VPN-Clients
| Komponente | Außen erreichbar | Aufgabe | | Komponente | Außen erreichbar | Aufgabe |
|---|---|---| |---|---|---|
| WireGuard Gateway | VPN-Adresse, Port 8080/8081 | Tunnel und eng begrenzte TCP-Proxys | | WireGuard Gateway | VPN-Adresse, feste Portmatrix | Tunnel und direkte TCP-Proxys für UI, API und Werkzeuge |
| Open WebUI | nur Docker-intern | Chat-Oberfläche | | Open WebUI | nur Docker-intern | Chat-Oberfläche |
| Profile Router | nur Docker-intern | OpenAI-API und Profilwahl | | Profile Router | nur Docker-intern | OpenAI-API und Profilwahl |
| Profile Controller | nein | startet ausschließlich fest erlaubte Profile | | Profile Controller | nein | startet ausschließlich fest erlaubte Profile |
@@ -47,7 +48,7 @@ Heimnetz / VPN-Clients
| XTTS-v2 | nein | primäre deutsche/englische Text-to-Speech-Ausgabe auf RTX 3060 | | XTTS-v2 | nein | primäre deutsche/englische Text-to-Speech-Ausgabe auf RTX 3060 |
| TTS-Gateway | nein | serialisiert XTTS, segmentiert Sprachwechsel und fällt auf Piper zurück | | TTS-Gateway | nein | serialisiert XTTS, segmentiert Sprachwechsel und fällt auf Piper zurück |
| Piper | nein | CPU-basierte Text-to-Speech-Rückfallebene | | Piper | nein | CPU-basierte Text-to-Speech-Rückfallebene |
| MCP-Tool-Stack | nein | voneinander getrennte Werkzeugbereiche | | MCP-Tool-Stack | über feste VPN-Ports | voneinander getrennte Werkzeugbereiche für OpenWebUI, Pi und Hermes |
| SearXNG/TinySearch | nein | private Suche, Crawl4AI-Extraktion und lokales Reranking | | SearXNG/TinySearch | nein | private Suche, Crawl4AI-Extraktion und lokales Reranking |
Nur der Profile Controller erhält den Docker-Socket. Der Router erhält weder Nur der Profile Controller erhält den Docker-Socket. Der Router erhält weder
@@ -90,7 +91,7 @@ Ultra bleibt für maximalen Kontext bewusst text-only.
- Docker-Netze liegen ausschließlich unter `172.30.0.0/16`. - Docker-Netze liegen ausschließlich unter `172.30.0.0/16`.
- Open WebUI und Router besitzen keine Docker-Host-Portfreigabe. - Open WebUI und Router besitzen keine Docker-Host-Portfreigabe.
- Der Gateway lauscht in seinem eigenen Namespace auf der Fritz-VPN-IP und - Der Gateway lauscht in seinem eigenen Namespace auf der Fritz-VPN-IP und
leitet nur 8080/8081 zu den internen Diensten weiter. leitet die dokumentierte Portmatrix zu UI, API, TTS und MCPs weiter.
- Quellrouting schickt `172.30.10.0/24` und `172.30.50.0/24` zum Gateway; - Quellrouting schickt `172.30.10.0/24` und `172.30.50.0/24` zum Gateway;
Regeln für `172.30.0.0/16` bewahren rein internen Docker-Verkehr. Regeln für `172.30.0.0/16` bewahren rein internen Docker-Verkehr.
- Die verschlüsselten äußeren Gateway-Pakete sind eng von diesen Quellregeln - Die verschlüsselten äußeren Gateway-Pakete sind eng von diesen Quellregeln
@@ -132,12 +133,11 @@ werden eindeutig buchstabiert.
## Zentrale MCP-Werkzeugebene ## Zentrale MCP-Werkzeugebene
Werkzeuge werden nicht in llama.cpp eingebaut. Sie laufen als eigene, Werkzeuge werden nicht in llama.cpp eingebaut. Sie laufen als eigene, zentrale
zentrale MCP-Container. Open WebUI greift intern darauf zu. Für externe Clients MCP-Container. Open WebUI greift intern darauf zu; Pi, Hermes und andere
wie Hermes wird später ein authentifizierter MCP-Gateway über WireGuard Clients verwenden ihre festen Ports direkt auf Athenas WireGuard-Adresse. Ein
vorgeschaltet; die unauthentifizierten internen Ports werden niemals direkt zusätzliches MCP-Gateway ist nicht erforderlich. So können alle Oberflächen
veröffentlicht. So können alle Oberflächen dieselben geprüften Werkzeuge dieselben Werkzeuge verwenden, ohne Secrets zu duplizieren.
verwenden, ohne Secrets zu duplizieren.
Die Trenneinheit ist **ein Container pro Fachbereich und Vertrauensstufe** – Die Trenneinheit ist **ein Container pro Fachbereich und Vertrauensstufe** –
nicht ein Container pro einzelner Funktion und nicht ein gemeinsamer nicht ein Container pro einzelner Funktion und nicht ein gemeinsamer
@@ -153,7 +153,7 @@ Open WebUI ── internes Netz ───────────┬── web-m
└── unraid-mcp-read └── unraid-mcp-read
Hermes Agent ─ WireGuard ─┐ Hermes Agent ─ WireGuard ─┐
weitere MCP-Clients ──────┴── mcp-gateway (später) ── dasselbe interne Netz Pi / weitere MCP-Clients ─┴── feste VPN-Ports 8201-8208 ── MCP-Container
``` ```
| Container | Werkzeugbereich | Standardrecht | | Container | Werkzeugbereich | Standardrecht |
@@ -169,8 +169,6 @@ weitere MCP-Clients ──────┴── mcp-gateway (später) ── das
| `unraid-mcp-read` | System-, Container- und begrenzte Logdiagnose | nur lesen | | `unraid-mcp-read` | System-, Container- und begrenzte Logdiagnose | nur lesen |
| `unraid-mcp-admin` | eng definierte Verwaltungsaktionen | bewusst aktivieren | | `unraid-mcp-admin` | eng definierte Verwaltungsaktionen | bewusst aktivieren |
| `sandbox-mcp` | temporäre Code- und Dateiarbeit | isolierter Arbeitsraum | | `sandbox-mcp` | temporäre Code- und Dateiarbeit | isolierter Arbeitsraum |
| `mcp-gateway` | Auth, Routing, Limits und Werkzeugauswahl | keine Fach-Secrets |
Read- und Write-Instanzen dürfen dasselbe Image verwenden, laufen aber mit Read- und Write-Instanzen dürfen dasselbe Image verwenden, laufen aber mit
unterschiedlichen Tokens, Netzwerkzugriffen und Werkzeug-Allowlisten. Der unterschiedlichen Tokens, Netzwerkzugriffen und Werkzeug-Allowlisten. Der
Gateway besitzt keine HA-, ARR- oder Unraid-Secrets. Er authentifiziert Clients, Gateway besitzt keine HA-, ARR- oder Unraid-Secrets. Er authentifiziert Clients,
+4 -2
View File
@@ -116,8 +116,10 @@ laufen, sondern alle fachlichen Funktionen geprüft wurden.
## Phase F – Sicherheitsprüfung ## Phase F – Sicherheitsprüfung
- [ ] Port 8080/8081 an der physischen Hostadresse nicht erreichbar - [ ] alle Anwendungsports aus `VPN_SERVICE_PORTS.md` an der physischen
- [ ] beide Ports über die Fritz-VPN-Adresse erreichbar Hostadresse nicht erreichbar
- [ ] OpenWebUI, Router und alle gestarteten MCPs über die Fritz-VPN-Adresse
erreichbar
- [ ] gestopptes WireGuard-Gateway blockiert Container-Egress - [ ] gestopptes WireGuard-Gateway blockiert Container-Egress
- [ ] Hilfsports nur localhost - [ ] Hilfsports nur localhost
- [ ] Router nur aus erlaubtem Netz erreichbar - [ ] Router nur aus erlaubtem Netz erreichbar
+5 -3
View File
@@ -180,9 +180,11 @@ Auf einer frischen Open-WebUI-Datenbank werden die internen MCP-Adressen über
`TOOL_SERVER_CONNECTIONS` vorbelegt. Bei einer übernommenen Datenbank müssen `TOOL_SERVER_CONNECTIONS` vorbelegt. Bei einer übernommenen Datenbank müssen
die Einträge einmal unter **Admin-Einstellungen → Externe Werkzeuge** geprüft die Einträge einmal unter **Admin-Einstellungen → Externe Werkzeuge** geprüft
oder importiert werden. Die Endpunkte stehen in `platform/mcp/README.md`. oder importiert werden. Die Endpunkte stehen in `platform/mcp/README.md`.
Kein MCP-Port wird auf dem Host veröffentlicht. Externe Clients wie Hermes Kein MCP-Port wird auf der physischen Universitätsadresse veröffentlicht.
benötigen später den authentifizierten WireGuard-Gateway und dürfen nicht OpenWebUI nutzt intern weiterhin die Docker-Namen; Pi, Hermes und andere
direkt auf das interne Werkzeugnetz zugreifen. Clients greifen direkt über die festen WireGuard-Adressen aus
[VPN_SERVICE_PORTS.md](VPN_SERVICE_PORTS.md) zu. Ein zusätzliches MCP-Gateway
oder ein weiterer Auth-Layer innerhalb des Heim-VPNs ist nicht vorgesehen.
Die vollständige Wiederherstellung einschließlich OpenWebUI, MCP-Secrets und Die vollständige Wiederherstellung einschließlich OpenWebUI, MCP-Secrets und
Navidrome/Last.fm ist unter Navidrome/Last.fm ist unter
+5 -3
View File
@@ -129,7 +129,8 @@ Docker-Netze verwenden ausschließlich `172.30.0.0/16`. Wichtige Netze:
Open WebUI und Router haben keine normalen Host-Portfreigaben. Der Open WebUI und Router haben keine normalen Host-Portfreigaben. Der
WireGuard-Gateway-Container beendet den Fritzbox-Clienttunnel und veröffentlicht WireGuard-Gateway-Container beendet den Fritzbox-Clienttunnel und veröffentlicht
innerhalb des VPN nur Open WebUI auf Port 8080 und die Router-API auf Port 8081. innerhalb des VPN OpenWebUI, Router, TTS und die festen MCP-Ports aus
`VPN_SERVICE_PORTS.md`.
Die KI- und Werkzeugcontainer erreichen Heimnetz und Internet über diesen Die KI- und Werkzeugcontainer erreichen Heimnetz und Internet über diesen
Gateway. Quellrouting sorgt dafür, dass sie bei Tunnelausfall nicht über das Gateway. Quellrouting sorgt dafür, dass sie bei Tunnelausfall nicht über das
Universitätsgateway ausweichen. Das gewünschte Verhalten ist fail-closed. Universitätsgateway ausweichen. Das gewünschte Verhalten ist fail-closed.
@@ -227,8 +228,9 @@ Fallback, internem Endpunkt, reproduzierbarer Version und Hörtest aus.
## 9. MCP-Werkzeuge ## 9. MCP-Werkzeuge
MCP-Werkzeuge gehören nicht in llama.cpp-Startparameter. Jeder Fachbereich MCP-Werkzeuge gehören nicht in llama.cpp-Startparameter. Jeder Fachbereich
läuft in einem getrennten Container mit eigener Secret-Datei und minimalem läuft in einem getrennten Container mit eigener Secret-Datei. Auf der
Netzzugriff. Kein MCP-Port wird am Host veröffentlicht. Universitätsadresse wird kein MCP-Port veröffentlicht; über die
WireGuard-Adresse sind alle Fach-MCPs direkt erreichbar.
| Bereich | Aufgabe | Rechte | | Bereich | Aufgabe | Rechte |
|---|---|---| |---|---|---|
+8 -6
View File
@@ -3,8 +3,9 @@
## Netzgrenze ## Netzgrenze
- Open WebUI und Router veröffentlichen keinerlei Host-Ports. - Open WebUI und Router veröffentlichen keinerlei Host-Ports.
- Ein dedizierter WireGuard-Container stellt auf seiner VPN-Adresse nur 8080 - Ein dedizierter WireGuard-Container stellt OpenWebUI, Router und die
und 8081 bereit. Werkzeugdienste direkt auf seiner VPN-Adresse bereit. Die verbindliche
Portmatrix steht in [VPN_SERVICE_PORTS.md](VPN_SERVICE_PORTS.md).
- Die egressfähigen Docker-Netze verwenden eigene Routingtabellen. - Die egressfähigen Docker-Netze verwenden eigene Routingtabellen.
- Heimnetz- und optionaler Internetverkehr laufen über WireGuard. - Heimnetz- und optionaler Internetverkehr laufen über WireGuard.
- Die Tabellen zeigen ausschließlich zum Gateway-Container und besitzen keine - Die Tabellen zeigen ausschließlich zum Gateway-Container und besitzen keine
@@ -22,13 +23,14 @@ physischen Schnittstelle erreichbar.
- Profile Controller: einzige Socket-Ausnahme; feste Profile und nur - Profile Controller: einzige Socket-Ausnahme; feste Profile und nur
List/Start/Stop, keine frei wählbaren Images, Befehle oder Mounts. List/Start/Stop, keine frei wählbaren Images, Befehle oder Mounts.
- Open WebUI: einziges persistentes Chat-Volume. - Open WebUI: einziges persistentes Chat-Volume.
- MCP-Fachcontainer: intern, getrennte Secrets und keine Host-Ports. - MCP-Fachcontainer: intern verbunden und über feste WireGuard-Ports direkt
für OpenWebUI, Pi, Hermes und andere Heim-VPN-Clients erreichbar.
- TinySearch/SearXNG: intern, Suchanfragen ohne Chatverlauf. - TinySearch/SearXNG: intern, Suchanfragen ohne Chatverlauf.
llama.cpp bekommt weder MCP-Konfiguration noch HA-, ARR- oder Unraid-Secrets. llama.cpp bekommt weder MCP-Konfiguration noch HA-, ARR- oder Unraid-Secrets.
Open WebUI kennt nur interne MCP-URLs; Authentisierung zu den Zielsystemen Open WebUI kann weiterhin die internen MCP-Namen verwenden. Andere Clients
findet im jeweiligen Fachcontainer statt. Externe MCP-Clients werden erst über nutzen ohne zusätzliches Gateway die festen MCP-Ports der WireGuard-Adresse.
einen authentifizierten WireGuard-Gateway zugelassen. Authentisierung zu den Zielsystemen findet im jeweiligen Fachcontainer statt.
Ein Docker-Socket bleibt grundsätzlich privilegiert. Der Controller reduziert Ein Docker-Socket bleibt grundsätzlich privilegiert. Der Controller reduziert
die erreichbare Funktion stark, ersetzt aber keine zusätzliche Socket-Proxy- die erreichbare Funktion stark, ersetzt aber keine zusätzliche Socket-Proxy-
+37
View File
@@ -0,0 +1,37 @@
# Dienste direkt über das Heim-VPN
Athena behandelt die von der Fritzbox zugewiesene WireGuard-Adresse als ihr
normales Anwendungsnetz. OpenWebUI, die Router-API und die nützlichen
Werkzeugdienste sind dort direkt erreichbar. Auf der physischen
Universitätsadresse werden diese Ports nicht veröffentlicht.
Aktuelle VPN-Adresse: `192.168.1.212`
| Port | Dienst | Adresse |
|---:|---|---|
| 22 | SSH zum Athena-Host | `ssh root@192.168.1.212` |
| 8080 | OpenWebUI | `http://192.168.1.212:8080` |
| 8081 | OpenAI-kompatible Router-API | `http://192.168.1.212:8081/v1` |
| 8085 | TTS-Gateway | `http://192.168.1.212:8085` |
| 8091 | Piper direkt | `http://192.168.1.212:8091` |
| 8092 | XTTS direkt | `http://192.168.1.212:8092` |
| 8201 | Athena Platform Context MCP | `http://192.168.1.212:8201/mcp` |
| 8202 | Athena Operator MCP | `http://192.168.1.212:8202/mcp` |
| 8203 | Web-MCP | `http://192.168.1.212:8203/mcp` |
| 8204 | GitHub-MCP | `http://192.168.1.212:8204/mcp` |
| 8205 | Home-Assistant-MCP | `http://192.168.1.212:8205/mcp` |
| 8206 | ARR-MCP | `http://192.168.1.212:8206/mcp` |
| 8207 | Navidrome-MCP | `http://192.168.1.212:8207/mcp` |
| 8208 | Unraid-SSH-MCP, falls aktiviert | `http://192.168.1.212:8208/mcp` |
| 8210 | SearXNG-Diagnoseoberfläche | `http://192.168.1.212:8210` |
| 8211 | TinySearch-MCP direkt | `http://192.168.1.212:8211/mcp` |
Pi, Hermes und andere MCP-Clients tragen diese URLs direkt ein. Ein
zusätzliches MCP-Gateway ist nicht erforderlich. Nicht gestartete optionale
Container führen am jeweiligen Port lediglich zu einer nicht erreichbaren
Verbindung; nach ihrem Start funktioniert derselbe Port automatisch.
Die Portweiterleitungen laufen ausschließlich im Netzwerk-Namespace des
WireGuard-Containers und binden explizit an dessen VPN-Adresse. Deshalb sind
sie nicht über `172.21.117.202` erreichbar. SSH bleibt davon unabhängig auch
auf der Universitätsadresse zulässig.
+7 -5
View File
@@ -14,8 +14,10 @@ Verschlüsselung. Eine LAN-zu-LAN-Konfiguration ist für diesen Host nicht nöti
Der Tunnel endet im Container `mike-ai-wireguard-gateway`. Nur dieser Container Der Tunnel endet im Container `mike-ai-wireguard-gateway`. Nur dieser Container
erhält `NET_ADMIN` und `/dev/net/tun`. Open WebUI und Router veröffentlichen erhält `NET_ADMIN` und `/dev/net/tun`. Open WebUI und Router veröffentlichen
keine Host-Ports; der Gateway stellt ausschließlich Port 8080 und 8081 auf der keine Ports auf der physischen Hostadresse. Der Gateway stellt OpenWebUI,
von der Fritzbox zugeteilten VPN-Adresse bereit. Router und die Werkzeugdienste auf der von der Fritzbox zugeteilten
VPN-Adresse bereit. Die vollständige Liste steht in
[VPN_SERVICE_PORTS.md](VPN_SERVICE_PORTS.md).
## Split der Verantwortlichkeiten ## Split der Verantwortlichkeiten
@@ -38,13 +40,13 @@ systemctl status mike-ai-container-vpn-guard
Der Healthcheck verlangt einen Handshake, der jünger als drei Minuten ist. Der Healthcheck verlangt einen Handshake, der jünger als drei Minuten ist.
Open WebUI liegt unter `http://<VPN-IP>:8080`, der Router unter Open WebUI liegt unter `http://<VPN-IP>:8080`, der Router unter
`http://<VPN-IP>:8081`. An der physischen Standortadresse dürfen beide Ports `http://<VPN-IP>:8081/v1`; die MCPs liegen auf 8201 bis 8208. An der
nicht antworten. physischen Standortadresse dürfen diese Anwendungsports nicht antworten.
## Getestetes Verhalten am 22. August 2026 ## Getestetes Verhalten am 22. August 2026
- Fritzbox-Handshake und Datenverkehr in beide Richtungen: erfolgreich - Fritzbox-Handshake und Datenverkehr in beide Richtungen: erfolgreich
- Open WebUI und Router über die VPN-Adresse: HTTP 200 - Open WebUI, Router und direkte MCP-Endpunkte über die VPN-Adresse: erreichbar
- dieselben Ports über die physische Hostadresse: geschlossen - dieselben Ports über die physische Hostadresse: geschlossen
- VPN-Gateway gestoppt: ausgehender Open-WebUI-Test blockiert (fail-closed) - VPN-Gateway gestoppt: ausgehender Open-WebUI-Test blockiert (fail-closed)
- Gateway erneut gestartet: automatischer aktueller Handshake - Gateway erneut gestartet: automatischer aktueller Handshake
+37 -15
View File
@@ -46,7 +46,7 @@ ip -4 route replace default dev wg0
ip -6 route replace default dev wg0 2>/dev/null || true ip -6 route replace default dev wg0 2>/dev/null || true
cleanup() { cleanup() {
kill "${proxy_ui_pid:-}" "${proxy_router_pid:-}" "${proxy_ssh_pid:-}" 2>/dev/null || true [ -z "${proxy_pids:-}" ] || kill $proxy_pids 2>/dev/null || true
wg-quick down "$RUNTIME" 2>/dev/null || true wg-quick down "$RUNTIME" 2>/dev/null || true
} }
trap cleanup EXIT INT TERM trap cleanup EXIT INT TERM
@@ -58,20 +58,42 @@ iptables -A FORWARD -o wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
# Nothing is published on the physical host. These listeners exist only in
# the WireGuard container namespace and forward VPN clients to internal names.
socat TCP-LISTEN:8080,bind=0.0.0.0,reuseaddr,fork TCP:open-webui:8080 &
proxy_ui_pid=$!
socat TCP-LISTEN:8081,bind=0.0.0.0,reuseaddr,fork TCP:router:8081 &
proxy_router_pid=$!
# Emergency SSH path for unattended operation. Bind explicitly to WireGuard's
# IPv4 address, never to a Docker-facing interface or the physical host. The
# target is the host-side gateway of the fixed frontend bridge. Host sshd still
# enforces its normal key-only authentication policy.
wg_ipv4=$(ip -4 -o address show dev wg0 | awk 'NR == 1 { split($4, address, "/"); print address[1] }') wg_ipv4=$(ip -4 -o address show dev wg0 | awk 'NR == 1 { split($4, address, "/"); print address[1] }')
[ -n "$wg_ipv4" ] || { echo "WireGuard IPv4 address is missing" >&2; exit 1; } [ -n "$wg_ipv4" ] || { echo "WireGuard IPv4 address is missing" >&2; exit 1; }
socat TCP-LISTEN:22,bind="$wg_ipv4",reuseaddr,fork TCP:172.30.10.1:22 &
proxy_ssh_pid=$!
wait "$proxy_ui_pid" # The VPN is Athena's normal application network. Nothing below is published
# on the physical university interface: every listener is bound inside this
# namespace to the Fritzbox-assigned WireGuard address. Clients on the home
# VPN may use OpenWebUI, the router and every useful MCP directly.
proxy_pids=""
start_proxy() {
listen_port=$1
target=$2
socat "TCP-LISTEN:${listen_port},bind=${wg_ipv4},reuseaddr,fork" "TCP:${target}" &
proxy_pids="$proxy_pids $!"
}
start_proxy 22 172.30.10.1:22
start_proxy 8080 open-webui:8080
start_proxy 8081 router:8081
start_proxy 8085 tts-gateway:8085
start_proxy 8091 piper:8085
start_proxy 8092 xtts:80
# MCP endpoints. Optional services keep their listener even while stopped and
# begin working automatically as soon as their container is started.
start_proxy 8201 mcp-platform-context:8000
start_proxy 8202 mcp-athena-operator:8000
start_proxy 8203 mcp-web:8000
start_proxy 8204 mcp-github:8000
start_proxy 8205 mcp-homeassistant:8000
start_proxy 8206 mcp-arr:8000
start_proxy 8207 mcp-navidrome:3000
start_proxy 8208 mcp-unraid-ssh:8000
# Search backends are also directly available for diagnostics and alternative
# clients. Normal chat clients should prefer the MCP endpoint on 8203.
start_proxy 8210 searxng:8080
start_proxy 8211 tinysearch:8000
wait $(printf '%s\n' "$proxy_pids" | awk '{print $2}')
+3 -1
View File
@@ -104,7 +104,9 @@ oder ein anderes Werkzeug benötigt wird.
## Sicherheitsmodell ## Sicherheitsmodell
- Kein MCP-Port wird auf eine Host-Adresse veröffentlicht. - Kein MCP-Port wird auf der physischen Universitätsadresse veröffentlicht.
Über Athenas WireGuard-Adresse sind die Fach-MCPs direkt auf den in
`docs/VPN_SERVICE_PORTS.md` dokumentierten Ports erreichbar.
- Nur Clients im privaten Docker-Netz `mike-ai-tools` erreichen die Endpunkte. - Nur Clients im privaten Docker-Netz `mike-ai-tools` erreichen die Endpunkte.
- Secrets bleiben in Dateien unter `/etc/mike-ai` und werden read-only - Secrets bleiben in Dateien unter `/etc/mike-ai` und werden read-only
eingehängt. Sie gehören weder in Git noch in OpenWebUI-Tooldefinitionen. eingehängt. Sie gehören weder in Git noch in OpenWebUI-Tooldefinitionen.
+3 -3
View File
@@ -141,9 +141,9 @@ services:
MCP_TRANSPORT: http MCP_TRANSPORT: http
MCP_HTTP_EXPOSE: "true" MCP_HTTP_EXPOSE: "true"
MCP_HTTP_PORT: "3000" MCP_HTTP_PORT: "3000"
# The endpoint is not published on the host. Host filtering still makes # OpenWebUI uses the Docker name; Pi/Hermes may reach the same endpoint
# accidental access from any other Docker name fail closed. # directly through Athena's WireGuard address and VPN port 8207.
MCP_HTTP_ALLOWED_HOSTS: "mike-ai-mcp-navidrome:3000,mike-ai-mcp-navidrome" MCP_HTTP_ALLOWED_HOSTS: "mike-ai-mcp-navidrome:3000,mike-ai-mcp-navidrome,${VPN_SERVICE_IP:-192.168.1.212}:8207,${VPN_SERVICE_IP:-192.168.1.212}"
WEBUI_ENABLED: "false" WEBUI_ENABLED: "false"
tmpfs: tmpfs:
- /tmp:rw,noexec,nosuid,nodev,size=64m - /tmp:rw,noexec,nosuid,nodev,size=64m