paramiko
を使用してリモートノードの束にSSHで接続し、root
特権でコマンドラインを実行したい
ホームディレクトリにsshキーがあるので、これらのリモートノードにsshするときにパスワードを入力する必要はありません。
ただし、次のスクリプトを実行する場合:
def connect(hostname):
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username='niky', pkey=paramiko.RSAKey.from_private_key(open('id_rsa'), 'passwd'), timeout = 240.0) return ssh
def run(hostname):
ssh = connect(hostname)
(stdin, stdout, stderr) = ssh.exec_command("Sudo ls")
res = stderr.readlines()
print hostname+': '+''.join(str(elem) for elem in res)+'\n'
run(remote.nity.com)
次のエラーが発生しました:
remote.nity.com: Sudo: no tty present and no askpass program specified
Sudo
の前にls
を追加しない場合、すべてが正常に機能します。潜在的な理由は何ですか?ありがとう!
在庫のsudoers
構成では、通常、次の行が存在します。
_Defaults requiretty
_
これは安全であり、ほとんどのユースケースで必要なものです。
あなたの場合、特定のユーザーに対してこのデフォルトをオーバーライドする必要があるため、以下に記述します。
_Defaults:niky !requiretty
_
また、niky
がパスワードなしでSudo
を呼び出せるようにする行を定義する必要があります。
niky remote.nity.com = (root)NOPASSWD: /bin/ls
この行は、ユーザーniky
がパスワードを必要とせずに_/bin/ls
_のroot
として_remote.nity.com
_を実行できることを意味します。
詳細については、 ここ を参照してください。
参考までに-検索に役立つ場合があります-あるSSHコマンドを別のSSHコマンド内にカプセル化すると、プレーンSSHでも同じエラーが発生することに注意してください。例:
localhost $ ssh [email protected] -C'Sudo su-anotheruser ssh [email protected]/run/this/executeable '
(ターゲットボックスに直接SSHで接続しないのはなぜですか?SSHキーがHost1とHost2の間でのみ設定されているか、Host1を経由せずにHost2アクセスを禁止するようにネットワークがルーティングされている可能性があります。sudoersなどに触れることは許可されていませんHost2上の他のファイル...本番環境で一般的です。).
いずれの場合も、上記を使用してSudo以外のコマンドを実行できますが、Sudoを前に付けると「ttyが存在しません」。
ベアsshコマンドでこれをどのように修正しますか? -tを渡します。例:localhost $ ssh [email protected] -C'Sudo su --anotheruser ssh -t [email protected]/run/this/executeable '
これで、リモートSudoはSSH内で正常に実行され、ttyに関する苦情はありません。 -tはそれを割り当てました。
したがって、問題は、Paramikoオブジェクト内の「-t」オプションをどのようにエミュレートするかということです。あなたの答えがあります。
このブログは説明しようとしていますが、おそらく「Sudo」の例にもっと時間を費やした可能性があります: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
(完璧な答えではなく、正しい方向に向かっていることをお詫びします...私はまだ実際にその情報を探しています)。
あなたが役に立つと思う2つのこと:
exec_command
は、get_pty
のオプションの引数を取ります。次のように使用できます。
(stdin, stdout, stderr) = ssh.exec_command("Sudo ls", get_pty = True)
パスワードをstdin
にスローし、改行してフラッシュして、確実に配信されるようにします。これにより、要求された場合にパスワードを確実に受け取ることができます(実際に要求されたかどうかを確認するために、より高度な方法を実行できます...単にパスワードを投入するだけでは、まだ問題は発生していません)。
stdin.write('passwd' + '\n')
stdin.flush()
まとめると、これらはSudo
の問題をparamiko
で修正する必要があります。