Entrez automatiquement le mot de passe SSH avec le script

194

Je dois créer un script qui saisit automatiquement un mot de passe sur le sshclient OpenSSH .

Disons que j'ai besoin de SSH myname@somehostavec le mot de passe a1234b.

J'ai déjà essayé ...

#~/bin/myssh.sh
ssh myname@somehost
a1234b

... mais cela ne fonctionne pas.

Comment puis-je intégrer cette fonctionnalité dans un script?

user1467855
la source

Réponses:

278

Vous devez d'abord installer sshpass .

  • Ubuntu / Debian: apt-get install sshpass
  • Fedora / CentOS: yum install sshpass
  • Cambre: 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

Remarques:

  • sshpasspeut également lire un mot de passe à partir d'un fichier lorsque l' -findicateur est passé.
    • L'utilisation -fempêche le mot de passe d'être visible si la pscommande est exécutée.
    • Le fichier dans lequel le mot de passe est stocké doit disposer d'autorisations sécurisées.
Abbotto
la source
12
C'est bien mieux que d'utiliser Expect.
Par Mejdal Rasmussen
5
sachez simplement que si sshpass bloque votre mot de passe des commandes telles que ps -aux, vous ne devriez normalement pas exécuter de commandes en tapant votre mot de passe car d'autres utilisateurs sur le même ordinateur peuvent voir le mot de passe en exécutant ps -aux. si possible, vous souhaitez également utiliser l'authentification par clé publique à la place, comme mentionné dans l'autre réponse. cela vous permet de séparer les informations d'authentification de votre script afin que vous puissiez partager votre script avec d'autres sans souci, et ensuite décider d'activer le chiffrement sur votre dossier ~ / .ssh sans chiffrer également votre script.
Alexander Taylor
2
Malheureusement, cela ne fonctionne pas pour moi sur un serveur avec un port ssh personnalisé ... pourquoi ssh ne peut-il pas simplement nous donner la possibilité d'insérer le mot de passe dans la ligne de commande?
Andy
2
pour que le port personnalisé fonctionne, ajoutez "-p port-number" à la fin de la commande
Ye Lwin Soe
96

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 /usr/bin/exp, alors vous pouvez utiliser:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

Terminé!

damn_c
la source
2
Cette réponse devrait obtenir plus de votes à mon avis, c'est un excellent emballage. J'ai juste essayé quelques opérations courantes comme rsyncing avec divers indicateurs et l'exécution de commandes à distance et cela fonctionnait à chaque fois. Ajouté à ma boîte à outils de scripts utiles, merci @damn_c!
user2082382
7
Peut-être qu'il n'a pas obtenu plus de votes positifs parce que les gens ne s'y attendaient pas?
clearlight
7
La raison pour laquelle ce n'est pas une très bonne réponse à l'OMI est que le mot de passe est écrit dans le script qui est de loin la méthode la moins sécurisée ...
PierreE
8
Le mot de passe sera visible par toute personne exécutant ps sur la machine.
Daniel Persson
22
"assword" est incroyable :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
71

Utilisez l'authentification par clé publique: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

Dans l'hôte source, exécutez ceci 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.

Diego Woitasen
la source
21
Je vois. Mais je suis obligé de ssh avec mot de passe. Ceci est dû au fait que "I" peut avoir le script sur une clé USB et avoir besoin de l'exécuter depuis n'importe quel ordinateur; sans désactiver la nécessité d'un mot de passe.
user1467855
3
@ user1467855, je pense que vous devez mieux expliquer vos besoins. Personne ne suggère que vous avez un réseau non sécurisé. Dans l'approche à clé publique, il serait toujours possible pour les utilisateurs de se connecter avec le mot de passe. Mais vous copieriez la clé privée sur votre clé USB, ce qui signifie que la clé USB serait la seule chose qui puisse se connecter sans mot de passe.
Aaron McDaid
5
Malheureusement, je suis dans une situation OP, car l'administrateur système interdit l'authentification par les clés rsa / dsa et nécessite des mots de passe. Qu'est-ce que tu vas faire.
Karel Bílek
27
Évalué parce que cela n'essaie même pas de répondre à la question posée.
Parthe Shot
2
Cela demande toujours la première connexion et ne peut pas être utilisé dans un script!
Mehrdad Mirreza
29

Vous pouvez utiliser un script attend. Je n'en ai pas écrit depuis un certain temps mais cela devrait ressembler à ci-dessous. 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
Lipongo
la source
J'ai fait ce que vous avez suggéré mais j'ai obtenu les erreurs suivantes:/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
user1467855
Merci Aaron d'avoir modifié ma réponse pour qu'elle soit correcte. Vous devrez peut-être exécuter la commande ci-dessous pour trouver le chemin correct à insérer pour expect. which expect
Lipongo
1
Vous pouvez également utiliser cette ligne de shebang:#!/usr/bin/env expect
glenn jackman
1
J'ai ajouté interactà la fin pour que la session ssh soit réellement interactive
Karel Bílek
-1 pour l'énorme risque de sécurité lié à la conservation d'un mot de passe en texte brut dans un script.
Aaron Digulla
21

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
RemiZOffAlex
la source
L' -pindicateur sert à spécifier un numéro de port.
Kookerus
4
Non. Sshpass n'est pas ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex
Pour exécuter sshpass sous Linux CentOS, vous devez yum -y install epel-releasepuisyum -y install sshpass
Junior Mayhé
Dans ce contexte, ces données peuvent être ignorées
RemiZOffAlex
Bien que je sache qu'il s'agit d'un ancien message, il convient de noter que la méthode Variant II laisserait le mot de passe donné à la session vulnérable dans l'historique de bash, ce qui la rendrait hautement déconseillée.
Kirkland le
11

