Comment obtenir HostName à partir d'un script exécutable dans un fichier de configuration SSH?

10

J'ai souvent besoin de ssh sur un ordinateur arbitraire à partir d'un cluster particulier (toutes les machines du cluster sont identiques). Cependant, l'ensemble des machines disponibles dans le cluster change fréquemment, j'ai donc un script qui renvoie un nom d'hôte arbitraire du cluster qui est disponible et correspond à mes besoins (par exemple, en ligne et exécutant le bon système d'exploitation).

Notez également que j'utilise le transfert d'informations d'identification Kerberos (GSSAPIAuthentication) pour l'authentification.

En ce moment, j'utilise ssh ssh `get_host`. Je voudrais plutôt exécuter ssh cluster. Avec un nom d'hôte connu, c'est facile avec ce qui suit dans /ssh/config:

Host cluster
    HostName static_host.cluster.domain.tld
    GSSAPIAuthentication yes
    GSSAPIDelegateCredentials yes

Comment puis-je sélectionner le HostNamedynamiquement, en utilisant mon script? (Ou SSH a-t-il une méthode différente pour prendre en charge la fonction souhaitée?) Je voudrais faire quelque chose comme ceci, mais cela ne fonctionne pas:

Host cluster
    HostName `get_host`   # This does not work
    ...

Grawity a montré que le ProxyCommandpeut être un script qui obtient le nom d'hôte et transmet la sshconnexion à l'aide de netcatou socat. Cependant, cela ne transfère pas les informations d'identification Kerberos. De l'aide est également appréciée.

ÉDITER:

Vous ne pouvez pas faire cela avec Kerberos comme je le voudrais (voir les commentaires dans la réponse acceptée). Donc, j'utilise ce script, ssh-wrappercomme sshalias pour effectuer une réécriture dynamique sur l' sshargument de ligne de commande. Ce n'est pas robuste, mais ça marche pour moi.

#!/bin/bash

# Mapping between host aliases and dynamically-generated hostname
declare -A MAP
MAP[cluster]=`gethost`

# Find and replace on all positional args
args=$*
for key in ${!MAP[@]}; do
    replace=${MAP[$key]}
    args=`echo ${args} | sed "s/\(^\|[[:space:]]\)${key}\(\$\|[[:space:]]\)/${replace}/"`
done

# Execute using called-name if not this script
if [ "ssh-wrapper" != "`basename $0`" ]; then
    exec $0 ${args}
# Otherwise, assume ssh and execute
else
    exec ssh ${args}
fi
David B.
la source
Question connexe sur la défaillance du serveur .
Michael - Où est Clay Shirky

Réponses:

6

~/.ssh/config:

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect:

#!/bin/bash
socat stdio tcp:$(get_host):22
user1686
la source
Merci. Cela (ou netcat $(get_host) 22) fonctionne très bien pour la connexion. Mais, il ne semble pas transmettre mes informations d'identification Kerberos. J'ai GSSAPIAuthentication yeset GSSAPIDelegateCredentials yessous Host clusterdans mon .ssh/configfichier, et ils fonctionnent si le HostName est donné explicitement, mais pas si je passe par le ProxyCommand. Pensées? Je vais également modifier la question.
David B.
Je ne pense pas que vous puissiez y parvenir - vous sshdevez connaître le nom d'hôte cible pour obtenir le ticket correct, et il n'y a tout simplement aucun moyen de le fournir dynamiquement (à moins d'utiliser un wrapper qui s'exécute simplement ssh $(get_host) "$@", ce que, si j'ai bien compris, vous ne voulez pas ). Cela peut fonctionner si tous les serveurs du cluster ont le même principal Kerberos, mais je ne pense pas que quiconque le fasse.
user1686
Malheureux, mais fait sens. J'ai écrit un wrapper rapide pour faire une recherche / remplacement dynamique (ajouté à la question). Ça va casser dans certains scénarios, mais ça marche pour moi.
David B.
Recherche
Juste une substitution sed sur les arguments de la ligne de commande pour ssh, depuis un mappage host-alise vers host-generation-script stocké dans le script.
David B.