Générez dynamiquement des entrées d'hôte SSH dans ~ / .ssh / config

9

Je dois administrer toute une pile d'hôtes sur ssh. Cependant, je ne peux y accéder que via un certain serveur ssh de passerelle.

J'ai les éléments suivants dans mon ~/.ssh/config:

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

Cependant, je dois me connecter à beaucoup de ces machines. Au lieu de mettre des dizaines d'entrées dans mon ~/.ssh/config, est-ce que je peux de toute façon avoir quelque chose comme ça:

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

Je sais que vous pouvez utiliser %hdans l' Hostnameargument, mais ce serait le nom d'hôte. Ce dont j'ai vraiment besoin, c'est d'une sorte de substitution de chaîne, comme celle de bash ${VAR%thingie}. Est-ce possible?

Rory
la source

Réponses:

24

Cela peut être fait avec le fichier de configuration SSH suivant:

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

Vous accédez ensuite à vos hôtes internes comme suit:

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

Le nom que vous choisissez pour la moitié droite doit être résolu par l'hôte de saut.

Le paramètre User est spécifié au cas où vous auriez besoin de mapper manuellement vers différents utilisateurs sur les différentes classes d'hôtes. ControlMaster et ControlPath sont spécifiés pour permettre la réutilisation de la connexion SSH.

cuivré
la source
6

Vous ne devriez pas avoir besoin de spécifier manuellement HostName car il proviendra de la ligne de commande.

Essayez simplement:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Dan Carley
la source
Le problème avec cette approche est que le nom d'hôte est assez générique (par exemple db1, www, mail2), alors que je veux qu'ils soient préfixés avec le projet, car je peux avoir besoin de ssh vers une autre machine appelée 'db2'. D'où le préfixe dans Host
Rory
2
Vous voulez donc réellement reconfigurer votre DNS. La solution la plus simple (mais la plus lourde) est de modifier votre fichier hosts. Vous pouvez en revanche toujours ajouter un serveur DNS local à votre poste de travail avec un domaine .invalid et utiliser les noms d'hôte que vous préférez.
Martin M.
+1 au précédent. Créez un sous-domaine pour chaque projet. Le DNS est là pour vous faciliter la vie;)
Dan Carley
1

Il semble qu'il n'y ait aucun moyen de le faire.

Rory
la source
1

J'ai eu un problème similaire et j'ai fini par écrire un script qui a généré tout le passe-partout pour moi. Je ne change plus ~ / ssh / config, je change ~ / ssh / config.in et relance mon script.

Michael Hoffman
la source
1
Envie de partager votre script? J'ai pensé à le faire, mais il semble qu'une solution robuste et générique pourrait demander beaucoup de travail pour bien se mettre en place. Même si votre solution n'est pas encore celle-là, il serait utile de savoir ce que vous pensez être juste et ce que vous feriez différemment si vous deviez le refaire.
iconoclaste du
Ma pensée était d'avoir .ssh/config.dun fichier pour chaque modèle, où chaque modèle générerait une ou plusieurs entrées dans la finale ~/.ssh/config. Il y aurait également un fichier avec des variables universelles, mais chaque modèle pourrait avoir ses propres variables qui auraient priorité sur les globales, répertoriées en haut. Le ~/.ssh/configfichier peut être généré à la demande ou selon un calendrier - cela n'a pas d'importance - tant que vous ne lui apportez jamais de modifications directes que vous souhaitez conserver.
iconoclaste du
Mon script est totalement non documenté et je ne pense pas qu'il serait compréhensible sans documentation ni exemples, que je n'ai pas le temps de créer.
Michael Hoffman
Compréhensible. Tout commentaire sur l'approche que j'ai décrite serait apprécié, surtout si je néglige un besoin ou un cas d'utilisation important, ou bien de gros (ou petits) obstacles.
iconoclaste du
1
Je pense que c'est une bonne approche, probablement un peu moins confuse que l'approche que j'ai utilisée. J'ai lu un certain nombre de déclarations d'hôte en mémoire, puis un certain nombre de déclarations de non-hôte. Les déclarations de non-hôte sont appliquées à chaque hôte du groupe actuel jusqu'à ce qu'il y ait un autre hôte. J'autorise également les hôtes à être déclarés plusieurs fois dans le fichier, y compris en utilisant la globalisation. À la fin, j'écris tout ce que j'ai construit en mémoire.
Michael Hoffman
1

Ignorez la spécification de la substitution du nom d'hôte directement via la Hostnamedéclaration et déterminez-le à la place lors de l'exécution. Pour ce faire, évaluez-le dans le cadre de ProxyCommand, utilisez %hpour le référencer dans la commande (utilisez également %pau lieu du port de codage en dur comme 22), c'est-à-dire

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

On pourrait même avoir une strophe plus générique, par laquelle vous pouvez spécifier n'importe quel hôte sans -juste être traité tel quel , ou selon une autre strophe correspondante, mais avoir une -approche générique pour spécifier n'importe quelle <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

De plus, les versions plus récentes du client SSH prennent en charge l' [-W host:port]option permettant d'exécuter directement la même fonction que nc(netcat). En tant que tel, nous pouvons utiliser le modifié:

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)

Bien sûr, si vous aviez une liste finie d'hôtes, vous pourriez toujours faire:

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

J'espère que cela t'aides!

Taz
la source
0

J'avais un client avec la même configuration et j'ai utilisé DSSH pour résoudre mon problème.
DSSH vous permet entre autres de vous connecter de manière transparente à des hôtes distants via un hôte de passerelle.

Cas d'utilisation

  • Collectez les paramètres de configuration des routeurs Cisco qui nécessitent une connexion "ena"
  • Connectez-vous aux serveurs sur lesquels PermitRootLogin est désactivé directement en tant que root (en tapant su - et mot de passe automatiquement), tout en préservant l'état de sortie
  • Ajouter une logique personnalisée telle que la journalisation avancée
  • tunnel via plusieurs connexions pour arriver au serveur cible
aussielunix
la source
5
Je préfère ne pas commencer à utiliser un client ssh tiers aléatoire qui utilise java, pour des choses que je peux faire dans ~ / .ssh / config.
Rory
le lien est mort
iconoclaste
La source du logiciel peut être trouvée sur Github: github.com/digmia/dssh
Guest