SSH-Tunneling in einen lokalen Netzwerkcomputer über einen Server
Ich möchte eine SSH-Verbindung für einen externen Administrator zu einer Centos-Maschine vorbereiten.
Folgendes Setup:
- HostA: Server mit statischer IP-Adresse
- HostB: Local-CentOS-Maschine
- HostC: Externes Admin-System
Verbindungslayout: HostC > HostA > (Router) > HostB
Ich habe die folgenden Befehle bei HostB ausprobiert:
ssh -R Port:user@HostB:22 user@HostA
ssh user@HostB -p Port # --> Timeout here
Ich möchte den Router nicht berühren, ich denke, es ist nicht unbedingt notwendig. Die SSH-Verbindung zu HostA (Linode-Server) funktioniert einwandfrei. Netstat zeigt, dass das PORTzuhört. Der zweite Befehl läuft jedoch ab. Was könnte der Grund sein?
Wie würde eine Verbindung von HostC hergestellt? Würde der folgende Befehl funktionieren?
ssh -t HostA 'ssh HostB -p Port'
Andere Bedingungen:
- Ich habe bereits
GatewayPorts yesbei HostA eingestellt. - HostA erlaubt nur Verbindungen über Schlüsseldateien.
- HostA kennt die öffentlichen Schlüssel bereits von HostB und HostC.
- HostB verwendet ssh-Standardkonfigurationen
- Ufw-Firewalls auf allen Computern (Port 22 und 10022 sind geöffnet)
Gibt es eine einfachere Möglichkeit, eine sichere Verbindung herzustellen, ohne sich um den Router sorgen zu müssen?
Antworten
Es gibt mindestens zwei Lösungen mit ssh -R, Sie scheinen ihre Teile zu mischen. Es gibt wenig mehr, was falsch ist.
Beim Abhören von HostA ist der Port nach außen offen
Es ist fast ein Duplikat dieser Frage: Zugriff auf den lokalen Host-Webserver über einen umgekehrten SSH-Tunnel und eine URL . Ich glaube, das Hauptproblem hier ist dasselbe, meine Antwort auf die andere Frage trifft zu, aber es reicht nicht aus.
Ihr Befehl war wie folgt:
# on HostB
ssh -R 10022:user@HostB:22 user@HostA
Es sollte eher so sein:
# on HostB
ssh -R :10022:localhost:22 user@HostA
Was wurde behoben?
Das
:Vorher10022, mit nichts vor, definiert ein Leerzeichenbind_address. Ohne sie würde der SSH-Server auf HostA nur an die Loopback-Schnittstellelocalhost:10022gebunden, dh auf HostA, auf die von außen nicht zugegriffen werden kann. Ein Leerzeichenbind_addressbedeutet "alle Schnittstellen". Siehe meine Antwort auf die verknüpfte Frage für Details.Das Ziel der Remoteweiterleitung wird auf dem lokalen Computer gelöst, in Ihrem Fall auf HostB. Es reicht höchstwahrscheinlich aus, um den SSH-Server auf HostB von HostB selbst
localhostaus zu erreichen. Dies liegt daran, dass SSH-Server normalerweise ihre Loopback-Schnittstellen abhören. Eine weitere Adresse , die Punkte zu HostB kann auch funktionieren, aberlocalhostoder127.0.0.1ist die KISS -able ein in einem solchen Fall.Bei der Angabe des Ziels dürfen Sie keinen Benutzer angeben. Ich meine,
HostBals Ziel könnte es funktionieren, aber nichtuser@HostB. In Ihrem Fall schien letzteres zu funktionieren, da die Adresse nur aufgelöst wird, wenn jemand den Tunnel tatsächlich benutzt. Sie haben es nie geschafft, den Tunnel zu benutzen. Wenn Sie dies tun würden, würde dersshProzess (der mit-R, auf HostB) ergeben:connect_to user@HostB: unknown host (Name or service not known)Zumindest sagt dies OpenSSH in meinem Debian 10.
Anmerkungen:
- Betrachten
-Noder-N -fOptionen (sieheman 1 ssh); oderautossh. GatewayPorts yesIn der SSH-Serverkonfiguration auf HostA ist das Richtige.- Eine vernünftige Firewall auf HostB sollte keine Verbindungen zur Loopback-Schnittstelle blockieren, es ist keine Konfiguration erforderlich. Es ist irrelevant, ob der TCP-Port
22für die Außenwelt offen ist. - Die Firewall auf HostA sollte den TCP-Port öffnen
10022(und natürlich22oder welchen Port auch immer der SSH-Server überwacht).
Dann verbinden Sie sich über das Internet wie folgt:
# on HostC or wherever
ssh -p 10022 userB@HostA
Beachten Sie, dass der Befehl für HostC HostB in keiner Weise angibt, aber userB auf HostB gültig sein sollte und Anmeldeinformationen für verwendet werden sollten userB@hostB. Wenn eine schlüsselbasierte Authentifizierung verwendet werden soll, sollte HostC den Schlüssel halten. Schlüssel auf HostA spielen keine Rolle. Es ist, als würde der SSH-Server von HostB mithören HostA:10022. Die Adresse gehört HostA, aber einer erreicht den auf HostB ausgeführten SSH-Server. Der Tunnel selbst ist transparent. Ich meine, Sie können vergessen, dass der Tunnel existiert, HostA:10022als Adresse von HostB behandeln und einfach die sshSyntax verwenden. ZB den folgenden Befehl:
# on HostC or wherever
ssh -p 10022 userB@HostA hostname
wird (versucht) hostnameauf HostB ausgeführt.
HostA abhören, der von HostA verfügbare Port
Wenn Sie tun:
# on HostB
ssh -R :10022:localhost:22 user@HostA
Dann überwacht der SSH-Server auf HostA alle Schnittstellen, einschließlich der Loopback-Schnittstelle von HostA. Wenn Sie etwas ähnlicheres tun als das, was Sie versucht haben:
# on HostB
ssh -R 10022:localhost:22 user@HostA
(Beachten Sie, dass es :vorher keine gibt 10022) Dann hört der Server nur die Loopback-Schnittstelle ab. In jedem Fall sollten Sie in der Lage sein, von HostA aus eine Verbindung zu HostB herzustellen:
# on HostA
ssh -p 10022 userB@localhost
wo userBist auf HostB gültig. Dies bedeutet, dass man dies tun kann:
# on HostC or wherever
ssh user@HostA # or any other userA valid on HostA
# now we're on HostA
ssh -p 10022 userB@localhost
Oder in einer einzigen Zeile:
# on HostC or wherever
ssh -t userA@HostA 'ssh -p 10022 userB@localhost'
Unterschiede zur ersten Methode:
- In einigen Fällen muss man
-texplizit verwenden. - Eine vernünftige Firewall auf HostA sollte keine Verbindungen zur Loopback-Schnittstelle blockieren, es ist keine Konfiguration erforderlich. Es ist irrelevant, ob der TCP-Port
10022für die Außenwelt offen ist. Dies bedeutet, dass die Methode möglicherweise auch dann funktioniert, wenn Sie kein Administrator auf HostA sind. Zusätzlich … GatewayPorts(eine andere Sache, die ein Nicht-Administrator nicht anpassen kann) muss nicht unbedingt seinyes.- Die Verbindung zu HostB erfolgt über HostA. Wenn eine schlüsselbasierte Authentifizierung verwendet werden soll, sollte HostA den Schlüssel halten. Es gibt ein Konzept zum Weiterleiten der Authentifizierungsagentenverbindung, damit HostC den Schlüssel halten kann. Alternativ ist es möglich, einen Tunnel von HostC zu HostB zu erstellen, damit HostC später über zwei verkettete Tunnel den SSH-Server von HostB erreichen und seinen eigenen Schlüssel verwenden kann. Ich werde nicht näher darauf eingehen.
- Man muss SSH-Zugang zu HostA haben. Wenn Sie nicht von HostC aus eine Verbindung herstellen, sollten Sie dies vermeiden. Dann bevorzugen Sie die erste Methode.