Gere dinamicamente entradas de host SSH em ~ / .ssh / config

9

Eu tenho que administrar uma pilha inteira de hosts sobre ssh. No entanto, só posso acessá-los através de um determinado servidor ssh de gateway.

Eu tenho o seguinte no meu ~/.ssh/config:

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

No entanto, tenho que me conectar a muitas dessas máquinas. Em vez de colocar dezenas de entradas no meu ~/.ssh/config, existe mesmo assim eu posso ter algo como isto:

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

Eu sei que você pode usar %hno Hostnameargumento, mas esse seria o nome do host. O que eu realmente preciso é de algum tipo de substituição de string, como o do bash ${VAR%thingie}. Isso é possível?

Rory
fonte

Respostas:

24

Isso pode ser feito com o seguinte arquivo de configuração 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

Você acessa seus hosts internos da seguinte maneira:

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

O nome escolhido para a metade direita deve ser resolvido pelo host do salto.

O parâmetro User é especificado caso você precise mapear manualmente para diferentes usuários nas diferentes classes de hosts. ControlMaster e ControlPath são especificados para permitir a reutilização da conexão SSH.

Copperlight
fonte
6

Você não precisa especificar manualmente o HostName, pois ele virá da linha de comando.

Simplesmente tente:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Dan Carley
fonte
O problema com essa abordagem é que o nome do host é bastante genérico (por exemplo, db1, www, mail2), enquanto eu quero que eles sejam prefixados com o projeto também, pois talvez eu precise ssh para uma máquina diferente chamada 'db2'. Daí o prefixo no Host
Rory
2
Então você realmente deseja reconfigurar seu DNS. A solução mais simples (mas mais complicada) é modificar o arquivo hosts. Por outro lado, você sempre pode adicionar um servidor DNS local à sua estação de trabalho com um domínio .invalid e usar os nomes de host de sua preferência.
Martin M.
+1 ao anterior. Crie um subdomínio para cada projeto. DNS está lá para facilitar a sua vida;)
Dan Carley
1

Parece que não há como fazer isso.

Rory
fonte
1

Eu tive um problema semelhante e acabei escrevendo um script que gerou todo o padrão para mim. Não altero mais o ~ / ssh / config, altero o ~ / ssh / config.in e executo o meu script.

Michael Hoffman
fonte
1
Gostaria de compartilhar seu script? Pensei em fazer isso, mas parece que uma solução robusta e genérica pode levar muito trabalho para dar certo. Mesmo que sua solução ainda não seja essa, seria útil saber o que você acha que está certo e o que você faria de maneira diferente se a resolvesse.
Iconoclasta
Meu pensamento era ter .ssh/config.dum arquivo para cada modelo, onde cada modelo geraria uma ou mais entradas na final ~/.ssh/config. Também haveria um arquivo com variáveis ​​universais, mas cada modelo poderia ter suas próprias variáveis ​​que teriam precedência sobre as globais, listadas na parte superior. O ~/.ssh/configarquivo pode ser gerado sob demanda ou em uma programação - não importaria - desde que você nunca faça edições diretas nele que deseja preservar.
Iconoclasta
Meu script é totalmente indocumentado e não acho que seria compreensível sem documentação ou exemplos, que não tenho tempo para criar.
Michael Hoffman
Compreensível. Qualquer feedback sobre a abordagem que descrevi seria apreciado, especialmente se eu negligenciar alguma necessidade importante ou caso de uso, ou ainda alguns obstáculos grandes (ou pequenos).
Iconoclasta
1
Eu acho que é uma boa abordagem, provavelmente um pouco menos confusa do que a abordagem que usei. Li várias declarações de host na memória e várias declarações que não são de host. As declarações que não são do host são aplicadas a cada host no grupo atual até que haja outro host. Também permito que os Hosts sejam declarados várias vezes no arquivo, incluindo o uso de globbing. No final, escrevo tudo o que tenho construído na memória.
Michael Hoffman
1

Ignore a especificação de substituir o nome do host diretamente por meio da Hostnamedeclaração e, em vez disso, determine-o em tempo de execução. Faça isso avaliando-o como parte do ProxyCommand, usando %hpara referenciá-lo no comando (também use em %pvez de codificar como 22)

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

Pode-se até ter uma estrofe mais genérica, na qual é possível especificar qualquer host sem -a apenas para ser tratado como está, ou conforme outra estrofe correspondente, mas ter uma -abordagem genérica para especificar qualquer <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

Além disso, as versões mais recentes do cliente SSH oferecem suporte à [-W host:port]opção de executar diretamente a mesma função que nc(netcat). Como tal, podemos usar o 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)

Obviamente, se você tiver uma lista finita de hosts, sempre poderá:

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

Espero que isto ajude!

Taz
fonte
0

Eu tinha um cliente com a mesma configuração e usei o DSSH para resolver meu problema.
O DSSH, entre outras coisas, permite que você efetue login transparente em hosts remotos por meio de um host de gateway.

Casos de uso

  • Colete parâmetros de configuração dos roteadores Cisco que exigem login "ena"
  • Efetue login nos servidores que têm o PermitRootLogin desativado diretamente como raiz (digitando su - e a senha automaticamente), preservando o status de saída
  • Adicione lógica personalizada, como log avançado
  • túnel através de várias conexões para chegar ao servidor de destino
aussielunix
fonte
5
Prefiro não começar a usar algum cliente ssh aleatório de terceiros que usa java, para coisas que eu posso fazer em ~ / .ssh / config.
Rory
o link está morto
iconoclasta
A fonte do software pode ser encontrada no Github: github.com/digmia/dssh
Convidado