Ersten Home-Gateway einrichten
Du hast eine NAS, einen Mini-PC oder einen Raspberry Pi im Heimnetz und willst Dienste daraus (Router-Admin, NAS-WebUI, Home Assistant, …) über deine GateControl-Instanz erreichbar machen. Ohne Port-Forwarding im Router, ohne Umwege.
Die Lösung ist der Home-Gateway-Container (ghcr.io/callmetechie/gatecontrol-gateway):
ein schlanker Companion, der den WireGuard-Tunnel ausgehend zum Server
aufbaut und im LAN als Weiterleiter dient. Der Server-Proxy kann dann
jedes LAN-Ziel per target_kind=gateway ansprechen, und der Gateway
macht den letzten Hop.
Diese Anleitung führt dich einmal durch: Peer anlegen → gateway.env
ziehen → docker-compose auf der NAS → erster Heartbeat prüfen.
Dauer: ~10 Minuten.
Was du vorher brauchst
- Eine laufende GateControl-Instanz mit Pro-Lizenz (Home-Gateway ist Pro-Feature).
- Admin-Zugang zur GateControl-Web-UI.
- Einen Hostrechner im Heimnetz, auf dem Docker läuft. Typische Kandidaten:
- Synology DSM 7.2+ mit Container-Manager
- Raspberry Pi 4/5 mit Raspberry Pi OS
- Ubuntu-/Debian-Box
- Proxmox-LXC mit Nesting + Keyctl
/dev/net/tunmuss am Host verfügbar sein (die Compose-Vorlage unten reicht es explizit durch). Bei Synology und manchen LXC-Varianten muss dafür einmaligmodprobe tunlaufen.- Eine freie LAN-IP auf dem Gateway-Host und Zugriff auf das LAN-Segment der Ziel-Geräte. Wichtig: Der Gateway-Host muss physisch im selben Layer-2-Netz liegen wie die Geräte, die du ansprechen willst — sonst funktioniert Wake-on-LAN nicht.
Kein Port-Forward im Router, keine Firewall-Öffnung, keine Public-IP nötig. Der Tunnel geht vom Gateway zum Server auf UDP 51820.
1. Gateway-Peer im Admin-UI anlegen
- Öffne die Admin-UI und gehe auf Peers & Clients.
- Klick auf + Hinzufügen (oben rechts).
- Im Modal:
- Peer Name: z.B.
homeserver-nucodernas-syno— das ist der Anzeigename im Admin-UI. - Beschreibung (optional):
Intel NUC · Debian 12 · Wohnzimmer. - Haken bei Home Gateway setzen. Das Feld Gateway API Port
erscheint und steht auf
9876. Standard lassen, sofern der Port auf dem Host nicht schon belegt ist.
- Peer Name: z.B.
- Speichern klicken.
Nach dem Speichern zeigt die UI einmalig einen Dialog mit den
Pairing-Tokens (api_token und push_token). Die Tokens werden im
Klartext nur dieses eine Mal angezeigt — Server speichert nur Hashes.
Lass das Modal offen bis Schritt 2.
2. gateway.env herunterladen
Im gleichen Dialog gibt es den Button Gateway-Config herunterladen.
Die Datei heißt gateway.env und enthält alles, was der Gateway-Container
braucht:
GC_SERVER_URL=https://gate.example.com
GC_API_TOKEN=...
GC_GATEWAY_TOKEN=...
GC_TUNNEL_IP=10.8.0.42
GC_API_PORT=9876
GC_HEARTBEAT_INTERVAL_S=30
WG_PRIVATE_KEY=...
WG_PRESHARED_KEY=...
WG_ENDPOINT=gate.example.com:51820
WG_SERVER_PUBLIC_KEY=...
WG_ADDRESS=10.8.0.42/32
WG_ALLOWED_IPS=10.8.0.1/32
WG_DNS=10.8.0.1
Wichtig:
- Speichere die Datei sofort in einem Passwort-Manager oder direkt auf dem Gateway-Host.
- Falls du die
.envverlierst: Peer-Edit öffnen → ENV herunterladen erneut klicken. Dabei werden beide Tokens rotiert — der alte Gateway verliert die Verbindung und muss neu deployed werden. - Die
WG_ADDRESS=10.8.0.42/32ist bewusst ein /32 (nicht /24). Das verhindert Routing-Konflikte, falls auf derselben Maschine parallel ein normaler GateControl-Client läuft.
3. docker-compose auf dem Gateway-Host
Leg auf der NAS/PI/NUC einen Ordner an, z.B. /opt/gatecontrol-gateway/.
Darin docker-compose.yml:
services:
gateway:
image: ghcr.io/callmetechie/gatecontrol-gateway:latest
container_name: gatecontrol-gateway
restart: unless-stopped
network_mode: host
cap_drop:
- ALL
cap_add:
- NET_ADMIN # wg-quick, iptables, Routing
- NET_BIND_SERVICE # L4-Ports <1024 (SSH, DNS, HTTP)
read_only: true
user: "0:0"
devices:
- /dev/net/tun:/dev/net/tun
tmpfs:
- /tmp
- /run
- /etc/wireguard
volumes:
- ./config:/config:ro
environment:
- LOG_LEVEL=info
- GATEWAY_ENV_PATH=/config/gateway.env
- WG_QUICK_USERSPACE_IMPLEMENTATION=wireguard-go
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Erklärungen zu den wichtigsten Punkten:
network_mode: hostist Pflicht. Der Gateway bindet L4-Routen dynamisch auf wechselnden Ports — das ginge mit Docker-NAT nicht ohne Neustart.cap_drop: ALL+ zwei explizite Caps ist die Security-Baseline.NET_ADMINbraucht wg-quick,NET_BIND_SERVICEnur wenn du L4-Routen auf Ports < 1024 laufen lässt.read_only: truemit tmpfs für/tmp,/run,/etc/wireguard— wg-quick schreibt Config zur Laufzeit nach/etc/wireguard.user: "0:0"ist bewusst root: wg-quick ist ein Shell-Script (Zeile 85) das bei UID != 0 ins Leere läuft. Die Security-Grenze sind die Caps, nicht die UID.WG_QUICK_USERSPACE_IMPLEMENTATION=wireguard-goerzwingt die Userspace-WireGuard-Implementation. Auf Synology DSM und in LXC-Containern ohne WG-Kernelmodul ist das der einzige Weg.
Leg dann die gateway.env aus Schritt 2 nach ./config/gateway.env
(also neben das Compose-File, in einen config/-Unterordner).
mkdir -p config
mv ~/Downloads/gateway.env config/gateway.env
chmod 600 config/gateway.env
4. Container starten
docker compose up -d
docker compose logs -f gateway
In den ersten Sekunden siehst du:
- WG-Setup (
[#] ip link add wg0 type wireguard…) - Heartbeat-Meldung:
POST /api/v1/gateway/heartbeat → 200 config sync: version N applied
Gib dem Prozess ~30 Sekunden bis zum ersten Heartbeat.
5. Im Admin-UI prüfen
Zurück in die Admin-UI, auf Peers & Clients. Im Abschnitt Home Gateways sollte deine Gateway-Card jetzt mit grünem Status-Dot als Online stehen.
Klick auf die Card — im Detail-Panel siehst du:
- Zuletzt gesehen (sollte Sekunden her sein)
- WG-Handshake (Uhrzeit, frisch)
- Laufzeit + Container-Version (aus
gateway_info.section_version) - Geroutete Ziele (noch leer — Routen legst du im nächsten Schritt an)
6. Erste Gateway-Route anlegen
Sobald der Gateway online ist, kannst du LAN-Hosts als Route anlegen. Das
ist der Standardfall: HTTP-Route auf z.B. dsm.example.com → target_kind
gateway → Gateway-Peer auswählen → LAN-Host 192.168.1.10:5001 → fertig.
Detaillierter Walk-Through mit allen Feldern und DNS/TLS-Feinheiten: siehe adding-a-route.md.
Für Remote-Desktop-Zugriff auf Windows-Rechner im selben LAN: siehe configuring-rdp.md.
Troubleshooting
Gateway bleibt offline
-
Container-Logs anschauen:
docker compose logs --tail 200 gatewayTypische Meldungen:
GC_SERVER_URL unreachable→ DNS/Netz vom Gateway zum Server kaputt.401 unauthorized→ Token ingateway.envstimmen nicht mit DB überein. Tokens rotiert oder falsche.envreingelegt?TLS alert 80→ Server hat SSL-Problem; siehe certificates.md.
-
Heartbeat per curl vom Gateway-Host simulieren:
curl -i -X POST https://gate.example.com/api/v1/gateway/heartbeat \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(grep ^GC_GATEWAY_TOKEN config/gateway.env | cut -d= -f2)" \ -d '{"peer_id":42,"status":"ok"}'200 OK → Netz ist gut, Problem liegt im Container-Code. Connection refused / Timeout → Firewall/DNS.
-
.envauf Korruption prüfen (z.B. Windows-Line-Endings nach Copy-Paste über Windows-Tools):file config/gateway.env # sollte "ASCII text" sagen, nicht "CRLF"
WG-Tunnel baut sich nicht auf
Symptom: Logs zeigen wg-quick: not a valid key oder Handshake did not complete after 5 seconds.
Prüfschritte:
- Server-Endpoint erreichbar? Vom Gateway-Host:
nc -u -v gate.example.com 51820(muss UDP können —ncohne-uist TCP und sagt "open" obwohl UDP zu ist). - GC_BASE_URL im Server korrekt gesetzt? Wenn die
gateway.envmit Platzhalter-Domaingatecontrol.example.comkommt, hast duGC_BASE_URLim Server-.envnicht gesetzt. - Firewall zwischen Gateway-Host und Internet: UDP 51820 raus muss frei sein. ICMP reicht als Test nicht.
/dev/net/tunvorhanden?
Wenn "No such file or directory":docker exec -it gatecontrol-gateway ls -la /dev/net/tunmodprobe tunam Host ausführen und Container neu starten.
Config-Hash out of sync
Symptom: Neue Route im Admin-UI erscheint nicht im Gateway.
Ursache: Gateway nutzt Pull + Push-Sync. Push kommt vom Server (OK),
Pull alle GC_POLL_INTERVAL_S Sekunden (Default 300 = 5 min).
Fix: Im Admin-UI auf der Gateway-Card Reload triggern — ruft den
Push-Endpoint direkt auf. Alternativ einmal docker compose restart gateway.
"Port 9876 already in use"
Der Health-API-Port (GC_API_PORT in der gateway.env) kollidiert mit
etwas anderem auf dem Host. Peer im Admin-UI bearbeiten, anderen Port
setzen (z.B. 19876), .env neu runterladen.
Weiterführend
- adding-a-route.md — Domain auf einen Gateway-LAN-Host mappen.
- configuring-rdp.md — RDP über Gateway-Routing.
- ../concepts/home-gateway.md — technisches Innenleben des Push+Pull-Sync, Self-Check-Layer, Heartbeat-Protokoll.
- ../API.md —
/api/v1/gateway/…-Endpoints für Automatisierung.