Running Sudo Command with paramiko

Solution 1:

First of all, have you tried in console with ssh [email protected] "sudo -S -p '' dmesg". If it also fails, then you might check the sshd settings and the sudoer settings.

If it works well, please add some echo between lines, so that we can know exactly when the exception was thrown. I highly doubt that you should change sudo dmesg to sudo -S -p '' dmesg.

You might also try my wrapper of paramiko. I can use it smoothly to access any CentOS/SuSE node and perform any commands (w/wo sudo privilege):

#!/usr/bin/python

from StringIO import StringIO
import paramiko 

class SshClient:
    "A wrapper of paramiko.SSHClient"
    TIMEOUT = 4

    def __init__(self, host, port, username, password, key=None, passphrase=None):
        self.username = username
        self.password = password
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        if key is not None:
            key = paramiko.RSAKey.from_private_key(StringIO(key), password=passphrase)
        self.client.connect(host, port, username=username, password=password, pkey=key, timeout=self.TIMEOUT)

    def close(self):
        if self.client is not None:
            self.client.close()
            self.client = None

    def execute(self, command, sudo=False):
        feed_password = False
        if sudo and self.username != "root":
            command = "sudo -S -p '' %s" % command
            feed_password = self.password is not None and len(self.password) > 0
        stdin, stdout, stderr = self.client.exec_command(command)
        if feed_password:
            stdin.write(self.password + "\n")
            stdin.flush()
        return {'out': stdout.readlines(), 
                'err': stderr.readlines(),
                'retval': stdout.channel.recv_exit_status()}

if __name__ == "__main__":
    client = SshClient(host='host', port=22, username='username', password='password') 
    try:
       ret = client.execute('dmesg', sudo=True)
       print "  ".join(ret["out"]), "  E ".join(ret["err"]), ret["retval"]
    finally:
      client.close() 

Solution 2:

Im sorry i dont have time for details answer but i was able to implement sudo commands on paramiko using this advise

#!/usr/bin/env python
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)

Solution 3:

I know this question is kind of old but I was wanting to use sudo and paramiko together, too. It took me a while to figure out this solution. It may not work for everyone but I figured it was worth adding.

def ssh_handler(hostname, username=USER, password=PASS, command=CMD): 
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname,
                username=username,
                password=password) 

    stdin, stdout, stderr = ssh.exec_command(prepare_command(command))
    # stdin.write(password+'\n')  

    response = stdout.read()   
    ssh.close()
    print response


def prepare_command(command):  
    if (not isinstance(command, basestring)): 
        command = ' ; '.join(command)  
    command = command.replace('"','\"') 
    command = 'sudo -s -- " '+command+' " \n'
    return command


# kind of a dumb example but you get the point 
mycmd = []; 
mycmd.append('cd /dir/this/user/doesnt/have/access/to')
mycmd.append('ls -las')
mycmd.append('cat file_in_dir.txt')

ssh_handler(server, command=mycmd)