Running Sudo Command with paramiko

前端 未结 4 837
北荒
北荒 2020-11-30 08:25

I am trying to execute a sudo command on a remote machine using python-paramiko, when I execute the command, I bind it with 3 streams, and I use the input stream to pass the

相关标签:
4条回答
  • 2020-11-30 08:32

    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)
    
    0 讨论(0)
  • 2020-11-30 08:35

    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)
    
    0 讨论(0)
  • 2020-11-30 08:41

    First of all, have you tried in console with ssh cdc@192.168.0.104 "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() 
    
    0 讨论(0)
  • 2020-11-30 08:54

    I was able to implement this solution which was found in other Stackoverflow threads.

    https://www.reddit.com/r/learnpython/comments/60taz7/execute_sudo_su_and_input_password_with_paramiko/df94q7s/

    The solution for me was to use invoke_shell() when requiring the use of commands with sudo.

    0 讨论(0)
提交回复
热议问题