So konfigurieren Sie eine Verknüpfung für eine SSH-Verbindung über einen SSH-Tunnel

22

Die Produktionsserver meiner Firma (FOO, BAR ...) befinden sich hinter zwei Gateway-Servern (A, B). Um eine Verbindung zum Server FOO herzustellen, muss ich mit meinem Benutzernamen JOHNDOE eine SSH-Verbindung zu Server A oder B herstellen. Von A (oder B) aus kann ich dann auf jeden Produktionsserver zugreifen, der eine SSH-Verbindung mit einem Standardbenutzernamen herstellt (nennen wir ihn) WEBBY).

Also muss ich jedes Mal etwas machen wie:

ssh johndoe@a
...
ssh webby@foo
...
# now I can work on the server

Wie Sie sich vorstellen können, ist dies ein Ärger, wenn ich scpmehrere Verbindungen schnell öffnen muss.

Ich habe einen SSH-Schlüssel konfiguriert und verwende auch .ssh / config für einige Verknüpfungen.

Ich habe mich gefragt, ob ich eine Art SSH-Konfiguration erstellen kann, um zu tippen

ssh foo

und lassen Sie SSH alle Verbindungen für mich öffnen / weiterleiten. Ist es möglich?

Bearbeiten

Die Antwort von womble ist genau das, wonach ich gesucht habe, aber im Moment kann ich netcat nicht verwenden, da es nicht auf dem Gateway-Server installiert ist.

weppos:~ weppos$ ssh foo -vv
OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/xyz/.ssh/config
debug1: Applying options for foo
debug1: Reading configuration data /etc/ssh_config
debug2: ssh_connect: needpriv 0
debug1: Executing proxy command: exec ssh a nc -w 3 foo 22
debug1: permanently_drop_suid: 501
debug1: identity file /Users/xyz/.ssh/identity type -1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_rsa type 1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_dsa type 2
bash: nc: command not found
ssh_exchange_identification: Connection closed by remote host
Simone Carletti
quelle

Antworten:

36

Als konkretere Version von Kyles Antwort möchten Sie Folgendes in Ihre ~/.ssh/configDatei einfügen:

host foo
  User webby
  ProxyCommand ssh a nc -w 3 %h %p

host a
  User johndoe

Wenn Sie dann "ssh foo" ausführen , versucht SSH, SSH johndoe@aauszuführen netcat( nc) und dann SSH auszuführen, webby@fooum diesen Tunnel zu durchlaufen. Zauber!

Dazu muss netcat natürlich auf dem Gateway-Server installiert sein. Dieses Paket ist für alle wichtigen Distributionen und Betriebssysteme verfügbar.

womble
quelle
Ausgezeichnet! Ich habe versucht, das herauszufinden, ich war noch nie in genau diese Situation geraten. Ich werde meine Antwort dort aufbewahren, falls es in Zukunft jemand anderem mit einer weniger spezifischen Situation helfen könnte.
Kyle Brandt
Ich habe meine ursprüngliche Frage einschließlich der ausführlichen Ausgabe meiner Verbindung aktualisiert. Es scheint, dass ich netcat nicht benutzen kann. Sollte es standardmäßig verfügbar sein?
Simone Carletti
Haben Sie nicht immer die Macht, es zu installieren? Möglicherweise können Sie dies auch mit Telnet tun, das habe ich noch nie versucht ...
Kyle Brandt
Möglicherweise können Sie netcat auch in Ihr Home-Verzeichnis herunterladen und dort kompilieren. Sie könnten dann einfach den vollständigen Pfad im Proxy-Befehl verwenden, dh / home / userName / bin / nc
Kyle Brandt
Ich habe gerade die Systemeinstellungen überprüft. Auf Ubuntu scheint Netcat standardmäßig verfügbar zu sein, leider werden die Gateway-Server von OpenSUSE betrieben. Ich werde in Betracht ziehen, Netcat auch auf den Gateway-Servern zu installieren.
Simone Carletti
7

Sie können die ProxyCommand-Direktive in Ihrer ~ / .ssh / config-Datei verwenden, um beispielsweise netcat als Relay zu verwenden:

host server2
    ProxyCommand ssh server1 nc server2 22

Das würdest du einfach mit 'ssh server2' machen. Die Manpage-Informationen für diese Direktive finden Sie in 'man ssh_config'.

Kyle Brandt
quelle
5

Ich bevorzuge einen anderen Ansatz, der einen vorauthentifizierten Tunnel zum Gateway-Server aufrechterhält. In ~/.ssh/config:

Host a
    ControlMaster auto
    ControlPath ~/.ssh/control-master/%r@%h:%p

Dann in .bashrc:

s () {
        if ( ssh -O check a 2>&1 > /dev/null 2>&1 )
        then
                ssh -t a ssh $1
        else
                if [[ -S ~/.ssh/control-master/insyte@a:22 ]]
                then
                        echo "Deleting stale socket..."
                        rm ~/.ssh/control-master/insyte@a:22
                fi
                echo "Opening master session..."
                if ssh -Nf a
                then
                         ssh -t a ssh $1
                fi
        fi
 }

