7.3 KiB
Portainer EE mit Remote-Agent (Hetzner) über SSH-Tunnel
Ziel
Lokaler Portainer EE verwaltet zusätzlich einen entfernten Docker-Host (Hetzner), ohne dass der Agent-Port (9001) öffentlich erreichbar ist. Der Key für die EE ist in Bitwarden hinterlegt.
Die Verbindung erfolgt ausschließlich über einen SSH-Tunnel.
Architektur
Übersicht
- Heimserver: Portainer EE
- Hetzner-Server: Portainer Agent
- Verbindung: SSH-Tunnel (autossh + systemd)
- Kein öffentlicher Port 9001
Netzwerkarchitektur mit Namespace- und Layer-Trennung
┌────────────────────────────┐
│ Internet │
└──────────────┬─────────────┘
│
│ SSH (TCP 22)
│
┌──────────────────────────┴──────────────────────────┐
│ Hetzner VPS (Host OS) │
│------------------------------------------------------│
│ │
│ Docker Engine │
│ ┌──────────────────────────────────────────────┐ │
│ │ portainer_agent Container │ │
│ │----------------------------------------------│ │
│ │ Agent lauscht auf: 0.0.0.0:9001 │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ Host-Port-Mapping: 9001 -> Container 9001 │
└──────────────────────────┬───────────────────────────┘
│
│ localhost:9001
============================================== SSH Tunnel ==============================================
ssh -L 0.0.0.0:9002:localhost:9001 root@hetzner-ip
=========================================================================================================
│
│ 0.0.0.0:9002 (Heimserver Host)
┌──────────────────────────┴──────────────────────────┐
│ Heimserver (Host OS) │
│------------------------------------------------------│
│ │
│ autossh Service │
│ lauscht auf: 0.0.0.0:9002 │
│ │
│ Docker Bridge Netzwerk │
│ IP: 172.17.0.1 │
│ │
│ Docker Engine │
│ ┌──────────────────────────────────────────────┐ │
│ │ portainer-ee Container │ │
│ │----------------------------------------------│ │
│ │ Verbindet zu: 172.17.0.1:9002 │ │
│ │ (Host-Bridge-IP) │ │
│ └──────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────┘
Funktionsweise
- Der Portainer-Agent läuft auf Hetzner und lauscht auf Port 9001.
- Dieser Port ist nicht öffentlich relevant, da keine direkte Nutzung erfolgt.
- Der Heimserver baut per SSH einen Tunnel auf:
- Lokaler Port 9002 → Hetzner localhost:9001
- Portainer EE verbindet sich intern über: 172.17.0.1:9002 (docker bridge)
- Der gesamte Traffic läuft verschlüsselt über SSH.
# 1. Portainer-Agent auf Hetzner
## docker-compose.yml
``` yaml
version: "3.8"
services:
portainer_agent:
image: portainer/agent:2.27.3
container_name: portainer_agent
restart: unless-stopped
ports:
- "9001:9001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
Starten: docker compose up -d Prüfen: ss -tlnp | grep 9001 Erwartet: 0.0.0.0:9001
2. SSH-Tunnel automatisieren (Heimserver)
autossh installieren
apt update apt install autossh -y
systemd Service anlegen
Datei: /etc/systemd/system/portainer-hetzner-tunnel.service
Inhalt:
[Unit]
Description=SSH Tunnel to Hetzner Portainer Agent
After=network.target
[Service]
User=root
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh \
-M 0 \
-N \
-o "ServerAliveInterval=30" \
-o "ServerAliveCountMax=3" \
-o "ExitOnForwardFailure=yes" \
-o "StrictHostKeyChecking=no" \
-i /root/.ssh/portainer_tunnel \
-L 0.0.0.0:9002:localhost:9001 \
root@65.
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
## Service aktivieren
``` snippet
systemctl daemon-reload
systemctl enable portainer-hetzner-tunnel
systemctl start portainer-hetzner-tunnel
Status prüfen:
systemctl status portainer-hetzner-tunnel
Port prüfen:
ss -tlnp | grep 9002
Erwartet:
0.0.0.0:9002
3. Portainer EE konfigurieren
In der WebUI: Environments → Add Environment → Agent Adresse: 172.17.0.1:9002 Hinweis: 172.17.0.1 ist die Docker-Bridge-IP des Hosts Portainer läuft im Container Der Tunnel läuft auf dem Host
Sicherheitsmodell
- Port 9001 nicht öffentlich erreichbar
- Kommunikation ausschließlich über SSH
- SSH-Key-basierte Authentifizierung
- Automatischer Reconnect via autossh
- Kein zusätzlicher VPN erforderlich
Troubleshooting
|Problem |Ursache | Prüfen |connection refused |Agent nicht auf 9001 gemappt | - ports9001:9001 in der docker-compose |SSH channel open failed |Agent lauscht nicht |keys vorhanden? |Endpoint unreachable |Tunnel nicht aktiv |curl localhost:9001 schlägt fehl |Agent läuft nicht korrekt