J'ai besoin de créer un script qui entre automatiquement un mot de passe dans le client OpenSSH ssh
.
Disons que j'ai besoin de SSH dans myname@somehost
avec le mot de passe a1234b
.
J'ai déjà essayé ...
#~/bin/myssh.sh
ssh myname@somehost
a1234b
... mais ça ne marche pas.
Comment puis-je intégrer cette fonctionnalité dans un script?
Vous devez d’abord installer sshpass .
apt-get install sshpass
yum install sshpass
pacman -S sshpass
Exemple:
sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM
Exemple de port personnalisé:
sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400
Notes:
sshpass
peut également lire un mot de passe à partir d'un fichier lorsque l'indicateur -f
est passé. -f
empêche que le mot de passe soit visible si la commande ps
est exécutée.Après avoir cherché une réponse à la question pendant des mois, j'ai finalement trouvé une meilleure solution: écrire un script simple.
#!/usr/bin/expect
set timeout 20
set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
eval spawn $cmd
expect "assword:"
send "$password\r";
interact
Mettez-le dans /usr/bin/exp
, vous pouvez alors utiliser:
exp <password> ssh <anything>
exp <password> scp <anysrc> <anydst>
Terminé!
Utilisez l'authentification par clé publique: https://help.ubuntu.com/community/SSH/OpenSSH/Keys
Dans l'hôte source, exécutez cette opération une seule fois:
ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost
C'est tout, après cela, vous pourrez faire ssh sans mot de passe.
Vous pouvez utiliser un script attend. Je n'en ai pas écrit depuis un certain temps, mais cela devrait ressembler à ce qui suit. Vous devrez diriger le script avec #!/usr/bin/expect
#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:"
send "username\r"
expect "Password:"
send "password\r"
interact
Variante I
sshpass -p PASSWORD ssh USER@SERVER
Variante II
#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact
sshpass
avec une meilleure sécuritéJe suis tombé sur ce fil en cherchant un moyen de faire passer SSH sur un serveur embourbé. Il a fallu plus d’une minute pour traiter la tentative de connexion SSH et le délai a expiré avant que je puisse entrer un mot de passe. Dans ce cas, je voulais pouvoir fournir mon mot de passe immédiatement lorsque l'invite était disponible.
(Et si ce n'est pas très clair: avec un serveur dans cet état, il est beaucoup trop tard pour configurer une connexion par clé publique.)
sshpass
à la rescousse. Cependant, il existe de meilleures façons de procéder que sshpass -p
.
Mon implémentation passe directement à l'invite de mot de passe interactif (vous ne perdez pas de temps à voir si un échange de clé publique peut avoir lieu) et ne révèle jamais le mot de passe sous forme de texte brut.
#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"
# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS
export SSHPASS
# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"
# clear the exported variable containing the password
unset SSHPASS
Un bon bonus du sshpass
déjà mentionné est que vous pouvez l'utiliser avec autossh
, ce qui élimine encore plus l'inefficacité interactive.
sshpass -p mypassword autossh -M0 -t [email protected]
Cela permettra la reconnexion automatique si, par exemple, votre wifi est interrompu par la fermeture de votre ordinateur portable.
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1
# sets some vars for ssh to play Nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh [email protected] -p 22
Je ne pense pas avoir vu quelqu'un suggérer cela et l'OP vient de dire "script" alors ...
J'avais besoin de résoudre le même problème et mon langage le plus confortable est Python.
J'ai utilisé la bibliothèque paramiko. En outre, je devais également émettre des commandes pour lesquelles il me faudrait des autorisations escaladées à l'aide de Sudo
. Il s'avère que Sudo peut accepter son mot de passe via stdin via l'indicateur "-S"! Voir ci-dessous:
import paramiko
ssh_client = paramiko.SSHClient()
# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)
# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"
ssh_client.connect(hostname="my.Host.name.com",
username="username",
# Uncomment one of the following...
# password=password
# pkey=pkey
)
# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command "echo {} | Sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)
# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)
exit_status = chan.recv_exit_status()
if exit_status != 0:
stderr = chan.recv_stderr(5000)
# Note that Sudo's "-S" flag will send the password Prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.
logger.error("Uh oh")
logger.error(stderr)
else:
logger.info("Successful!")
J'espère que ça aide quelqu'un. Mon cas d'utilisation consistait à créer des répertoires, à envoyer et à décompresser des fichiers et à démarrer des programmes sur ~ 300 serveurs simultanément. En tant que tel, l'automatisation était primordiale. J'ai essayé sshpass, et je m'attends à cela, puis j'ai trouvé ça.
J'espère que ça aide quelqu'un autant que moi!
La réponse de @abbotto n'a pas fonctionné pour moi, a dû faire certaines choses différemment:
J'ai une meilleure solution qui inclut la connexion à votre compte plutôt que le changement d'utilisateur root. C'est un script bash
http://felipeferreira.net/index.php/2011/09/ssh-automatic-login/
Voici comment je me connecte à mes serveurs.
ssp <server_ip>
cat /home/myuser/Documents/ssh_script.sh
#!/bin/bash
sshpass -p mypassword racine ssh @ $ 1
Et donc...
ssp server_ip
Je travaille comme suit
.ssh/config a été modifié pour éliminer l'invite yes/no - Je suis derrière un pare-feu, je ne m'inquiète donc pas des clés ssh usurpées
Host *
StrictHostKeyChecking no
Créez un fichier de réponse pour attendez-à-dire answer.expect
set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart
expect "*?assword {
send "password\r" <- your password here.
interact
Créez votre script bash et appelez expect dans le fichier
#!/bin/bash
i=1
while [$i -lt 129] # a few nodes here
expect answer.expect hadoopslave$i
i=[$i + 1]
sleep 5
done
Obtient 128 datanodes hadoop actualisés avec la nouvelle configuration - en supposant que vous utilisez un montage NFS pour les fichiers hadoop/conf
J'espère que cela aide quelqu'un - je suis un Windows décroché et cela m'a pris environ 5 heures pour comprendre!
J'ai réussi à le faire fonctionner avec ça:
SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername
Si vous le faites sur un système Windows, vous pouvez utiliser Plink (composant de PuTTY).
plink your_username@yourhost -pw your_password