152 votes

Utiliser Expect dans un script Bash pour fournir un mot de passe à une commande SSH.

J'essaie d'utiliser Expect dans un script Bash pour fournir le mot de passe SSH. Fournir le mot de passe fonctionne, mais je ne me retrouve pas dans la session SSH comme je le devrais. Cela revient directement à Bash.

Mon script :

#!/bin/bash

read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com'
expect "password"
send "$PWD\n"
EOD
echo "you're out"

La sortie de mon script :

spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com's password: you're out

Je voudrais avoir ma session SSH et, seulement quand je la quitte, revenir à mon script Bash.

La raison pour laquelle j'utilise Bash avant Expect est que je dois utiliser un menu. Je peux choisir à quelle unité/dispositif me connecter.

<strong>À ceux qui veulent répondre que je devrais utiliser des clés SSH, veuillez vous abstenir.</strong>

56 votes

Veuillez voir la première ligne : Pour ceux qui veulent répondre que je devrais utiliser des clés SSH, veuillez vous abstenir.

58 votes

Je modifierais votre première ligne pour qu'elle soit un peu plus amicale. Vous pourriez envisager quelque chose comme "En raison de contraintes, je ne peux tout simplement pas utiliser de clés SSH, je dois trouver un moyen de le faire fonctionner avec des attentes". Vous devez vous attendre à ce que les gens soient naturellement curieux de savoir pourquoi vous n'utilisez pas de clés, et vous essayez juste d'être utile :) @Ignacio ne l'a pas fait suggérer que vous les utilisiez, il confirmait simplement que c'était une contrainte et non un oubli.

0 votes

J'essaierais d'utiliser kermit dans ce cas. Il dispose d'un très langage de script robuste columbia.edu/kermit/skermit.html#scripts

99voto

pietrushnic Points 353

Mélanger Bash et Expect n'est pas un bon moyen d'obtenir l'effet désiré. J'essaierais d'utiliser uniquement Expect :

#!/usr/bin/expect
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com

# Use the correct prompt
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
send "my_password\r"
interact -o -nobuffer -re $prompt return
send "my_command1\r"
interact -o -nobuffer -re $prompt return
send "my_command2\r"
interact

Un exemple de solution pour bash pourrait être :

#!/bin/bash
/usr/bin/expect -c 'expect "\n" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }'

Cela attendra Enter et revenir ensuite (pour un moment) à la session interactive.

1 votes

Ça marche très bien, merci. Et si je veux taper une commande une fois que je suis connecté via SSH, que dois-je faire ?

0 votes

Ce script doit retourner un shell ineractif avec un utilisateur connecté. Je ne comprends pas la question. Si vous voulez absolument utiliser le même script dans bash regardez l'entrée éditée.

0 votes

De la même manière que j'envoie le mot de passe lorsqu'on me le demande, je voudrais envoyer des commandes système une fois connecté.

57voto

dotnix Points 195

Le moyen le plus simple est d'utiliser sshpass . Il est disponible en Ubuntu / Debian et vous n'avez pas à vous occuper de l'intégration prévue avec Bash.

Un exemple :

sshpass -p<password> ssh <arguments>
sshpass -ptest1324 ssh user@192.168.1.200 ls -l /tmp

La commande ci-dessus peut être facilement intégrée à un script de Bash.

Note : Veuillez lire le Considérations de sécurité section dans man sshpass pour une compréhension complète des implications en matière de sécurité.

0 votes

Je ne sais pas si c'est une bonne solution, mais elle simplifie certainement beaucoup de choses. Merci

10 votes

Très dangereux du point de vue de la sécurité : les arguments de la ligne de commande peuvent être lus par n'importe quel autre processus du système. Il est possible de les écraser, et avec un peu de chance sshpass le fait, mais même dans ce cas, il y a une période pendant laquelle il est encore en train de démarrer avant qu'il ne soit capable de le faire lorsque le mot de passe est disponible pour tous les processus.

1 votes

@CharlesDuffy Bien sûr, vous avez raison. sshpass est utilisé dans un scénario où vous avez des scripts de test simples qui s'exécutent dans un environnement de réseau local où la sécurité n'est pas la première préoccupation. En fait, il existe une section dans man sshpass où une section entière sur les considérations de sécurité est expliquée. J'ai ajouté ceci à la réponse, merci.

32voto

dr-jan Points 673

Ajoutez la commande "interact" Expect juste avant votre EOD :

#!/bin/bash

read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
expect "password"
send "$PWD\n"
interact
EOD
echo "you're out"

Cela devrait vous permettre d'interagir avec la machine distante jusqu'à ce que vous vous déconnectiez. Ensuite, vous serez de retour dans Bash.

0 votes

Il entre et ressort immédiatement. "Vous êtes sorti" est imprimé.

8 votes

J'ai remplacé "interact" et "EOD" par "expect eof" et cela a fonctionné pour moi. Ceci est sur un Mac.

3 votes

Aucune des réponses de cette page n'a fonctionné pour moi mais la suggestion de @Emmanuel d'utiliser expect eof a résolu le problème.

10voto

Timmah Points 810

Veillez également à utiliser

send -- "$PWD\r"

à la place, car les mots de passe commençant par un tiret (-) échoueront sinon.

L'exemple ci-dessus n'interprète pas une chaîne commençant par un tiret comme une option de la commande d'envoi.

9voto

user562374 Points 2196

Utilisez l'outil d'aide fd0ssh (de hxtools, pas de pmt). Il fonctionne sans avoir à attendre une invite particulière de la part de l'utilisateur. ssh programme.

0 votes

C'est génial ! C'est un peu difficile de le faire fonctionner (au moins dans le serveur Ubuntu) mais ça marche bien ! La configuration que nous avons faite : echo "yoursshpass" | fd0ssh ssh -c -L$port:$ip:$remote_port user@yourserver.com & MERCI !

1 votes

Beaucoup plus sûr que de passer le mot de passe sur la ligne de commande comme sshpass fait.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X