J'ai un nombre arbitraire de serveurs avec la même combinaison utilisateur / passe. Je veux écrire un script (que j'appelle une fois) pour que
ssh-copy-id user@myserver
est appelé pour chaque serveur. Comme ils ont tous le même utilisateur / passe, cela devrait être facile, mais ssh-copy-id
je veux que je tape le mot de passe séparément à chaque fois, ce qui va à l'encontre de l'objectif de mon script. Il n'y a pas d'option pour saisir un mot de passe, c'est-à-dire ssh-copy-id -p mypassword user@myserver
.
Comment puis-je écrire un script qui remplit automatiquement le champ du mot de passe lorsque ssh-copy-id
je le demande?
Réponses:
Jetez un oeil à sshpass . Placez votre mot de passe dans un fichier texte et faites quelque chose comme ceci:
la source
Vous pouvez utiliser attendre d'écouter l'invite de mot de passe et envoyer votre mot de passe:
Enregistrez le script, rendez-le exécutable et appelez-le comme:
./login.expect user@myserver
la source
spawn
? Pour des raisons que je ne peux pas contrôler, je suis bloqué avec bash v3.2.spawn: command not found
spawn
est un mot clé expect (voir le manuel expect (1)). On dirait que le script est interprété comme un shell plutôt que comme prévu. Avez-vous prévu d'installer? Que se passe-t-il si vous exécutez attendez directement:expect -f login.expect user@myserver
spawn ssh-copy-id -o StrictHostKeyChecking=no $argv
La réponse de quanta est assez bonne, mais elle vous oblige à mettre votre mot de passe dans un fichier texte.
Depuis la page de manuel "sshpass":
Donc, ce que vous pouvez faire est de capturer le mot de passe une fois pendant le script, de le stocker dans une variable, de faire écho au mot de passe et de le diriger vers sshpass en entrée.
Je fais ça tout le temps et ça marche bien. Exemple:
echo "Please insert the password used for ssh login on remote machine:" read -r USERPASS for TARGETIP in $@; do echo "$USERPASS" | sshpass ssh-copy-id -f -i $KEYLOCATION "$USER"@"$TARGETIP" done
la source
Il s'agit d'un problème avec ssh-copy-id; il ajoute également une clé chaque fois que vous l'exécutez. Si vous automatisez le processus, votre fichier authorized_keys est rapidement encombré de clés en double. Voici un programme Python qui évite les deux problèmes. Il s'exécute à partir du serveur de contrôle et place les clés d'un serveur distant dans un autre serveur distant.
la source
Plutôt que de taper votre mot de passe plusieurs fois, vous pouvez utiliser
pssh
et son-A
commutateur pour le demander une fois, puis envoyer le mot de passe à tous les serveurs d'une liste.REMARQUE: l' utilisation de cette méthode ne vous permet pas d'utiliser
ssh-copy-id
, cependant, vous devrez donc rouler votre propre méthode pour ajouter votre fichier de clé de publication SSH au fichier de votre compte distant~/.ssh/authorized_keys
.Exemple
Voici un exemple qui fait le travail:
Le script ci-dessus est généralement structuré comme suit:
pssh
Détails de haut niveaucat <pubkey>
sort le fichier de clé publique verspssh
pssh
utilise le-I
commutateur pour ingérer des données via STDIN-l <remote user>
est le compte du serveur distant (nous supposons que vous avez le même nom d'utilisateur sur les serveurs dans le fichier IP)-A
indiquepssh
de demander votre mot de passe, puis de le réutiliser pour tous les serveurs auxquels il se connecte-i
indiquepssh
d'envoyer n'importe quelle sortie à STDOUT plutôt que de la stocker dans des fichiers (son comportement par défaut)'...cmds to add pubkey...'
- c'est la partie la plus délicate de ce qui se passe, donc je vais le décomposer par lui-même (voir ci-dessous)Commandes exécutées sur des serveurs distants
Ce sont les commandes qui
En ordre:pssh
s'exécuteront sur chaque serveur:définissez umask de l'utilisateur distant sur 077, afin que tous les répertoires ou fichiers que nous allons créer, leurs autorisations soient définies en conséquence, comme suit:
créer le répertoire
~/.ssh
et ignorer nous avertir s'il est déjà là$afile
avec le chemin d'accès au fichier authorized_keyscat - >> $afile
- prendre l'entrée de STDIN et l'ajouter au fichier authorized_keyssort -u $afile -o $afile
- trie de façon unique le fichier authorized_keys et l'enregistreRemarque: ce dernier bit est de gérer le cas où vous exécutez plusieurs fois ci-dessus sur les mêmes serveurs. Cela évitera que votre clé pub ne soit ajoutée plusieurs fois.
Remarquez les tiques simples!
Portez également une attention particulière au fait que toutes ces commandes sont imbriquées à l'intérieur de guillemets simples. C'est important, car nous ne voulons
$afile
être évalués qu'après son exécution sur le serveur distant.J'ai développé ce qui précède, il est donc plus facile à lire ici, mais je lance généralement le tout sur une seule ligne comme ceci:
Matériel bonus
En utilisant ,
pssh
vous pouvez renoncer à avoir à construire des fichiers et soit fournir un contenu dynamique à l' aide-h <(...some command...)
ou vous pouvez créer une liste d'adresses IP en utilisant un autre despssh
commutateurs de »,-H "ip1 ip2 ip3"
.Par exemple:
Ce qui précède pourrait être utilisé pour extraire une liste d'adresses IP de mon
~/.ssh/config
fichier. Bien sûr, vous pouvez également utiliserprintf
pour générer du contenu dynamique:Par exemple:
Vous pouvez également utiliser
seq
pour générer des séquences de nombres formatés aussi!Références et outils similaires à
pssh
Si vous ne souhaitez pas l'utiliser
pssh
comme je l'ai fait ci-dessus, d'autres options sont disponibles.la source
Ansible's authorized_key_module
ne semble pas fonctionner pour une nouvelle machine. Je dois d'abord ssh-copy-id xxx, donc je cherche un moyen d'utiliser simplement ansible add ssh-key pour une nouvelle machine, une idée?L'un des outils SSH parallèles (clusterssh, mssh, pssh) peut vous convenir.
Par exemple, utilisez cssh pour vous connecter à toutes les machines et ajoutez la clé vous-même.
la source
Quelques choses qui pourraient convenir:
Comme mentionné dans d'autres réponses, sshpass est probablement la solution la plus simple.
la source
Je veux souligner à quel point une idée est mauvaise pour:
Voici une implémentation un peu plus sécurisée ...
la source