¿Cómo ejecutar sudo con paramiko? (Pitón)

Lo que he intentado:

  1. invoke_shell() luego channel.send su y luego el envío de la contraseña resultó en no ser root
  2. invoke_shell() y luego channel.exec_command dieron como resultado un error de “Canal cerrado”
  3. _transport.open_session() luego channel.exec_command resultó en no ser root
  4. invoke_shell() luego escribir a stdin y vaciarlo resultó en no ser root

mira este ejemplo:

 ssh.connect('127.0.0.1', username='jesse', password='lol') stdin, stdout, stderr = ssh.exec_command( "sudo dmesg") stdin.write('lol\n') stdin.flush() data = stdout.read.splitlines() for line in data: if line.split(':')[0] == 'AirPort': print line 

Ejemplo encontrado aquí con más explicaciones: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

¡Espero eso ayude!

invoke_shell me funcionó así:

 import paramiko, getpass, re, time ssh_client = paramiko.SSHClient() ssh_client.connect( host ) sudo_pw = getpass.getpass("sudo pw for %s: " % host) command = "sudo magicwand" channel = ssh_client.invoke_shell() channel.send( command ) # wait for prompt while not re.search(".*\[sudo\].*",channel.recv(1024)): time.sleep(1) channel.send( "%s\n" % sudo_pw ) 

Lo siento, no tengo tiempo para responder a los detalles, pero pude implementar comandos sudo en paramiko usando este consejo

 import paramiko l_password = "yourpassword" l_host = "yourhost" l_user = "yourusername" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(l_host, username=l_user, password=l_password) transport = ssh.get_transport() session = transport.open_session() session.set_combine_stderr(True) session.get_pty() #for testing purposes we want to force sudo to always to ask for password. because of that we use "-k" key session.exec_command("sudo -k dmesg") stdin = session.makefile('wb', -1) stdout = session.makefile('rb', -1) #you have to check if you really need to send password here stdin.write(l_password +'\n') stdin.flush() for line in stdout.read().splitlines(): print 'host: %s: %s' % (l_host, line) 
 You Can use channel to send sudo password: passwd = getpass.getpass() ssh = paramiko.client.SSHClient() ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) ssh.load_system_host_keys() ssh.connect(host, allow_agent=True) chan = ssh.get_transport().open_session() chan.get_pty() chan.setblocking(1) chan.exec_command("sudo -k dmesg") while chan.recv_ready()==False: stdout=chan.recv(4096) if re.search('[Pp]assword', stdout): chan.send(passwd+'\n') time.sleep(1) while chan.recv_ready(): stdout += chan.recv(20000) chan.close() ssh.close()de here 

AlexS respuesta afinada de AlexS Fine (que ahora la estoy usando en producción) sería:

 def sudo_run_commands_remote(command, server_address, server_username, server_pass, server_key_file): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=server_address, username=server_username, password=server_pass, key_filename=server_key_file) session = ssh.get_transport().open_session() session.set_combine_stderr(True) session.get_pty() session.exec_command("sudo bash -c \"" + command + "\"") stdin = session.makefile('wb', -1) stdout = session.makefile('rb', -1) stdin.write(server_pass + '\n') stdin.flush() print(stdout.read().decode("utf-8")) 

Elimine la parte del nombre de key_filename del método de connect si no usa un archivo de clave y, en cambio, si solo usa una clave sin contraseña, elimine la parte de la password .

Algunas notas sobre esto es que es capaz de comandos múltiples. Lo que significa que se está ejecutando un bash como root para que pueda tantos comandos como pueda en una sola ejecución con solo separarlos con ; .

En mi opinión, sería mucho más fácil y seguro crear un script que tenga derechos de suscripción.

Por ejemplo, agregue esto a sudoers:

 myuser ALL=NOPASSWD:/home/myuser/somescript.sh 

Ahora puede invocar el script a través de paramiko en la máquina host y terminar con él.

Pude ejecutar el comando sudo cupsdisable en el servidor remoto manualmente sin tener que ingresar la contraseña cuando inicio sesión en ese servidor como uno de los usuarios admin (no root) pero cuando ejecuto la misma usando stdin, stdout, stderr = client.exec_command("sudo cupsdisable ") no hace nada.

El comando que funcionó para mí fue:

 stdin, stdout, stderr = client.exec_command("sudo -u root /usr/sbin/cupsdisable ") 

Esto es específico para el escenario mencionado anteriormente solamente. Espero que esto ayude a alguien