web-dev-qa-db-ja.com

使用python Paramiko for ssh:Sudo:ttyが存在せず、askpassプログラムが指定されていません

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を追加しない場合、すべてが正常に機能します。潜在的な理由は何ですか?ありがとう!

5
misteryes

在庫のsudoers構成では、通常、次の行が存在します。

_Defaults requiretty_

これは安全であり、ほとんどのユースケースで必要なものです。

あなたの場合、特定のユーザーに対してこのデフォルトをオーバーライドする必要があるため、以下に記述します。

_Defaults:niky !requiretty_

また、nikyがパスワードなしでSudoを呼び出せるようにする行を定義する必要があります。

niky remote.nity.com = (root)NOPASSWD: /bin/ls

この行は、ユーザーnikyがパスワードを必要とせずに_/bin/ls_のrootとして_remote.nity.com_を実行できることを意味します。

詳細については、 ここ を参照してください。

2
dawud

参考までに-検索に役立つ場合があります-ある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/

(完璧な答えではなく、正しい方向に向かっていることをお詫びします...私はまだ実際にその情報を探しています)。

1
Scott Prive

あなたが役に立つと思う2つのこと:

  1. exec_commandは、get_ptyのオプションの引数を取ります。次のように使用できます。

    (stdin, stdout, stderr) = ssh.exec_command("Sudo ls", get_pty = True)
    
  2. パスワードをstdinにスローし、改行してフラッシュして、確実に配信されるようにします。これにより、要求された場合にパスワードを確実に受け取ることができます(実際に要求されたかどうかを確認するために、より高度な方法を実行できます...単にパスワードを投入するだけでは、まだ問題は発生していません)。

    stdin.write('passwd' + '\n')
    stdin.flush()
    

まとめると、これらはSudoの問題をparamikoで修正する必要があります。

1
ArtOfWarfare