2011-06-07 61 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,這樣你就可以在一次運行中儘可能多地執行命令,只需將它們與;分開即可。