Comment exécuter la commande sftp avec un mot de passe du script Bash?

173

J'ai besoin de transférer un fichier journal vers un hôte distant en utilisant sftp à partir d'un hôte Linux. J'ai reçu des informations d'identification pour la même chose de mon groupe d'opérations. Cependant, comme je n'ai pas de contrôle sur un autre hôte, je ne peux pas générer et partager des clés RSA avec l'autre hôte.

Existe-t-il donc un moyen d'exécuter la sftpcommande (avec le nom d'utilisateur / mot de passe fourni) à partir du script Bash via une tâche cron ?

J'ai trouvé une question similaire de Stack Overflow, Spécifiez le mot de passe pour sftp dans un script Bash , mais il n'y avait pas de réponse satisfaisante à mon problème.

anubhava
la source

Réponses:

178

Vous avez quelques options autres que l'utilisation de l'authentification par clé publique:

  1. Utiliser le trousseau
  2. Utilisez sshpass (moins sécurisé mais qui répond probablement à vos besoins)
  3. Utilisez expect (le moins sécurisé et plus de codage nécessaire)

Si vous décidez de donner une chance à sshpass, voici un extrait de script fonctionnel pour le faire:

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!
anubhava
la source
3
Pour l'utiliser sur Mac: stackoverflow.com/questions/9102557/…
anubhava
18
Pas besoin d'exporter, je pense. SSHPASS=password sshpass -e ...devrait faire.
Jens
9
J'ai pu faire un one-liner pour télécharger un fichier journal:sshpass -p "my_password" sftp -oPort=9999 user@host:dir/file.log
Cloud Artisans
6
@gorus: One-liner est très cool, mais je ne voulais pas utiliser de mot de passe sur la ligne de commande en raison des risques accrus de surveillance.
anubhava
8
-oBatchMode=noétait la pièce manquante cruciale pour moi.
richardkmiller
99

Une autre façon serait d'utiliser lftp:

lftp sftp://user:password@host  -e "put local-file.name; bye"

L'inconvénient de cette méthode est que les autres utilisateurs de l'ordinateur peuvent lire le mot de passe à partir d'outils tels psque et que le mot de passe peut faire partie de l'historique de votre shell.

Une alternative plus sécurisée disponible depuis LFTP 4.5.0 consiste à définir la LFTP_PASSWORDvariable d'environnement et à exécuter lftp avec --env-password. Voici un exemple complet:

LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user@host  -e "put local-file.name; bye"

LFTP comprend également une fonction de mise en miroir cool (peut inclure la suppression après le transfert confirmé --Remove-source-files):

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
Karassik
la source
9
+1 pour avoir suggéré une alternative mais pouvons-nous éviter de fournir un mot de passe sur la ligne de commande?
anubhava
1
Vote contre le vote pour avoir montré le mot de passe à quiconque sur le même ordinateur
Aaron Digulla
10
Vous pouvez créer le fichier de script pour lftp, de cette façon vous n'aurez pas à fournir le mot de passe dans la ligne de commande. Créez un fichier put-script: puis open sftp://user:password@host; put local-file.name; exit exécutez De lftp -f put-script cette façon, vous n'avez pas besoin d'avoir le nom d'utilisateur et le mot de passe dans une ligne de commande et pouvez configurer des autorisations restrictives sur votre fichier de script.
obaranovsky
@obaranovsky C'est une bonne idée. Je me demande si je devais ajouter ceci à ma variable d'environnement en tant qu'alias ou fonction, serait-il sécurisé et possible de le cacher aux autres utilisateurs?
sdkks
1
Beaucoup plus facile à faire lftpque de jouer avec sftpet sshpass. Bonne réponse.
MeanEYE
53

Expect est un excellent programme à utiliser.

Sur Ubuntu, installez-le avec:

sudo apt-get install expect

Sur une machine CentOS, installez-le avec:

yum install expect

Disons que vous souhaitez établir une connexion à un serveur sftp, puis télécharger un fichier local de votre machine locale vers le serveur sftp distant

#!/usr/bin/expect

spawn sftp username@hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact

Cela ouvre une connexion sftp avec votre mot de passe au serveur.

Ensuite, il va dans le répertoire où vous souhaitez télécharger votre fichier, dans ce cas "logdirectory"

Cela télécharge un fichier journal à partir du répertoire local trouvé dans / var / log / avec le nom de fichier file.log vers le «répertoire journal» sur le serveur distant

rezizter
la source
Merci pour votre réponse, je m'attendais à l'une de mes options pour réaliser cette tâche.
anubhava
Je vous remercie. J'ai trouvé votre réponse grâce à une recherche, je l'ai utilisée et construit un script avec succès. Je viens de publier le script pour poterity
rezizter
Merci beaucoup pour votre réponse, je l'ai déjà voté pour :)
anubhava
J'utilise ceci pour entrer la phrase de passe de la clé privée ssh. Il est plus pratique de mettre la même clé publique sur tous les serveurs et de simplement faire pivoter périodiquement la phrase secrète de la clé privée.
sdkks
24

Vous pouvez utiliser lftp de manière interactive dans un script shell afin que le mot de passe ne soit pas enregistré dans .bash_history ou similaire en procédant comme suit:

vi test_script.sh

Ajoutez ce qui suit à votre fichier:

#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>

cd <base directory for your put file>

lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT

Et écrivez / quittez l'éditeur vi après avoir modifié l'hôte, l'utilisateur, le mot de passe et le répertoire pour votre saisie de fichier put. :wqEnsuite, rendez votre script exécutable chmod +x test_script.shet exécutez-le ./test_script.sh.

Mike S.
la source
2
Pour écraser le fichier existant, ajoutez "set xfer: clobber on" après lftp << END_SCRIPT
Balaji Natarajan
17

On m'a récemment demandé de passer de ftp à sftp, afin de sécuriser la transmission des fichiers entre les serveurs. Nous utilisons le package Tectia SSH, qui a une option--password pour passer le mot de passe sur la ligne de commande.

exemple : sftp --password="password" "userid"@"servername"

Exemple de lot:

(
  echo "
  ascii
  cd pub
  lcd dir_name
  put filename
  close
  quit
    "
) | sftp --password="password" "userid"@"servername"

J'ai pensé que je devrais partager ces informations, car je regardais divers sites Web, avant d'exécuter la commande help ( sftp -h), et j'ai été surpris de voir l'option de mot de passe.

Mahony
la source
9
+1 pour votre bonne suggestion. Cependant, cela vous demandera de passer le mot de passe sur la ligne de commande et quiconque sur le système exécutant la pscommande pourra voir votre mot de passe.
anubhava
4
J'ai essayé ça, j'ai euunknown option -- - usage: sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host
cyber8200
1
@ihue probablement parce que vous avez besoin de Techia SSH , pas d'OpenSSH
qris
17

Vous pouvez remplacer en activant l'authentification sans mot de passe. Mais vous devriez installer les clés (pub, priv) avant de vous lancer.

Exécutez les commandes suivantes sur le serveur local.

Local $> ssh-keygen -t rsa 

Appuyez sur ENTRÉE pour toutes les options demandées. Aucune valeur ne doit être saisie.

Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user@targetmachine:
Prompts for pwd$>  ENTERPASSWORD

Connectez-vous au serveur distant à l'aide de la commande suivante

Local $> ssh user@targetmachine
Prompts for pwd$> ENTERPASSWORD

Exécutez les commandes suivantes sur le serveur distant

Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit

Exécutez la commande suivante sur le serveur local pour tester l'authentification sans mot de passe. Il doit être connecté sans mot de passe.

$> ssh user@targetmachine
SriniV
la source
1
+1 pour votre réponse, mais la question portait sur le faire sans clés publiques / privées.
anubhava
oups ... Je viens de voir les restrictions sur le partage de clés :)
SriniV
Par curiosité, cette commande lftp -p ${port} -u ${login_id},${password} ${ip_number}invoquée depuis un script shell les affichera-t- elle quelque part? Comment avez-vous résolu en dehors de sshpass?
SriniV
Je n'ai pas lftpet je compte sur sshpassMac et Linux à la fois.
anubhava
Or pur. Merci! :)
Nikolay Tsenkov
7

Combinez sshpass avec un fichier d'informations d'identification verrouillé et, dans la pratique, c'est aussi sécurisé que n'importe quoi - si vous avez root sur la boîte pour lire le fichier d'informations d'identification, tous les paris sont de toute façon ouverts.

Rich Harding
la source
5

Programme Bash pour attendre que sftp demande un mot de passe, puis envoyez-le:

#!/bin/bash
expect -c "
spawn sftp username@your_host
expect \"Password\"
send \"your_password_here\r\"
interact "

Vous devrez peut-être installer attendez, changez le libellé de «Mot de passe» en minuscule «p» pour correspondre à ce que votre invite reçoit. Le problème ici est qu'il expose votre mot de passe en texte brut dans le fichier ainsi que dans l'historique des commandes. Ce qui va presque à l'encontre de l'objectif d'avoir un mot de passe en premier lieu.

Eric Leschinski
la source
+1 mais je pense que vous indiquez clairement quels sont les problèmes avec cette approche.
anubhava
5

Vous pouvez utiliser sshpass pour cela. Voici les étapes

  1. Installez sshpass pour Ubuntu - sudo apt-get install sshpass
  2. Ajoutez l'adresse IP distante à votre fichier d'hôte connu si c'est la première fois Pour Ubuntu -> ssh user @ IP -> entrez 'yes'
  3. donnez une commande combinée de scp et sshpass pour cela. Vous trouverez ci-dessous un exemple de code pour faire face à la guerre à Tomcat distant sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps
ravi ranjan
la source