Pythonに書いたBashスクリプトを書き直しています。そのスクリプトの核心は
ssh -t first.com "ssh second.com very_remote_command"
paramiko によるネストされた認証に問題があります。私の正確な状況を扱った例は見つかりませんでしたが、リモート ホストでsudoを使用した例を見つけることができました。
最初のメソッドは標準入力に書き込みます
ssh.connect('127.0.0.1', username='jesse', password='lol')
stdin, stdout, stderr = ssh.exec_command("sudo dmesg")
stdin.write('lol\n')
stdin.flush()
2 番目はチャネルを作成し、ソケットのようなsendとrecvを使用します。
stdin.writeをsudoで動作させることができましたが、リモート ホストのsshでは動作しません。
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('first.com', username='luser', password='secret')
stdin, stdout, stderr = ssh.exec_command('ssh luser@second.com')
stdin.write('secret')
stdin.flush()
print '---- out ----'
print stdout.readlines()
print '---- error ----'
print stderr.readlines()
ssh.close()
...版画...
---- out ----
[]
---- error ----
['Pseudo-terminal will not be allocated because stdin is not a terminal.\r\n', 'Permission denied, please try again.\r\n', 'Permission denied, please try again.\r\n', 'Permission denied (publickey,password,keyboard-interactive).\r\n']
疑似端末エラーは、元のコマンドの -t フラグを思い出させたので、Channel を使用する 2 番目の方法に切り替えました。ssh.exec_command 以降の代わりに、次のものがあります。
t = ssh.get_transport()
chan = t.open_session()
chan.get_pty()
print '---- send ssh cmd ----'
print chan.send('ssh luser@second.com')
print '---- recv ----'
print chan.recv(9999)
chan = t.open_session()
print '---- send password ----'
print chan.send('secret')
print '---- recv ----'
print chan.recv(9999)
...しかし、「---- send ssh cmd ----」と出力され、プロセスを強制終了するまでハングします。
私はPythonを初めて使用し、ネットワークについてあまり知識がありません。最初のケースでは、パスワードの送信がsudoでは機能するのにsshでは機能しないのはなぜですか? プロンプトは異なりますか?paramiko はこれに適したライブラリでもありますか?