Generieren Sie dynamisch SSH-Host-Einträge in ~ / .ssh / config

9

Ich muss einen ganzen Haufen Hosts über ssh verwalten. Ich kann jedoch nur über einen bestimmten Gateway-SSH-Server darauf zugreifen.

Ich habe folgendes in meinem ~/.ssh/config:

Host mygateway-www
Hostname www
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Ich muss mich jedoch mit vielen dieser Maschinen verbinden. Anstatt Dutzende von Einträgen in meine ~/.ssh/configzu schreiben, kann ich sowieso so etwas haben:

Host mygateway-*
Hostname ???WHAT GOES HERE????
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Ich weiß, dass Sie %hin dem HostnameArgument verwenden können, aber das wäre der Hostname. Was ich wirklich brauche, ist eine Art String-Substitution, wie Bash's ${VAR%thingie}. Ist das möglich?

Rory
quelle

Antworten:

23

Dies kann mit der folgenden SSH-Konfigurationsdatei erfolgen:

Host *
  ServerAliveInterval 120

Host gateway.somewhere.com
  User jdoe

Host gateway+*
  User jdoe
  ProxyCommand ssh -T -a $(echo %h |cut -d+ -f1).somewhere.com nc $(echo %h |cut -d+ -f2) %p 2>/dev/null
  ControlMaster auto
  ControlPath ~/.ssh/ssh-control_%r@%h:%p

Sie greifen dann wie folgt auf Ihre internen Hosts zu:

ssh gateway+internalhost01.somewhere.com
ssh gateway+internalhost02.somewhere.com

Der Name, den Sie für die rechte Hälfte wählen, sollte vom Sprunghost aufgelöst werden können.

Der Benutzerparameter wird angegeben, wenn Sie verschiedenen Benutzern auf den verschiedenen Hostklassen manuell zuordnen müssen. ControlMaster und ControlPath werden angegeben, um die Wiederverwendung der SSH-Verbindung zu ermöglichen.

Kupferlicht
quelle
6

Sie sollten HostName nicht manuell angeben müssen, da er über die Befehlszeile erfolgt.

Versuchen Sie einfach:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Dan Carley
quelle
Das Problem bei diesem Ansatz ist, dass der Hostname ziemlich allgemein ist (z. B. db1, www, mail2), während ich möchte, dass ihnen auch das Projekt vorangestellt wird, da ich möglicherweise auf einem anderen Computer namens 'db2' ssh muss. Daher das Präfix in Host
Rory
2
Sie möchten also Ihr DNS tatsächlich neu konfigurieren. Die einfachste (aber umständlichste) Lösung besteht darin, die Hosts-Datei zu ändern. Andererseits können Sie Ihrer Workstation jederzeit einen lokalen DNS-Server mit einer ungültigen Domäne hinzufügen und die von Ihnen bevorzugten Hostnamen verwenden.
Martin M.
+1 der vorherige. Erstellen Sie für jedes Projekt eine Subdomain. DNS ist da, um Ihnen das Leben zu erleichtern;)
Dan Carley
1

Es sieht so aus, als gäbe es keine Möglichkeit, dies zu tun.

Rory
quelle
1

Ich hatte ein ähnliches Problem und schrieb schließlich ein Skript, das die gesamte Boilerplate für mich generierte. Ich ändere ~ / ssh / config nicht mehr, ich ändere ~ / ssh / config.in und führe mein Skript erneut aus.

