2011-06-07 79 views
12

我已经试过:如何用paramiko运行sudo? (蟒蛇)

  1. invoke_shell(),然后channel.send苏然后发送密码导致不是根
  2. invoke_shell(),然后channel.exec_command导致通道关闭错误
  3. _transport.open_session()然后channel.exec_command导致根不是
  4. invoke_shell(),然后写入到stdin和冲洗它导致根不是
+0

为什么不使用setuid http://en.wikipedia.org/wiki/Setuid? “命令::没有TTY存在并没有指定askpass程序”,如果你的sudoer需要密码,但 – 2011-06-07 19:44:53

回答

17

检查这个例子了:

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 

例发现这里有更多的解释: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

希望它能帮助!

+2

这将无法正常工作 – 2014-05-28 12:08:58

+1

好吧,你所提供的链接riskable的评论解决了上述问题: 标准输入,标准输出,标准错误= ssh.exec_command(“sudo -S%s”%命令) #如果stdout仍然打开,则sudo向我们要求输入密码 如果stdout.channel.closed为False: stdin.write('%s \ n '%password) stdin.flush() – 2014-05-28 12:21:06

+0

这是否仍然有效?它对我没有任何帮助 – 2016-07-07 15:52:29

0

在我看来,创建具有sudoer权限的脚本会更容易和更安全。

例如,将它添加到sudoers的:

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

现在你只需通过调用的paramiko主机上的脚本,并用它来完成。

+0

要编辑sudoers,我们必须以root身份登录(或使用'su' |'sudo')并编辑sudoers或运行脚本来执行此操作。如果你只能通过'paramiko'访问远程系统,那么我可能很难或不可能完成。例如,你正在自动化一些东西,你不想为每个主机手动准备你的脚本。 – Jury 2015-12-24 09:13:14

+0

这在大多数情况下不是一种选择,因为这具有很高的安全风险。 – 2016-05-12 09:52:04

4

invoke_shell工作对我来说是这样的:

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) 
+0

'''而不是循环'''做了诡计!感谢分享! :) – 2015-02-04 01:48:49

+0

这不起作用,getpass也不安全,因为它显示密码int他的历史 – TechJS 2018-02-16 12:03:11

2

对不起我没有时间详细回答,但我使用this提醒

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) 
2
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 
0

能够落实的paramiko sudo的命令AlexS微调答案(我现在在生产中使用它)将是:

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")) 

如果不使用密钥文件,则删除key_filename部分的connect方法;相反,如果只使用没有密码的密钥,请删除password部分。

关于此的一些注意事项是,它是多命令能力。意思是运行一个bash作为root,这样你就可以在一次运行中尽可能多地执行命令,只需将它们与;分开即可。