Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).
SSH-Tunnel: Portweiterleitung über SSH¶
Ein SSH-Tunnel leitet TCP-Verbindungen durch eine bestehende, verschlüsselte SSH-Verbindung weiter. Für die getunnelte Anwendung sieht es aus, als käme die Verbindung ganz normal von localhost — tatsächlich läuft sie verschlüsselt über SSH zu einem entfernten Rechner. Damit lassen sich Dienste erreichen, die nicht öffentlich freigegeben sind, ohne eine eigene VPN-Infrastruktur zu betreiben.
Funktionsprinzip¶
Das SSH-Protokoll überträgt mehrere logische Channels über eine einzige TCP-Verbindung (üblicherweise Port 22). Ein Channel trägt die interaktive Shell-Sitzung, ein anderer kann eine reine Portweiterleitung sein. Die weitergeleiteten Daten selbst brauchen kein eigenes Verschlüsselungsprotokoll — SSH übernimmt das für den gesamten Kanal.
Hinweis
Ein SSH-Tunnel ersetzt keine Firewall-Regeln. Er kann sie im Gegenteil faktisch umgehen, wenn SSH-Zugang zu weitreichend vergeben ist — siehe Abschnitt „Absicherung auf dem Server" weiter unten.
Die drei Varianten¶
Local Forwarding (-L)¶
Öffnet einen Port auf dem eigenen Rechner. Verbindungen dorthin werden über den SSH-Server zu ZIEL_HOST:ZIEL_PORT weitergeleitet. ZIEL_HOST muss nicht der SSH-Server selbst sein — er muss nur von dort aus erreichbar sein.
# Admin-Oberfläche, die nur auf localhost:3000 des Servers lauscht
ssh -L 3000:127.0.0.1:3000 admin@server.example.org
# Datenbank auf einem internen Host hinter dem SSH-Server erreichen
ssh -L 5432:db-internal.example.org:5432 admin@server.example.org
Typische Einsatzzwecke: Admin-Oberflächen, Datenbank-Clients, interne Dashboards, einmalige Ersteinrichtungen (siehe Wiki.js: Ersteinrichtung auf einem Headless-Server).
Remote Forwarding (-R)¶
Öffnet einen Port auf dem entfernten Server. Verbindungen dorthin werden zurück zum lokalen Rechner (oder einem von dort erreichbaren Ziel) geleitet.
# lokalen Entwicklungsserver kurzzeitig über einen öffentlichen Server erreichbar machen
ssh -R 8080:127.0.0.1:3000 user@public-server.example.org
Typischer Einsatz: ein Rechner hinter NAT oder Firewall ohne eingehende Verbindungen (z. B. ein Raspberry Pi im Heimnetz) baut selbst eine ausgehende SSH-Verbindung zu einem öffentlichen Server auf und macht sich darüber von außen erreichbar.
Achtung
Standardmäßig lauscht der geöffnete Port auf dem Server nur auf localhost des Servers selbst (GatewayPorts no). Damit er auch von außen erreichbar ist, muss der Server das explizit erlauben — siehe Abschnitt „Absicherung auf dem Server".
Dynamic Forwarding (-D)¶
Öffnet lokal einen SOCKS5-Proxy. Anwendungen, die SOCKS unterstützen (Browser, curl --socks5), können darüber beliebige Ziele ansprechen, die vom SSH-Server aus erreichbar sind — das Ziel wird zur Laufzeit von der Anwendung bestimmt, nicht beim Tunnelaufbau. Faktisch ein Mini-VPN für einzelne Programme.
Tunnel zu Unix-Sockets¶
SSH kann Verbindungen nicht nur zu TCP-Ports, sondern auch zu Unix-Domain-Sockets weiterleiten — auf beiden Seiten des Tunnels:
# lokalen TCP-Port zu einem Unix-Socket auf dem Server weiterleiten
ssh -L 8080:/var/lib/tomcat10/xwiki-socket/xwiki.sock user@server
# lokalen Unix-Socket zu einem entfernten TCP-Ziel weiterleiten
ssh -L /tmp/local.sock:127.0.0.1:5432 user@server
Das ist unter anderem nützlich, um einen Dienst, der absichtlich nur über einen Unix-Socket lauscht — etwa nach den Anleitungen XWiki über Unix-Socket anbinden oder Wiki.js über Unix-Socket anbinden — für eine Wartungssitzung testweise ohne Nginx direkt zu erreichen.
Nützliche Optionen¶
| Option | Wirkung |
|---|---|
-N |
keine Shell öffnen, nur tunneln |
-f |
nach Verbindungsaufbau in den Hintergrund gehen |
-C |
Kompression aktivieren (bei langsamen Leitungen) |
-T |
kein Pseudo-Terminal anfordern |
-o ServerAliveInterval=60 |
Keepalive-Pakete gegen tote Verbindungen |
-o ExitOnForwardFailure=yes |
Tunnelaufbau abbrechen, wenn die Portweiterleitung fehlschlägt (nützlich in Skripten) |
Reiner Hintergrund-Tunnel ohne Shell:
Dauerhafte Tunnel¶
Ein per Hand gestarteter Tunnel bricht bei Netzwerkunterbrechungen ab. Für dauerhafte Verbindungen eignet sich autossh, das die SSH-Verbindung bei Abbruch automatisch neu aufbaut:
sudo apt install autossh
autossh -M 0 -N -o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-L 5432:localhost:5432 user@server
-M 0 deaktiviert den klassischen autossh-Monitor-Port und verlässt sich stattdessen auf die SSH-eigenen Keepalive-Optionen — das ist die heute übliche Empfehlung, da der Monitor-Port selbst einen zusätzlichen offenen Port bedeuten würde.
Für einen dauerhaft laufenden Tunnel als Systemdienst eignet sich ein eigener systemd-Service, siehe systemd-Dienste erstellen.
Kurzform per SSH-Config¶
Häufig genutzte Tunnel lassen sich in ~/.ssh/config als Alias hinterlegen:
Host db-tunnel
HostName server.example.org
User admin
LocalForward 5432 localhost:5432
ServerAliveInterval 60
Danach genügt:
Absicherung auf dem Server¶
Auf dem SSH-Server (/etc/ssh/sshd_config) lässt sich steuern, ob und wie Tunnel überhaupt erlaubt sind:
| Option | Bedeutung | Empfehlung |
|---|---|---|
AllowTcpForwarding |
yes (Default), no, local oder remote — steuert, ob Portweiterleitung grundsätzlich erlaubt ist |
auf reinen Jump-Hosts oder Servern mit strengen Policies auf no setzen |
GatewayPorts |
no (Default), yes oder clientspecified — steuert, ob bei Remote Forwarding auch andere Rechner auf den geöffneten Port zugreifen dürfen |
im Zweifel bei no belassen |
PermitOpen |
schränkt bei erzwungenen Befehlen (ForceCommand) die erlaubten Ziele einer Weiterleitung ein |
für Nutzer mit reinem Tunnel-Zugang (keine Shell) sinnvoll |
Achtung
Ein SSH-Nutzer mit erlaubter Portweiterleitung kann darüber praktisch jeden vom Server aus erreichbaren Dienst ansprechen — auch wenn eine Firewall wie UFW den direkten Zugriff von außen blockiert. SSH-Zugänge deshalb genauso restriktiv vergeben wie offene Ports.
Fehlerbehandlung¶
bind: Address already in use¶
Der lokale Port ist bereits belegt — durch einen alten Tunnel oder eine andere Anwendung.
channel N: open failed: administratively prohibited¶
Der Server erlaubt keine Portweiterleitung für diesen Nutzer oder generell (AllowTcpForwarding no). Serverseitige sshd_config prüfen.
channel N: open failed: connect failed¶
Der SSH-Server konnte das eigentliche Ziel (ZIEL_HOST:ZIEL_PORT) nicht erreichen — Zieladresse, Zielport oder Netzwerkroute vom Server aus prüfen, nicht vom eigenen Rechner aus.
Tunnel scheint zu stehen, reagiert aber nicht mehr¶
Meist eine tote TCP-Verbindung ohne Keepalive. Mit ServerAliveInterval/ServerAliveCountMax arbeiten (siehe oben) oder auf autossh umsteigen.
Wichtige Befehle im Überblick¶
| Aufgabe | Befehl |
|---|---|
| Lokalen Port weiterleiten | ssh -L LOKALER_PORT:ZIEL_HOST:ZIEL_PORT user@server |
| Entfernten Port weiterleiten | ssh -R REMOTE_PORT:ZIEL_HOST:ZIEL_PORT user@server |
| SOCKS-Proxy öffnen | ssh -D LOKALER_PORT user@server |
| Nur tunneln, keine Shell, im Hintergrund | ssh -N -f -L … user@server |
| Laufende Tunnel finden | ps aux \| grep "ssh -" |
| Belegten lokalen Port finden | sudo ss -ltnp \| grep PORT |
Verwandte Themen¶
- UFW-Firewall installieren und steuern
- systemd-Dienste erstellen
- XWiki über Unix-Socket anbinden
- Wiki.js über Unix-Socket anbinden
- Wiki.js nativ unter Linux installieren
Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).