sshpass + autossh

Un avantage appréciable du déjà mentionné sshpassest que vous pouvez l'utiliser avec autossh, éliminant encore plus l'inefficacité interactive.

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

Cela permettra la reconnexion automatique si, par exemple, votre wifi est interrompu en fermant votre ordinateur portable.

Sridhar Sarnobat
la source
2
Notez que vous ne pouvez pas ajouter d'option -fpour autossh dans cette combinaison, car when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt aussi superuser.com/questions/1278583/…
allenyllee
9

sshpass avec une meilleure sécurité

Je suis tombé sur ce fil en cherchant un moyen de ssh dans un serveur enlisé - il a fallu plus d'une minute pour traiter la tentative de connexion SSH et a expiré avant que je puisse entrer un mot de passe. Dans ce cas, je voulais être en mesure de 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 bien trop tard pour configurer une connexion par clé publique.)

sshpassà la rescousse. Cependant, il existe de meilleures façons de procéder quesshpass -p .

Mon implémentation passe directement à l'invite de mot de passe interactive (pas de temps perdu à voir si l'é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
Ian
la source
1
note à moi-même: mise à jour du script à utiliser trappour empêcher ctrl-C de divulguer la SSHPASSvariable
Ian
1
J'ai trouvé que PreferredAuthentications=keyboard-interactivecela ne fonctionnait pas, mais le remplacer par PreferredAuthentications=passwordfonctionnait.
Mike Partridge
8

C'est ainsi que je me connecte à mes serveurs.

ssp <server_ip>
  • alias ssp = '/ home / monutilisateur / Documents / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#! / bin / bash

sshpass -p mypassword racine ssh @ $ 1

Et donc...

ssp server_ip
DimiDak
la source
5
# 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 root@owned.com -p 22

référence: https://www.linkedin.com/pulse/youre-doing-wrong-ssh-plain-text-credentials-robert-mccurdy?trk=mp-reader-card

RmccurdyDOTcom
la source
3
Je pense que cet article est juste sarcastique!
Yan Foto
5

Je ne pense pas avoir vu qui que ce soit suggérer cela et le PO a juste dit "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 j'aurais besoin d'autorisations augmentées en utilisant sudo. Il s'avère que sudo peut accepter son mot de passe via stdin via le drapeau "-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 cela aide quelqu'un. Mon cas d'utilisation était la création de répertoires, l'envoi et la suppression de fichiers et le démarrage de programmes sur environ 300 serveurs à la fois. En tant que tel, l'automatisation était primordiale. J'ai essayé sshpass, expectpuis j'ai trouvé ça.

John Carrell
la source
2

Je l'ai fait fonctionner comme suit

.ssh / config a été modifié pour éliminer l'invite oui / non - je suis derrière un pare-feu donc je ne suis pas inquiet des clés ssh usurpées

host *
     StrictHostKeyChecking no

Créez un fichier de réponses pour expect ie 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 simplement 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 codes de données hadoop actualisés avec une 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 numpty et cela m'a pris environ 5 heures à comprendre!

WT29
la source
"Je suis derrière un pare-feu donc je ne suis pas inquiet des clés ssh usurpées". Un pare-feu ne fait absolument rien dans ce cas. Le HostKeyCheck vous permet de vérifier que l'hôte à l'autre extrémité n'est pas un hôte cheval de Troie. C'est-à-dire celui qui prétend juste être là où vous voulez vous connecter. Si vous vous connectez à un hôte inconnu et que vous faites quelque chose de sensible, comme écrire un fichier contenant des informations d'identification ou un jeton ou entrer un mot de passe, ces informations sont désormais de notoriété publique. Le fait d'être derrière un pare-feu n'a pas d'importance.
JCGB
2

Si vous faites cela sur un système Windows, vous pouvez utiliser Plink (qui fait partie de PuTTY).

plink your_username@yourhost -pw your_password
Marko Vranjkovic
la source
1

J'ai réussi à le faire fonctionner avec ça:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername
Konstantin Ineshin
la source
0

Dans l'exemple ci-dessous, j'écrirai la solution que j'ai utilisée:

Le scénario: je souhaite copier un fichier à partir d'un serveur à l'aide du script sh:

#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")

echo "$my_script"
BERGUIGA Mohamed Amine
la source
-2

Utilisez ce script tossh dans le script, le premier argument est le nom d'hôte et le second sera le mot de passe.

#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: " 
send "$pass\n";
interact"
Shivam Mehrotra
la source
Qu'est-ce que cela montre en plus des réponses existantes? En particulier ceux de damn_c, Lipongo ou RemiZOffAlex et autres ...
Martin Prikryl
exécution de script avec ssh #! / usr / bin / expect set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh expect "* assword:" envoyer "$ pass \ n"; interagir "
Shivam Mehrotra
-3

Pour connecter une machine distante via des scripts shell, utilisez la commande ci-dessous:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS

IPADDRESS, USERNAMEet PASSWORDsont les valeurs d'entrée qui doivent être fournies dans le script, ou si nous voulons fournir au moment de l'exécution, utilisez la commande "read".

timide
la source
5
Que montre cette réponse en plus des réponses existantes? + Ne jamais suggérer à quiconque d'utiliser StrictHostKeyChecking=nosans en expliquer les conséquences.
Martin Prikryl
-5
sudo ssh username@server_ip_address -p port_number

appuyez sur la touche Entrée, puis entrez le mot de passe de votre système, puis entrez enfin le mot de passe de votre serveur

Manoj Rana
la source