Michael Hoffman
quelle
1
Möchten Sie Ihr Skript teilen? Ich habe darüber nachgedacht, aber es scheint, dass eine robuste und generische Lösung viel Arbeit erfordert, um sie richtig zu machen. Selbst wenn Ihre Lösung noch nicht so ist, wäre es hilfreich zu wissen, was Ihrer Meinung nach richtig ist und was Sie anders machen würden, wenn Sie es noch einmal machen würden.
Bilderstürmer
Mein Gedanke war, .ssh/config.dfür jede Vorlage eine Datei zu haben, in der jede Vorlage im Finale einen oder mehrere Einträge generiert ~/.ssh/config. Es würde auch eine Datei mit universellen Variablen geben, aber jede Vorlage könnte ihre eigenen Variablen haben, die Vorrang vor den oben aufgeführten globalen Variablen haben. Die ~/.ssh/configDatei kann bei Bedarf oder nach einem Zeitplan erstellt werden - das spielt keine Rolle -, solange Sie keine direkten Änderungen daran vorgenommen haben, die Sie beibehalten möchten.
Bilderstürmer
Mein Skript ist völlig undokumentiert und ich denke nicht, dass es ohne Dokumentation oder Beispiele, für deren Erstellung ich keine Zeit habe, verständlich wäre.
Michael Hoffman
Verständlich. Jedes Feedback zu dem von mir skizzierten Ansatz wäre willkommen, insbesondere wenn ich entweder einen wichtigen Bedarf oder Anwendungsfall oder einige große (oder kleine) Hindernisse übersehen würde.
Bilderstürmer
1
Ich denke, das ist ein guter Ansatz, wahrscheinlich etwas weniger verwirrend als der Ansatz, den ich verwendet habe. Ich habe eine Reihe von Host-Deklarationen in den Speicher eingelesen, dann eine Reihe von Nicht-Host-Deklarationen. Die Nicht-Host-Deklarationen werden auf jeden Host in der aktuellen Gruppe angewendet, bis ein anderer Host vorhanden ist. Ich erlaube auch, dass Hosts mehrmals in der Datei deklariert werden, einschließlich Globbing. Am Ende schreibe ich alles auf, was ich in Erinnerung behalten habe.
Michael Hoffman
1

Ignorieren Sie die Angabe, den Hostnamen direkt über die HostnameDeklaration zu überschreiben, und bestimmen Sie ihn stattdessen zur Laufzeit. Dies geschieht, indem es als Teil der Auswertung ProxyCommand, indem %hes in dem Befehl referenzieren (auch verwendet %panstelle von hartzucodieren Port als 22) , dh

Host mygateway-*
   #Hostname ???WHAT GOES HERE????
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc $(echo %h|sed 's/^mygateway-//') %p

Man könnte sogar eine allgemeinere Zeilengruppe haben, wobei Sie jeden Host angeben können, ohne eine -so zu behandeln, wie sie ist, oder gemäß einer anderen übereinstimmenden Zeilengruppe, aber einen generischen -Ansatz, um eine beliebige anzugeben <gateway>-<target>:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh $(echo %h|cut -d - -f1) nc $(echo %h|cut -d - -f2-) %p

Darüber hinaus unterstützen neuere Versionen des SSH-Clients die [-W host:port]Option, dieselbe Funktion wie nc(netcat) direkt auszuführen . Als solches können wir das modifizierte verwenden:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh -W $(echo %h|cut -d - -f2-):%p $(echo %h|cut -d - -f1)

Wenn Sie eine endliche Liste von Hosts hätten, könnten Sie natürlich immer Folgendes tun:

Host host1 host2 host3 hostN
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc %h %p

Hoffe das hilft!

Taz
quelle
0

Ich hatte einen Client mit dem gleichen Setup und habe DSSH verwendet , um mein Problem zu lösen.
Mit DSSH können Sie sich unter anderem über einen Gateway-Host transparent bei Remote-Hosts anmelden.

Anwendungsfälle

  • Sammeln Sie Konfigurationsparameter von Cisco-Routern, für die eine "ena" -Anmeldung erforderlich ist
  • Melden Sie sich bei Servern an, bei denen PermitRootLogin direkt als root deaktiviert ist (indem Sie su - und password automatisch eingeben), während Sie den Exit-Status beibehalten
  • Fügen Sie benutzerdefinierte Logik hinzu, z. B. erweiterte Protokollierung
  • Tunneln Sie durch mehrere Verbindungen, um zum Zielserver zu gelangen
aussielunix
quelle
5
Ich möchte lieber keinen zufälligen SSH-Client eines Drittanbieters verwenden, der Java verwendet, für Dinge, die ich in ~ / .ssh / config tun kann.
Rory
Der Link ist tot
Bilderstürmer
Die Softwarequelle finden Sie auf Github: github.com/digmia/dssh
Gast