From 16a6288a4d2419d1cf96d2208e49c72b1adb35aa Mon Sep 17 00:00:00 2001 From: Mikei386 <44135113+Mikei386@users.noreply.github.com> Date: Sun, 23 Aug 2026 08:55:06 +0200 Subject: [PATCH] Add WireGuard-only SSH recovery path --- docs/INSTALLATION.md | 9 +++++++++ docs/REMOTE_SITE_CHECKLIST.md | 4 ++++ platform/docker/wireguard-gateway/entrypoint.sh | 11 ++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 29753fe..b5b57a8 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -63,6 +63,7 @@ werden nicht ausgegeben. Sie liegen root-only unter `/etc/mike-ai`. - Open WebUI: `http://:8080` - Router: `http://:8081` +- SSH fallback: `ssh root@` (key-only, forwarded to host sshd) - llama.cpp-WebUI: absichtlich deaktiviert und nicht veröffentlicht ```bash @@ -71,8 +72,16 @@ sudo docker inspect -f '{{.State.Health.Status}}' mike-ai-wireguard-gateway sudo docker compose --env-file /etc/mike-ai/stack.env \ -f /opt/mike-ai/stack/compose.yaml ps curl http://:8081/health +ssh -o BatchMode=yes root@ true ``` +Der SSH-Fallback lauscht ausschließlich auf der IPv4-Adresse von `wg0` im +WireGuard-Gateway-Container. Er wird nicht als Docker-Port auf dem +Standort-Interface veröffentlicht. Das Gateway leitet die Verbindung an den +hostseitigen Gateway-Endpunkt des festen `frontend`-Netzes weiter; Anmeldung, +Schlüsselprüfung und Protokollierung erfolgen weiterhin durch den normalen +OpenSSH-Dienst des Hosts. + Die TTS-Verbindung wird für eine frische Open-WebUI-Datenbank automatisch als OpenAI-kompatibler Audio-Endpunkt des Routers vorbelegt. Der Router reicht sie intern an Piper weiter; Port 8085 wird nicht am Host veröffentlicht. Ein diff --git a/docs/REMOTE_SITE_CHECKLIST.md b/docs/REMOTE_SITE_CHECKLIST.md index a952847..4794c66 100644 --- a/docs/REMOTE_SITE_CHECKLIST.md +++ b/docs/REMOTE_SITE_CHECKLIST.md @@ -55,6 +55,9 @@ Minute sowie ein aktueller WireGuard-Handshake. - SSH bleibt auf der Standort-Schnittstelle erreichbar, akzeptiert aber nur Public-Key-Anmeldungen. Vor dem Transport muss der Schlüsselzugriff getestet werden. +- Zusätzlich stellt das WireGuard-Gateway unter seiner VPN-Adresse Port 22 als + key-only SSH-Notweg zum Host bereit. Der Listener ist explizit an `wg0` + gebunden und wird nicht auf dem Standort-Interface veröffentlicht. - Der WireGuard-Tunnel muss **vor dem Transport** erfolgreich aufgebaut und von zuhause erreichbar getestet sein. - Für WireGuard braucht Athena keine eingehende Portfreigabe am Standort: Der @@ -74,6 +77,7 @@ Minute sowie ein aktueller WireGuard-Handshake. 4. `mike-ai-wireguard-gateway` stoppen: Container-Egress muss scheitern; Gateway wieder starten und aktuellen Handshake prüfen. 5. Von zuhause aus ausschließlich über die spätere VPN-Adresse zugreifen. + Dabei sowohl Open WebUI als auch `ssh root@` prüfen. Ohne erfolgreich getesteten WireGuard-Tunnel und die UEFI-Stromoptionen gilt der Host nicht als bereit für einen unbeaufsichtigten Standort. diff --git a/platform/docker/wireguard-gateway/entrypoint.sh b/platform/docker/wireguard-gateway/entrypoint.sh index 143f6d8..e619d0c 100644 --- a/platform/docker/wireguard-gateway/entrypoint.sh +++ b/platform/docker/wireguard-gateway/entrypoint.sh @@ -46,7 +46,7 @@ ip -4 route replace default dev wg0 ip -6 route replace default dev wg0 2>/dev/null || true cleanup() { - kill "${proxy_ui_pid:-}" "${proxy_router_pid:-}" 2>/dev/null || true + kill "${proxy_ui_pid:-}" "${proxy_router_pid:-}" "${proxy_ssh_pid:-}" 2>/dev/null || true wg-quick down "$RUNTIME" 2>/dev/null || true } trap cleanup EXIT INT TERM @@ -65,4 +65,13 @@ 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] }') +[ -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"