2011-06-07 15 views
12

मैं क्या कोशिश की है:paramiko के साथ sudo कैसे चलाएं? (अजगर)

  1. invoke_shell() तो channel.send सु तो भेज पासवर्ड जड़ नहीं किया जा रहा में हुई
  2. invoke_shell() तो चैनल बंद हो गया त्रुटि
  3. में हुई channel.exec_command
  4. _transport.open_session() तो
  5. invoke_shell जड़ में नहीं किया जा रहा में हुई channel.exec_command() तो stdin के लिए लिख सकते हैं और फ्लश यह जड़ में नहीं किया जा रहा में हुई
+0

क्यों सेटुइड का उपयोग नहीं करें http://en.wikipedia.org/wiki/Setuid? "sudo: कोई tty वर्तमान और कोई askpass कार्यक्रम निर्दिष्ट" अपने sudoer एक पासवर्ड है, हालांकि की आवश्यकता है –

उत्तर

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

यह काम नहीं करेगा: stdin, stdout, stderr = –

+1

ठीक है, लिंक आपके द्वारा दी गई पर riskable की टिप्पणी से ऊपर समस्या का हल ssh.exec_command ("sudo -S% s"% कमांड) # अगर स्टडआउट अभी भी खुला है तो सुडो हमें पासवर्ड के लिए पूछ रहा है अगर stdout.channel.closed गलत है: stdin.write ('% s \ n '% पासवर्ड) stdin.flush() –

+0

क्या यह अभी भी काम करता है?यह मेरे लिए कुछ भी नहीं है –

0

मेरे दिमाग में यह एक स्क्रिप्ट बनाने के लिए बहुत आसान और सुरक्षित होगा जिसमें सुडौयर अधिकार हैं।

उदाहरण के लिए, sudoers से जोड़ें:

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

अब तुम सिर्फ paramiko के माध्यम से स्क्रिप्ट आह्वान कर सकते हैं होस्ट मशीन पर है और इसके साथ किया जाए।

+0

सूडोर्स को संपादित करने के लिए, हमें रूट के रूप में लॉग इन करना होगा (या 'su' | 'sudo' का उपयोग करें) और ऐसा करने के लिए सूडर्स या रन स्क्रिप्ट संपादित करें। यदि आपके पास केवल 'paramiko' के माध्यम से रिमोट सिस्टम तक पहुंच है तो मैं मुश्किल या असंभव हो सकता हूं। उदाहरण के लिए, आप कुछ स्वचालित कर रहे हैं, आप अपनी स्क्रिप्ट के लिए प्रत्येक मेजबान मैन्युअल रूप से तैयार नहीं करना चाहते हैं। – Jury

+0

यह ज्यादातर मामलों में एक विकल्प नहीं है क्योंकि यह उच्च सुरक्षा जोखिम है। –

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

कि '' 'जबकि लूप नहीं 'चाल चल रही थी! साझा करने के लिए धन्यवाद! :) –

+0

यह काम नहीं करता है, गेटपास भी सुरक्षित नहीं है क्योंकि यह पासवर्ड को दिखाता है – TechJS

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

connect विधि के key_filename हिस्सा निकालें यदि आप एक कुंजी फ़ाइल का उपयोग करें और इसके विपरीत में यदि आप केवल पासवर्ड के बिना एक कुंजी का उपयोग करें, password हिस्से को हटाने नहीं है।

इसके बारे में कुछ नोट्स यह है कि, यह बहु कमांड सक्षम है। मतलब यह है कि bashroot के रूप में चल रहा है, ताकि आप एक ही रन में जितना कमांड कर सकें, उन्हें ; से अलग कर सकते हैं।

संबंधित मुद्दे