feat(vpn): expose Athena services directly over WireGuard
This commit is contained in:
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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-
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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}')
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user