5

Я хочу использовать 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 все прекрасно работает , каковы потенциальные причины? Спасибо!

3 ответа3

2

В стандартной конфигурации sudoers обычно присутствует следующая строка:

Defaults requiretty

Это и безопасно, и то, что вам нужно в большинстве случаев использования.

В вашем случае вам нужно переопределить это значение по умолчанию для конкретного пользователя, поэтому вы должны написать ниже:

Defaults:niky !requiretty

Также вам нужно определить строку, позволяющую niky вызывать sudo без пароля:

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

Эта строка означает, что пользователю niky разрешено выполнять /bin/ls от имени пользователя root на remote.nity.com без пароля.

Дальнейшая ссылка может быть найдена здесь.

1

К вашему сведению - может помочь вам в поиске - обратите внимание, что вы получите ту же ошибку в обычном SSH, если вы инкапсулируете одну команду SSH в другую, например:

localhost $ ssh user1@host1.example.com -C 'sudo su - другой пользователь ssh user2@host2.example2.com /run /this / исполняемый файл'

(Почему бы не SSH прямо к целевой коробке? Ну, может быть, ключи SSH установлены только между host1 и host2, или сеть маршрутизируется так, чтобы запретить доступ host2 без прохождения через host1. Может быть, вам не разрешено трогать sudoers или любой другой файл на host2 ... обычно в Production envs.).

В любом случае вы можете запускать команды, отличные от sudo, используя приведенное выше, но префикс sudo вызывает "отсутствие tty present".

Как вы можете исправить это с помощью голой команды SSH? Передайте -t, например: localhost $ ssh user1@host1.example.com -C 'sudo su - другой пользователь ssh -t user2@host2.example2.com /run /this / исполняемый файл'

Теперь удаленный sudo работает нормально внутри SSH, никаких претензий к tty. Это выделено.

Итак, вопрос в том, как можно эмулировать опцию "-t" внутри объекта Paramiko? Там твой ответ.

Этот блог пытается объяснить, но, возможно, мог бы потратить больше времени на пример 'sudo':http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

(Извиняюсь за мою точку зрения в правильном направлении вместо идеального ответа ... Я все еще ищу эту информацию на самом деле).

1

Две вещи, которые вы найдете полезными:

  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 .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .