Bedingter Proxy-Befehl in ~ / .ssh / config?

14

Ich habe meine ~/.ssh/configmit verschiedenen Hosts konfiguriert, auf die entweder über unser Firmen-VPN oder über einen SSH-Proxyserver zugegriffen werden kann.

Im Moment habe ich nur

Host internal-server
    ProxyCommand ssh -W internal.ip:22 external-server

Wenn ich mich jedoch im internen Netzwerk befinde, kann ich direkt auf die interne IP-Adresse zugreifen. Durch das Proxying über den externen Server wird die Verbindungsherstellung lediglich verzögert.

Gibt es eine Möglichkeit, einen vorläufigen Proxy für den Fall, dass die interne IP nicht erreichbar ist, und eine direkte Verbindung herzustellen, wenn dies nicht der Fall ist?

alt
quelle

Antworten:

8

Normalerweise richte ich so etwas ein. Es wird davon ausgegangen, dass der zwischengeschaltete Host den Namen auflösen kann.

Host *%homeproxy
    ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22

Also würde ich mich gerne verbinden ssh blah%homeproxy.

Zoredache
quelle
Mein google-fu versagt mir. Können Sie das näher erläutern? Ich habe diese *% -Syntax noch nie gesehen.
Fukawi2
3
Der %Charakter hat nichts Besonderes . Man könnte wirklich alles gebrauchen. Der Prozentwert wird verwendet, da er in einem Hostnamen oder Benutzernamen nicht gültig ist. Der cutBefehl mit dem ProxyCommand verwendet den %als Begrenzer, um den Hostnamen abzurufen .
Zoredache
1
Das ist gut, aber es bedeutet, dass ich den vollständigen Hostnamen und nicht den ssh-Alias ​​buchstabieren muss.
Alt
@mobiusnz Es bedeutet eigentlich nur , dass Sie für jede andere einen anderen Namen müssen mittels verbinden. In meinem Fall, zum Beispiel, wenn ich zu Hause bin, benutze ich ssh targetH, was Ziel von zu Hause bedeutet . Wenn in einem lokalen Netzwerk zu zielen, einfach ssh target. Es wäre schön gewesen, wenn dies in der Antwort klarer formuliert worden wäre.
Rubens
4

Ich benutze eine andere Methode mit Match. In meinem Fall möchte ich einen lokalen Proxy verwenden, wenn dieser ausgeführt wird oder nicht. Die folgende Direktive erfüllt dies in netter Weise:

Match Exec "nc -z 127.0.0.1 1086"
    ProxyCommand nc -X 5 -x 127.0.0.1:1086 %h %p

Es stimmt mit jedem SSH-Versuch überein und führt eine schnelle Überprüfung durch, ncum festzustellen, ob mein Proxy unter 1086 aktiv ist (in diesem Fall wird es ncohne Fehler beendet). In diesem Fall wird der ProxyCommand festgelegt.

domoarigato
quelle
2

Vor einem Jahrzehnt habe ich einen Proxy-Befehl für diese Art von Szenario geschrieben. In Ihrem Anwendungsfall könnte mein Proxy-Befehl folgendermaßen lauten:

Host internal-server
    ProxyCommand ssh-multipath-proxy %h:%p -- ssh -W %h:%p external-server

Ein paar Vorbehalte: Es ist mir etwas peinlich zuzugeben, dass IPv6 nicht unterstützt wird und dass nur eine einzige IP-Adresse pro Hostname verwendet wird. Außerdem wird das Client-Banner erst dann auf den Server übertragen, wenn das Server-Banner gesendet wurde. Aber es ist unwahrscheinlich, dass dies zu Problemen führt.

Kasperd
quelle
2

Vielen Dank für @ till's Answer , es hat mich sehr inspiriert.

Ich habe festgestellt, dass Sie Ihre Verbindung zwangsweise umleiten können ProxyCommand nc dst dst-port.

Beispielsweise stellen Sie tatsächlich eine Verbindung her, B.comwenn Sie verwenden

ssh A.com -o ProxyCommand="nc B.com 22"

Werde UserKnownHostsFileaber trotzdem aufnehmen wieA.com

So können Sie Ihrer Domain "auto" hinzufügen ssh_config

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(timeout 0.1 nc -z %h %p) && nc %h %p || ssh -W %h:%p external-server'

Ich ersetzte nc -w 1 %h %pmit (timeout 0.1 nc -z %h %p) && nc %h %p, es ist schneller, wenn Sie den internen Server weniger als 100ms erreichen könnten.

Sie können auch durch ersetzt werden ping, dies kann jedoch auf fehlerhafte Informationen hinweisen, wenn Sie einen TCP-basierten Proxy verwenden proxychainsoder der Server kein ICMP-Echo zulässt.

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(ping %h &>/dev/null) && nc %h %p || ssh -W %h:%p external-server'

Sie können durch (timeout 0.1 nc -z %h %p)alles ersetzen , was erkennt, ob Sie sich auf einem internen Server befinden.

Wenn Sie mehrere Kandidaten-IPs haben, können Sie dies auch verwenden:

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c 'f(){(timeout 0.1 ping -c 1 $1 &>/dev/null) && nc $1 %p;}; f 1.1.1.1 || f 2.2.2.2 || f 3.3.3.3'

Es wird versucht, eine Verbindung herzustellen 1.1.1.1, wenn dies fehlschlägt, versuchen Sie, eine Verbindung herzustellen 2.2.2.2, und dann 3.3.3.3.

Komeiji Kuroko
quelle
0

Dies funktioniert etwas automatischer mit einer geringfügigen zusätzlichen Verzögerung von 1 Sekunde, wenn Sie sich nicht hinter der Firewall befinden und die Firewall Folgendes nicht ablehnt:

Host proxyhost.example.com
ProxyCommand none

Host *.example.com
ProxyCommand sh -c "nc -w 1 %h %p || ssh -W  %h:%p proxyhost.example.com"
bis
quelle
0

Normalerweise würde ich einen anderen Eintrag wie diesen erstellen.

Host myVM
    ProxyCommand ssh -W internal.ip:22 external-server
    User ubuntu

Host myVM-np
    User ubuntu

Rufen Sie dann einfach die gewünschte auf, abhängig von Ihrer aktuellen Proxy-Umgebung.

Sharath Srinivasan
quelle