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/pass, cela devrait être facile mais ssh-copy-id
veut 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
le demande?
Jetez un œil à sshpass . Placez votre mot de passe dans un fichier texte et faites quelque chose comme ceci:
$ sshpass -f password.txt ssh-copy-id user@yourserver
Vous pouvez utiliser attendre d'écouter l'invite de mot de passe et envoyer votre mot de passe:
#!/usr/bin/expect -f
spawn ssh-copy-id $argv
expect "password:"
send "YOUR_PASSWORD\n"
expect eof
Enregistrez le script, rendez-le exécutable et appelez-le comme: ./login.expect user@myserver
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":
Si aucune option n'est donnée, sshpass lit le mot de passe à partir de l'entrée standard.
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
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.
import subprocess
def Remote(cmd,IP):
cmd = '''ssh root@%s '''%(IP)+cmd
lines = subprocess.check_output(cmd.split())
return '\n'.join(lines)
source = '123.456.78.90'
target = '239.234.654.123'
getkey = 'cat /root/.ssh/id_rsa.pub'
getauth = 'cat /root/.ssh/authorized_keys'
sourcekey = Remote(getkey, source).replace('\n','').strip()
authkeys = Remote(getauth, target).replace('\n','').strip()
if sourcekey not in authkeys:
keycmd=''' echo "%s" >>/root/.ssh/authorized_keys;
chmod 600 /root/.ssh/authorized_keys '''%(sourcekey) # A compound Shell statement
print 'Installed key', Remote(keycmd,target)
else: print 'Does not need key'
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.
Je veux souligner à quel point une idée est mauvaise pour:
Voici une implémentation un peu plus sécurisée ...
#!/usr/bin/python3
import os
import getpass
import argparse
parser = argparse.argument_parser()
parser.add_argument('-l','--login', action='store', help='username')
parser.add_argument('-p','--port', action='store', default='22', help='port')
parser.add_argument('-L','--list', action='store', help='file list of IPs')
parser.add_argument('-i','--ip-address', action='store', nargs='+', metavar='Host' help='ip or list of ips')
args = parser.parse_args()
if not args.login:
print("You need a login, broski!")
return 0
if args.list:
ips = [i for i in open(args.list, 'r').readlines()]
passwd = getpass.getpass('Password: ')
for ip in ips:
cmd = 'ssh-id-copy {0}@{1} -p {2}'.format(ip,args.port,passwd)
os.system('sshpass -p ' + passwd + ' ' + cmd)
print("Key added: ", ip) # prints if successful
# ex: sshpass -p passwd ssh-id-copy [email protected]
Elif args.Host:
ip = args.Host
cmd = 'ssh-id-copy {0}@{1} -p {2}'.format(ip,args.port,passwd)
os.system('sshpass -p ' + passwd + ' ' + cmd)
print("Key added: ", ip) # prints if successful
else:
print("No IP addresses were given to run script...")
return 0
Quelques choses qui pourraient convenir:
Comme mentionné dans d'autres réponses, sshpass est probablement la solution la plus simple.