Saltar al contenido

Enviar una contraseña a través de SSH o SCP con subprocess.Popen

Por fin luego de tanto luchar pudimos hallar la contestación de esta contratiempo que muchos los lectores de este sitio web han presentado. Si tienes algo que compartir no dudes en compartir tu información.

Solución:

Aquí hay una función para ssh con una contraseña usando pexpect:

import pexpect

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.

El 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. los 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 key-autenticación basada en. Cualquier solución para invocar ssh seguirá uno de estos enfoques:

  1. Usa un SSH key para la autenticación, en lugar de una contraseña.
  2. Utilice sshpass, expect o una herramienta similar para automatizar la respuesta a la solicitud de contraseña.
  3. 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í.
  4. Solicite al administrador del servidor SSH que 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í.
  5. Escriba su propio cliente ssh usando perl, python, java o su idioma favorito. Hay bibliotecas de clientes ssh disponibles para la mayoría de los lenguajes de programación modernos, y tendría control total sobre cómo el cliente obtiene la contraseña.
  6. Descargue el código fuente de ssh y cree una versión modificada de ssh que funciona como usted quiere.
  7. 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:

  1. Use pexpect, el módulo de expectativa de python, para invocar scp y darle la contraseña.
  2. Utilice paramiko, la implementación ssh de Python, para realizar esta tarea ssh en lugar de invocar un programa externo.

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *