memmex
Lt. Junior Grade
- Registriert
- Juni 2008
- Beiträge
- 408
[How-To] Zugriff von außen hinter DoubleNAT / DS-Lite / Firewall mittels Reverse SSH Tunnel
1. Das Problem
Falls der Heimanschluss keine öffentliche IP hat, lässt sich aus dem Internet nicht auf Dienste im eigenen Heimnetz zugreifen oder eine VPN-Verbindung herstellen.
Dies ist beispielsweise der Fall, wenn
2. Die Lösungsidee
In den obig aufgezählten Beispielen ist jeweils von der Seite des Internets kein "Durchkommen" in das Heimnetzwerk. Wir können aber natürlich aus dem Heimnetzwerk auf beliebige Dienste im Internet zugreifen.
Der Trick eines SSH Reverse Tunnels ist es, vom Heimnetzwerk aus eine Verbindung zu einem Relayserver im Internet herzustellen und diese Verbindung immer offen zu halten. Sie fungiert als Tunnel (ähnlich einem VPN-Tunnel), durch den Traffic wieder in das Heimnetz geschickt werden kann. Der SSH Tunnel übernimmt ebenfalls die Transportverschlüsselung der Daten.
Befindet man sich beispielsweise mit einem Laptop in einem öffentlichen Netzwerk und möchte auf die nextcloud-Instanz im Heimnetz zugreifen, dann öffnet man im Browser die Adresse
2.1. Achtung
Ihr betreibt bei dieser Vorgehensweise einen eigenen Server im Internet. Ihr seid alleine für die sichere Konfiguration und Wartung dessen verantwortlich. Informiert euch vorher über die rechtlichen Einschränkungen und mögliche Haftungsrisiken.
Desweiteren öffnet ihr Ports, die direkt in euer Heimnetzwerk führen. Die offenen Ports kann sich jeder mit einem Portscanner anzeigen lassen und jede Person im Internet kann sich mit diesen offenen Ports verbinden. Öffnet nur Ports in euer Heimnetz, wenn ihr genau wisst, was ihr macht.
Natürlich dürfen keine Ports in fremde Netze (Cafes, Hotels, Arbeitsplatz, ...) hinein durch SSH Tunnel geöffnet werden.
3. Was wird benötigt?
3.1. Welcher Server eignet sich als Relayserver?
Als Relayserver eignet sich jede Instanz im Internet, zu der ihr vollen Rootzugriff habt und der eine feste IP zugewiesen wurde.
Ich empfehle ein Relay mit Serverstandort Deutschland zu wählen. Dies verringert die Pingzeiten und gewährt deutsche Gesetze des Datenschutzes, da der gesamte getunnelte Datenverkehr über das Relay läuft.
Der Relayserver benötigt kaum CPU-Leistung, noch RAM und auch keinen Festplattenplatz. Einzig die Bandbreite des Relayservers sollte mindestens so schnell sein, wie eure Internetverbindung.
Ich empfehle den kleinsten Server bei Hetzner (CX11) für weniger als 3 € im Monat mit 20 TB High-Speed-Traffic. Alternativ bietet Strato den kleinsten vServer V3 für 1 € im Monat an.
4. Vorgehen
4.1 SSH Keys erstellen
Um einen Tunnel aufzubauen, muss der Localserver eine SSH Verbindung zum Relayserver aufbauen können.
Zur Authentifizierung verwenden wir SSH Keys. Dies erhöht die Sicherheit gegenüber Passwörtern erheblich und bietet auch Vorteile bei der späteren Automatisierung.
Alle folgenden Befehle in diesem Tutorial werden unter beiden Systemen als User
Wir benötigen sowohl auf dem Local- als auch auf dem Relayserver SSH Schlüssel und generieren sie jeweils mit
Damit sich der Localserver beim Relayserver anmelden kann, muss der Public Key des Localservers als ein authorisierter Schlüssel im Relayserver hinterlegt werden:
Wir testen die Anmeldung
4.2 SSH Konfiguration anpassen
In der Standardeinstellung erlaubt der SSH Dienst keine Weiterleitungen, so dass wir dessen Config auf beiden Servern anpassen müssen:
4.3 Unser erster SSH Reverse Tunnel
Wir sind nun bereit, den ersten SSH Reverse Tunnel zu starten. Dies funktioniert mit dem Programm
Testweise leiten wir jetzt die Ports 80 (HTTP) und 443 (HTTPS) weiter. Außerdem möchten wir uns auch per SSH (Port 22) mit unserem Localserver verbinden können.
Es ist wichtig, dass die Ports weder auf dem Local- noch auch auf dem Relayserver bereits belegt sind. In unserem Fall ist der Port 22 auf dem Relayserver bereits in Benutzung, da wir auf diesem Port unseren SSH Tunnel starten. Wir weichen auf dem Relayserver auf Port 22022 aus.
Bei den Platzhaltern
Wir können mit dem Befehl
Anschließend schließen wir den Tunnel auf dem Localserver wieder mit
4.4 SSH Reverse Tunnel automatisch starten und neu aufbauen
Wir möchten, dass sich der Tunnel zum Relayserver beim Start des Localservers automatisch aufbaut. Dies soll auch geschehen, falls eine Seite das Internet verliert und deshalb der Tunnel zusammenbricht.
Genau für diese Aufgabe wurde das Programm autossh geschrieben, das wir noch auf dem Localserver installieren müssen:
Zur besseren Übersicht und Anpassbarkeit erstellen wir ein kleines Skript auf dem Localserver
Das Skript führen wir bei jedem Neustart mittels
Nach einem Neustart des Localservers
5. Abschließende Worte
Vielen Dank für das Lesen meines Guides. Ich hoffe, dass ich euch helfen konnte!
Abschließend möchte ich noch einmal darauf hinweisen, dass dies eine mögliche Lösung ist, um dem DS-Lite / DoubleNAT Problem zu begegnen. Sie ist aber sicherlich nicht für jeden Anwender geeignet.
Für weitere Anmerkungen und Korrekturen gerne im Thread kommentieren.
Viele Grüße
memmex
Versionsverlauf:
1. Das Problem
Falls der Heimanschluss keine öffentliche IP hat, lässt sich aus dem Internet nicht auf Dienste im eigenen Heimnetz zugreifen oder eine VPN-Verbindung herstellen.
Dies ist beispielsweise der Fall, wenn
- eine zweite Firewall aktiv ist, auf die man kein Zugriff hat (Wohnheim, Untermiete, ...).
- Dual Stack Lite (DS-Lite) genutzt wird (Kabelnetzbetreiber, ...).
- Double NAT (Double Network Address Translation) eingesetzt wird (zweiter Router des ISP, ...).
- mittels Mobilfunk auf das Internet zugegriffen wird.
2. Die Lösungsidee
In den obig aufgezählten Beispielen ist jeweils von der Seite des Internets kein "Durchkommen" in das Heimnetzwerk. Wir können aber natürlich aus dem Heimnetzwerk auf beliebige Dienste im Internet zugreifen.
Der Trick eines SSH Reverse Tunnels ist es, vom Heimnetzwerk aus eine Verbindung zu einem Relayserver im Internet herzustellen und diese Verbindung immer offen zu halten. Sie fungiert als Tunnel (ähnlich einem VPN-Tunnel), durch den Traffic wieder in das Heimnetz geschickt werden kann. Der SSH Tunnel übernimmt ebenfalls die Transportverschlüsselung der Daten.
Befindet man sich beispielsweise mit einem Laptop in einem öffentlichen Netzwerk und möchte auf die nextcloud-Instanz im Heimnetz zugreifen, dann öffnet man im Browser die Adresse
111.202.22.222:443
. Die Anfrage wird durch den Tunnel an die lokale IP 10.10.0.100:443
weitergegeben und die Antwort auf gleichem Weg wieder zugestellt.2.1. Achtung
Ihr betreibt bei dieser Vorgehensweise einen eigenen Server im Internet. Ihr seid alleine für die sichere Konfiguration und Wartung dessen verantwortlich. Informiert euch vorher über die rechtlichen Einschränkungen und mögliche Haftungsrisiken.
Desweiteren öffnet ihr Ports, die direkt in euer Heimnetzwerk führen. Die offenen Ports kann sich jeder mit einem Portscanner anzeigen lassen und jede Person im Internet kann sich mit diesen offenen Ports verbinden. Öffnet nur Ports in euer Heimnetz, wenn ihr genau wisst, was ihr macht.
Natürlich dürfen keine Ports in fremde Netze (Cafes, Hotels, Arbeitsplatz, ...) hinein durch SSH Tunnel geöffnet werden.
3. Was wird benötigt?
- einen Localserver mit einem Linuxbetriebssystem (Raspberry Pi, Heimserver, NAS, ...)
- einen Relayserver mit einem Linuxbetriebssystem, root Zugang und einer festen IP bzw. (optional) einem Domainnamen (vServer, dedizierter Server, ...)
- grundlegende Linuxkenntnisse
3.1. Welcher Server eignet sich als Relayserver?
Als Relayserver eignet sich jede Instanz im Internet, zu der ihr vollen Rootzugriff habt und der eine feste IP zugewiesen wurde.
Ich empfehle ein Relay mit Serverstandort Deutschland zu wählen. Dies verringert die Pingzeiten und gewährt deutsche Gesetze des Datenschutzes, da der gesamte getunnelte Datenverkehr über das Relay läuft.
Der Relayserver benötigt kaum CPU-Leistung, noch RAM und auch keinen Festplattenplatz. Einzig die Bandbreite des Relayservers sollte mindestens so schnell sein, wie eure Internetverbindung.
Ich empfehle den kleinsten Server bei Hetzner (CX11) für weniger als 3 € im Monat mit 20 TB High-Speed-Traffic. Alternativ bietet Strato den kleinsten vServer V3 für 1 € im Monat an.
4. Vorgehen
4.1 SSH Keys erstellen
Um einen Tunnel aufzubauen, muss der Localserver eine SSH Verbindung zum Relayserver aufbauen können.
Zur Authentifizierung verwenden wir SSH Keys. Dies erhöht die Sicherheit gegenüber Passwörtern erheblich und bietet auch Vorteile bei der späteren Automatisierung.
Alle folgenden Befehle in diesem Tutorial werden unter beiden Systemen als User
root
ausgeführt.Wir benötigen sowohl auf dem Local- als auch auf dem Relayserver SSH Schlüssel und generieren sie jeweils mit
ssh-keygen
. Wir geben keine Passphrase an und der Speicherort wird ebenfalls nicht verändert.Damit sich der Localserver beim Relayserver anmelden kann, muss der Public Key des Localservers als ein authorisierter Schlüssel im Relayserver hinterlegt werden:
ssh-copy-id -i /root/.ssh/id_rsa.pub root@<relayip>
.Wir testen die Anmeldung
ssh root@<relayip>
und bestätigen die Serveridentität.4.2 SSH Konfiguration anpassen
In der Standardeinstellung erlaubt der SSH Dienst keine Weiterleitungen, so dass wir dessen Config auf beiden Servern anpassen müssen:
nano /etc/ssh/sshd_config
.
Bash:
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
AllowTcpForwarding yes
GatewayPorts yes
ClientAliveInterval 30
ClientAliveCountMax 4
- Normalerweise empfehle ich, den SSH Zugang für
root
generell zu sperren. Wir befinden uns aber in der Situation, dass Ports <1024 nur vonroot
abgefangen und weitergeleitet werden dürfen. - Zum sicheren Betrieb eines Servers sollte immer der Passwortzugang abgeschaltet und die Schlüsselauthentifizierung erlaubt werden.
AllowTcpForwarding
undGatewayPorts
sind notwendig, um einen SSH Reverse Tunnel aufzubauen und Daten durch ihn zu leiten.ClientAliveInterval
undClientAliveCountMax
bestimmen, wie häufig ein künstliches Paket durch den Tunnel gesendet wird, um ihn aufrecht zu erhalten. Mit den obigen Werten habe ich persönlich gute Erfahrungen gemacht.
shutdown -r now
.4.3 Unser erster SSH Reverse Tunnel
Wir sind nun bereit, den ersten SSH Reverse Tunnel zu starten. Dies funktioniert mit dem Programm
ssh
und folgender Syntax auf dem Localserver:
Bash:
ssh -N -R <relayport>:<localip>:<localport> root@<relayip>
ssh
öffnet normalerweise eine Shell auf dem Relayserver. Dieses Verhalten unterbinden wir mit-N
.- Eine Portweiterleitung wird jeweils mit der Option
-R
eingeleitet. - Die genaue Funktion der verschiedenen Schalter ist in man ssh nachzulesen.
Testweise leiten wir jetzt die Ports 80 (HTTP) und 443 (HTTPS) weiter. Außerdem möchten wir uns auch per SSH (Port 22) mit unserem Localserver verbinden können.
Es ist wichtig, dass die Ports weder auf dem Local- noch auch auf dem Relayserver bereits belegt sind. In unserem Fall ist der Port 22 auf dem Relayserver bereits in Benutzung, da wir auf diesem Port unseren SSH Tunnel starten. Wir weichen auf dem Relayserver auf Port 22022 aus.
Bash:
ssh -N -R 80:127.0.0.1:80 -R 443:127.0.0.1:443 -R 22022:127.0.0.1:22 root@<relayip>
<localip>
und <relayip>
können sowohl IP-Adressen als auch Domainnamen angegeben werden. Der Localserver kann außerdem den Traffic an jede weitere <localip>
im Heimnetzwerk weiterreichen.Wir können mit dem Befehl
netstat -tulpen | grep -v 127.0.0.1
sehen, welche Ports auf dem Server momentan geöffnet sind. Auf dem Relayserver sehen wir den geöffneten Tunnel.Anschließend schließen wir den Tunnel auf dem Localserver wieder mit
CTRL+C
.4.4 SSH Reverse Tunnel automatisch starten und neu aufbauen
Wir möchten, dass sich der Tunnel zum Relayserver beim Start des Localservers automatisch aufbaut. Dies soll auch geschehen, falls eine Seite das Internet verliert und deshalb der Tunnel zusammenbricht.
Genau für diese Aufgabe wurde das Programm autossh geschrieben, das wir noch auf dem Localserver installieren müssen:
apt -y install autossh
.Zur besseren Übersicht und Anpassbarkeit erstellen wir ein kleines Skript auf dem Localserver
touch /opt/ssh_tunnel.sh
und machen es ausführbar chmod +x /opt/ssh_tunnel.sh
.nano /opt/ssh_tunnel.sh
:
Bash:
#!/bin/bash
#
echo "" && echo "" && echo ""
echo "-- start autossh --"
/usr/bin/autossh -M 0 -f -N -v -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" -o "ExitOnForwardFailure yes" -R 80:127.0.0.1:80 -R 443:127.0.0.1:443 -R 22022:127.0.0.1:22 root@<relayip>
#
echo "" && echo "" && echo ""
echo "use 'kill -9 \$(pidof autossh) && kill -9 \$(pidof /usr/bin/ssh)' to kill autossh"
#
echo "" && echo "" && echo ""
-N
und-R
sind die gleichen Schalter vonssh
wie oben.-M 0
deaktiviert die Monitorfunktion vonautossh
.-f
startetssh
im Hintergrund.-v
Verbose Mode.ServerAliveInterval
undServerAliveCountMax
erfüllen eine analoge Funktion auf der Serverseite wieClientAliveInterval
undClientAliveCountMax
.ExitOnForwardFailure
bewirkt, dass der Tunnelaufbau fehlschlägt, falls die angeforderten Ports belegt sind.
Das Skript führen wir bei jedem Neustart mittels
crontab
aus.crontab -e
:
Bash:
@reboot /bin/bash /opt/ssh_tunnel.sh >> /tmp/cron.log
Nach einem Neustart des Localservers
shutdown -r now
sehen wir auf beiden Servern mit netstat -tulpen | grep -v 127.0.0.1
die offenen Ports und auch die Programme autossh
und ssh
in der Prozessorliste htop
des Localservers.5. Abschließende Worte
Vielen Dank für das Lesen meines Guides. Ich hoffe, dass ich euch helfen konnte!
Abschließend möchte ich noch einmal darauf hinweisen, dass dies eine mögliche Lösung ist, um dem DS-Lite / DoubleNAT Problem zu begegnen. Sie ist aber sicherlich nicht für jeden Anwender geeignet.
Für weitere Anmerkungen und Korrekturen gerne im Thread kommentieren.
Viele Grüße
memmex
Versionsverlauf:
- 2019.07.20: Veröffentlichung
- 2019.07.21: kleine Korrekturen
- 2021.11.05: Anpassungen von Formulierungen
Zuletzt bearbeitet: