L'OpenSSH scp
l'utilitaire invoque le ssh
programme pour établir la connexion SSH à l'hôte distant, et le processus ssh gère l'authentification. Le ssh
L'utilitaire n'accepte pas de mot de passe sur la ligne de commande ou sur son entrée standard. Je pense que c'est une décision délibérée de la part des développeurs d'OpenSSH, car ils pensent que les gens devraient utiliser des mécanismes plus sécurisés comme l'authentification par clé. Toute solution pour invoquer ssh suivra l'une de ces approches :
- Utilisez une clé SSH pour l'authentification, au lieu d'un mot de passe.
- Utilisez sshpass, expect ou un outil similaire pour automatiser la réponse à l'invite de mot de passe.
- Utiliser (abuser) la fonctionnalité SSH_ASKPASS pour obtenir
ssh
pour obtenir le mot de passe en appelant une autre commande, décrite ici ou ici, ou dans certaines des réponses ici. - Demandez à l'administrateur du serveur SSH d'activer l'authentification basée sur l'hôte et utilisez-la. Notez que l'authentification basée sur l'hôte ne convient qu'à certains environnements réseau. Voir les notes supplémentaires ici et ici.
- Écrivez votre propre client ssh en utilisant perl, python, java ou votre langage préféré. Il existe des bibliothèques clientes ssh disponibles pour la plupart des langages de programmation modernes, et vous auriez un contrôle total sur la façon dont le client obtient le mot de passe.
- Téléchargez le code source ssh et créez une version modifiée de
ssh
qui fonctionne comme vous le souhaitez. - Utilisez un client ssh différent. Il existe d'autres clients ssh disponibles, à la fois gratuits et commerciaux. L'un d'entre eux pourrait mieux répondre à vos besoins que le client OpenSSH.
Dans ce cas particulier, étant donné que vous appelez déjà scp
à partir d'un script python, il semble que l'une d'entre elles serait l'approche la plus raisonnable :
- Utilisez pexpect, le module python expect, pour invoquer
scp
et donnez-lui le mot de passe. - Utilisez paramiko, l'implémentation python ssh, pour effectuer cette tâche ssh au lieu d'appeler un programme extérieur.
Voici une fonction à ssh
avec un mot de passe en utilisant pexpect
:
import pexpect
import tempfile
def ssh(host, cmd, user, password, timeout=30, bg_run=False):
"""SSH'es to a host using the supplied credentials and executes a command.
Throws an exception if the command doesn't return 0.
bgrun: run command in the background"""
fname = tempfile.mktemp()
fout = open(fname, 'w')
options = '-q -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oPubkeyAuthentication=no'
if bg_run:
options += ' -f'
ssh_cmd = 'ssh %[email protected]%s %s "%s"' % (user, host, options, cmd)
child = pexpect.spawn(ssh_cmd, timeout=timeout) #spawnu for Python 3
child.expect(['[pP]assword: '])
child.sendline(password)
child.logfile = fout
child.expect(pexpect.EOF)
child.close()
fout.close()
fin = open(fname, 'r')
stdout = fin.read()
fin.close()
if 0 != child.exitstatus:
raise Exception(stdout)
return stdout
Quelque chose de similaire devrait être possible en utilisant scp
.
La deuxième réponse que vous avez liée suggère que vous utilisiez Pexpect (qui est généralement la bonne façon d'interagir avec les programmes en ligne de commande qui attendent une entrée). Il y en a un fork qui fonctionne pour python3 que vous pouvez utiliser.