So verbinden Sie sich mit foo:

s foo

Wenn Sie das erste Mal eine Verbindung herstellen, werden Sie mit "a" authentifiziert und ein dauerhafter SSH-Tunnel mit Hintergrund wird geöffnet. Nachfolgende Aufrufe von "s" werden fast augenblicklich durch den vorauthentifizierten Tunnel geöffnet.

Funktioniert super.

Insyte
quelle
2

Diese Art von Funktionalität ist in neueren Versionen von OpenSSH vorhanden und kann auf diese Weise verwendet werden

ssh -W server2 server1

Wo server2ist Ihr beabsichtigtes Ziel und server1ist Ihr Proxy-Host. Sie können dies vereinfachen, indem Sie die ProxyCommandOption in Ihrer ssh-Konfiguration verwenden, etwa:

host = *.example.com
user = packs
port = 22
ProxyCommand ssh -W %h:%p server1
Scott Pack
quelle
Es scheint, dass Sie dafür OpenSSH 5.4+ an allen drei Standorten benötigen: Desktop, Vermittler, Ziel. (Nun, der erste und der letzte sicherlich).
Steve Bennett
@SteveBennett: Ich benutze diese Methode schon eine Weile, sie funktioniert ziemlich gut. Ich musste auf ein paar RHEL5-Systemen auf die Netcat-Methode zurückgreifen, was ärgerlich war.
Scott Pack
2

Wenn netcatder Proxy nicht verfügbar ist, probieren Sie diesen Trick:

host foo
  User webby      
  ProxyCommand ssh a 'exec 3<>/dev/tcp/foo/22; cat <&3 & cat >&3;kill $!'

host a
  User johndoe

Dann sollten Sie in der Lage sein ssh foo.

Wenn Sie eine aktuelle Version von ssh auf a haben (dh mit dem -WBefehl zum Weiterleiten der Standardeingabe und -ausgabe), können Sie möglicherweise Folgendes verwenden:

host foo
  User webby
  ProxyCommand ssh -W foo:%p a

host a
  User johndoe

Schließlich, nur weil ich es cool fand (und nicht, weil es in Ihrem speziellen Fall aufgrund von Benutzernamenunterschieden funktioniert), zeigt der Blog-Beitrag eines Freundes , wie man solche Dinge dynamisch macht und rekursiv SSH-Proxys verkettet (zusammen mit einigen Dingen) das funktioniert nicht gut):

host */*
  ProxyCommand ssh ${$(dirname %h)/\%%/@} nc ${$(basename %h)#*%%} %p

Und dann ssh machine1/machine2solltest du dir eine Granate machine2zulegen, die durchtunnelt ist machine1.

Ich frage mich, ob Sie benutzerdefinierte sedBefehle anstelle von verwenden dirnameund basenamedas Problem möglicherweise nicht mit anderen Benutzernamen lösen.

Paul Price
quelle
2

Dies kann dadurch erreicht werden ssh -At johndoe@a ssh webby@foo. Der -ABefehl leitet Ihren ssh-Agenten weiter (sodass Sie keine erneute Authentifizierung am Proxy vornehmen müssen), während -tsichergestellt wird, dass auf dem Proxy ein Terminal vorhanden ist. Die folgende Bash-Funktion kann nützlich sein:

ssh-bounce () {
    local cmd=""
    for i in "$@"; do
        cmd+="ssh -At $i "
    done
    $cmd
}
Marcin
quelle
Dies ist bei weitem die einfachste Lösung. Jetzt braucht es nur noch 35 Upvotes. (Übrigens macht die -A nichts für mich.)
Steve Bennett
0
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found

Netcat ist nicht installiert a. Wenn Sie ausführen ssh host "command arg", commandwird auf ausgeführt host, nicht auf Ihrem lokalen Computer.

Markdrayton
quelle
Ja, ich weiß. Dies ist genau das, was ich in einem Kommentar zu Wombles Antwort berichtet habe. :)
Simone Carletti
0

Seit OpenSSH 7.3 (2016-08-01) sind die ProxyJumpOption und das entsprechende -JBefehlszeilenflag verfügbar, um eine einfachere Indirektion durch eine oder mehrere SSH-Bastionen oder "Sprunghosts" zu ermöglichen.

Dadurch wird die Abhängigkeit vom externen ncBefehl, wie sie in der Womble-Lösung zu finden ist, aufgehoben .

ssh -J johndoe@a webby@foo 

abaut als Benutzer johndoe eine SSH-Verbindung von Ihrer Workstation zum Gateway-Server auf und tunnelt die SSH-Sitzung, um foo für den Benutzer Webby darüber zu hosten.

Um dies zu vereinfachen, erstellen Sie Hostdefinitionen für Ihre ~/.ssh/configund die, die Sie einfach ausführen könnenssh foo

Host a
    User johndoe

Host foo
    User Webby 
    ProxyJump a
HBruijn
quelle