OpenSSH scp
La utilidad invoca el ssh
programa para hacer la conexión SSH al host remoto, y el proceso ssh maneja la autenticación. El ssh
La utilidad no acepta una contraseña en la línea de comando o en su entrada estándar. Creo que esta es una decisión deliberada por parte de los desarrolladores de OpenSSH, porque sienten que las personas deberían usar mecanismos más seguros como la autenticación basada en claves. Cualquier solución para invocar ssh seguirá uno de estos enfoques:
- Utilice una clave SSH para la autenticación, en lugar de una contraseña.
- Use sshpass, expect o una herramienta similar para automatizar la respuesta a la solicitud de contraseña.
- Usar (abusar) de la función SSH_ASKPASS para obtener
ssh
para obtener la contraseña invocando otro comando, descrito aquí o aquí, o en algunas de las respuestas aquí. - Haga que el administrador del servidor SSH habilite la autenticación basada en host y úsela. Tenga en cuenta que la autenticación basada en host solo es adecuada para determinados entornos de red. Ver notas adicionales aquí y aquí.
- Escriba su propio cliente ssh usando perl, python, java o su lenguaje favorito. Hay bibliotecas de clientes ssh disponibles para la mayoría de los lenguajes de programación modernos, y tendrá control total sobre cómo el cliente obtiene la contraseña.
- Descargue el código fuente de ssh y cree una versión modificada de
ssh
que funciona de la manera que deseas. - Utilice un cliente ssh diferente. Hay otros clientes ssh disponibles, tanto gratuitos como comerciales. Uno de ellos podría adaptarse mejor a sus necesidades que el cliente OpenSSH.
En este caso particular, dado que ya estás invocando scp
de un script de python, parece que uno de estos sería el enfoque más razonable:
- Utilice pexpect, el módulo de expectativa de Python, para invocar
scp
y aliméntelo con la contraseña. - Utilice paramiko, la implementación ssh de Python, para realizar esta tarea ssh en lugar de invocar un programa externo.
Aquí hay una función para ssh
con una contraseña usando 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
Algo similar debería ser posible usando scp
.
La segunda respuesta que vinculó sugiere que use Pexpect (que generalmente es la forma correcta de interactuar con los programas de línea de comando que esperan entrada). Hay una bifurcación que funciona para python3 que puedes usar.