Genere dinámicamente entradas de host SSH en ~ / .ssh / config

9

Tengo que administrar un montón de hosts a través de ssh. Sin embargo, solo puedo acceder a ellos a través de un determinado servidor ssh de puerta de enlace.

Tengo lo siguiente en mi ~/.ssh/config:

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

Sin embargo, tengo que conectarme a muchas de estas máquinas. En lugar de poner docenas de entradas en mi ~/.ssh/config, ¿hay alguna forma de que pueda tener algo como esto:

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

Sé que puedes usarlo %hen el Hostnameargumento, pero ese sería el nombre de host. Lo que realmente necesito es algún tipo de sustitución de cadena, como bash ${VAR%thingie}. es posible?

Rory
fuente

Respuestas:

24

Esto se puede hacer con el siguiente archivo de configuración SSH:

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

Luego accede a sus hosts internos de esta manera:

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

El nombre que elija para la mitad derecha debe ser resuelto por el host de salto.

El parámetro Usuario se especifica en caso de que necesite asignar manualmente a diferentes usuarios en las diferentes clases de hosts. ControlMaster y ControlPath se especifican para permitir la reutilización de la conexión SSH.

Copperlight
fuente
6

No debería necesitar especificar manualmente HostName ya que vendrá de la línea de comando.

Simplemente intente:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Dan Carley
fuente
El problema con ese enfoque es que el nombre de host es bastante genérico (por ejemplo, db1, www, mail2), mientras que también quiero que tengan el prefijo del proyecto, ya que es posible que necesite ssh a una máquina diferente llamada 'db2'. De ahí el prefijo en Host
Rory
2
Entonces, en realidad desea reconfigurar su DNS. La solución más simple (pero más engorrosa) es modificar su archivo de hosts. Por otro lado, siempre puede agregar un servidor DNS local a su estación de trabajo con un dominio inválido y usar los nombres de host que prefiera.
Martin M.
+1 el anterior. Crea un subdominio para cada proyecto. DNS está ahí para hacerte la vida más fácil;)
Dan Carley
1

Parece que no hay forma de hacer esto.

Rory
fuente
1

Tuve un problema similar y terminé escribiendo un script que generó toda la plantilla para mí. Ya no cambio ~ / ssh / config, cambio ~ / ssh / config.in y vuelvo a ejecutar mi script.

Michael Hoffman
fuente
1
¿Quieres compartir tu guión? He pensado en hacer esto, pero parece que una solución robusta y genérica podría requerir mucho trabajo para hacerlo bien. Incluso si su solución aún no es eso, sería útil saber qué cree que es correcto y qué haría de manera diferente si tuviera que hacerlo de nuevo.
iconoclasta
Mi idea era tener .ssh/config.dun archivo para cada plantilla, donde cada plantilla generaría una o más entradas en la final ~/.ssh/config. También habría un archivo con variables universales, pero cada plantilla podría tener sus propias variables que tendrían prioridad sobre los globales, enumerados en la parte superior. El ~/.ssh/configarchivo podría generarse a pedido o en un horario, no importaría, siempre y cuando nunca haya realizado modificaciones directas que desea conservar.
iconoclasta
Mi script está totalmente indocumentado y no creo que sea comprensible sin documentación o ejemplos, que no tengo tiempo para crear.
Michael Hoffman
Comprensible. Cualquier comentario sobre el enfoque que describí sería apreciado, especialmente si estoy pasando por alto alguna necesidad importante o un caso de uso, o bien algunos obstáculos grandes (o pequeños).
iconoclasta
1
Creo que es un buen enfoque, probablemente un poco menos confuso que el enfoque que utilicé. Leí una cantidad de declaraciones de Host en la memoria, luego una cantidad de declaraciones de no host. Las declaraciones de no host se aplican a cada host en el grupo actual hasta que haya otro host. También permito que los hosts se declaren varias veces en el archivo, incluido el uso de globbing. Al final escribo todo lo que he estado construyendo en la memoria.
Michael Hoffman
1

Ignorar la especificación que anula el nombre de host directamente a través de la Hostnamedeclaración y, en su lugar, determinarlo en tiempo de ejecución. Para hacerlo, evalúelo como parte del ProxyCommand, usando %hpara referenciarlo en el comando (también use en %plugar del puerto de codificación como 22), es decir

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

Incluso se podría tener una estrofa más genérica, mediante la cual puede especificar cualquier host sin un -solo ser tratado como es, o según otras estrofas coincidentes, pero tener un -enfoque genérico para especificar cualquiera <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

Además, las versiones más nuevas del cliente SSH admiten la [-W host:port]opción de realizar directamente la misma función que nc(netcat). Como tal, podemos usar el modificado:

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)

Por supuesto, si tuviera una lista finita de hosts, siempre podría hacer:

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

¡Espero que esto ayude!

Taz
fuente
0

Tenía un cliente con la misma configuración y usé DSSH para resolver mi problema.
DSSH, entre otras cosas, le permite iniciar sesión de forma transparente en hosts remotos a través de un host de puerta de enlace.

Casos de uso

  • Recopile los parámetros de configuración de los enrutadores Cisco que requieren inicio de sesión "ena"
  • Inicie sesión en los servidores, que tienen PermitRootLogin deshabilitado directamente como root (escribiendo su - y contraseña automáticamente), mientras conserva el estado de salida
  • Agregue lógica personalizada como registro avanzado
  • túnel a través de varias conexiones para llegar al servidor de destino
aussielunix
fuente
55
Prefiero no comenzar a usar algún cliente ssh aleatorio de terceros que use Java, para cosas que puedo hacer en ~ / .ssh / config.
Rory
el enlace está muerto
iconoclasta
La fuente del software se puede encontrar en Github: github.com/digmia/dssh
Invitado