私が試したこと:
invoke_Shell()
then _channel.send
_ su
そしてパスワードを送信すると、rootではなくなりましたinvoke_Shell()
、次に_channel.exec_command
_の結果、「チャネルが閉じられました」エラーが発生しました_transport.open_session()
then _channel.exec_command
_結果としてルートになりませんでしたinvoke_Shell()
次にstdinに書き込んでフラッシュすると、rootではなくなりましたこの例を確認してください。
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/
それが役に立てば幸い!
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 )
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
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
部分を削除します。
これに関するいくつかの注意点は、マルチコマンド対応であるということです。つまり、bash
をroot
として実行しているため、コマンドを;
で区切るだけで、1回の実行でできるだけ多くのコマンドを実行できます。
申し訳ありませんが、詳細な回答をする時間がありませんが、 this adviceを使用してparamikoにSudoコマンドを実装できました。
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)
リモートサーバーで管理者ユーザー(rootではない)の1人としてログインするときにパスワードを入力せずに手動で_Sudo cupsdisable
_コマンドを実行できましたが、stdin、stdout、stderr = client.exec_command("Sudo cupsdisable <Printqueuename>")
を使用して同じものを実行すると何もしません。
私のために働いたコマンドは:
_stdin, stdout, stderr = client.exec_command("Sudo -u root /usr/sbin/cupsdisable <printQueuename>")
_
これは、上記のシナリオにのみ固有です。これが誰かを助けることを願っています
私の考えでは、sudoer権限を持つスクリプトを作成する方がはるかに簡単で安全です。
たとえば、これをsudoersに追加します。
myuser ALL=NOPASSWD:/home/myuser/somescript.sh
これで、ホストマシンのparamikoを介してスクリプトを呼び出し、それを実行できます。