Могу ли я запретить ткани запрашивать пароль sudo? - PullRequest
48 голосов
/ 17 сентября 2010

Я использую Fabric для запуска команд на удаленном сервере. Пользователь, с которым я соединяюсь на этом сервере, имеет некоторые привилегии sudo и не требует пароля для использования этих привилегий. При подключении SSH к серверу я могу запустить sudo blah, и команда выполняется без запроса пароля. Когда я пытаюсь выполнить ту же команду с помощью функции Fabric sudo, у меня запрашивается пароль. Это связано с тем, что Fabric использует команду следующим образом при использовании sudo:

sudo -S -p <sudo_prompt> /bin/bash -l -c "<command>"

Очевидно, мой пользователь не имеет разрешения на выполнение /bin/bash без пароля.

Я обошел проблему, используя run("sudo blah") вместо sudo("blah"), но мне было интересно, есть ли лучшее решение. Есть ли решение этой проблемы?

Ответы [ 8 ]

32 голосов
/ 17 сентября 2010

Попробуйте передать shell=False в sudo.Таким образом / bin / bash не будет добавлен в команду sudo.sudo('some_command', shell=False)

Из строки 503 fabric / operations.py :

if (not env.use_shell) or (not shell):
    real_command = "%s %s" % (sudo_prefix, _shell_escape(command))

блок else выглядит следующим образом:

                                             # V-- here's where /bin/bash is added
real_command = '%s %s "%s"' % (sudo_prefix, env.shell,
    _shell_escape(cwd + command))
13 голосов
/ 19 ноября 2013

Это самый прямой ответ на ваш вопрос: у вас на самом деле нет проблем;вы не понимаете, как работают Fabric run () и sudo ().

Ваш «обходной путь» НЕ является обходным путем, это 100% правильный ответ на проблему.

Вот простой набор правил: 1) Используйте «run ()», когда вы не ожидаете приглашения.2) используйте «sudo ()», когда ожидаете приглашения.(это должно быть верно для всех или большинства команд, требующих приглашения, даже если рассматриваемый исполняемый файл не является Bash или Sudo).

Этот же ответ применяется к людям, пытающимся запускать команды под "sudo".Даже если у sudoers есть конфигурация без пароля для текущего пользователя в какой-либо системе, если вы используете sudo () вместо run (), вы вызовете запрос (если код Fabric уже не содержит пароль или ключ ENV).

Кстати, автор Fabric ответил на мой вопрос - очень похожий на ваш вопрос - в #IRC.Хороший парень, один из незамеченных героев открытого источника сохраняющихся в его ткани и Paramiko работе.

... В моей тестовой среде всегда есть 1 имя пользователя с полным доступом без пароля к sudo.Ввод sudo echo hello не подскажет мне.Кроме того, этот пользователь sudo настроен на "! Requiretty", поэтому все команды могут выполняться по SSH (например, переключение SSH между хостами).Это означает, что я могу просто использовать «run ()» для выполнения «sudo что-то», но это просто другая команда, которая запускается без приглашения.Что касается безопасности, то чья-то задача - заблокировать производственный хост, но не тестовый хост.(Если вас заставляют что-то проверять, а вы не можете автоматизировать, это огромная проблема).

13 голосов
/ 13 мая 2013

Вы можете использовать:

fabric.api import env
# [...]
env.password = 'yourpassword'
6 голосов
/ 04 октября 2011

В вашем файле / etc / sudoers добавьте

user ALL=NOPASSWD: some_command

где user - ваш пользователь sudo, а some_command - команда, которую вы хотите запустить с fabric, затем на сценарии fabric запустите sudo it с shell = False:

sudo('some_command', shell=False)

это работает для меня

2 голосов
/ 17 сентября 2010

В вашем /etc/sudoers файле вы можете добавить

user ALL=NOPASSWD: /bin/bash

... где user - ваше имя пользователя Fabric.

Очевидно, что вы можете сделать это, только если у вас есть root-доступ, так как /etc/sudoers доступен для записи только root.

Также очевидно, что это не очень безопасно, так как возможность выполнения /bin/bash оставляет вас открытым практически для всего, поэтому, если у вас нет доступа с правами root и вам нужно попросить системного администратора сделать это за вас, вероятно, не будет.

1 голос
/ 28 сентября 2013

Вы также можете использовать пароли для нескольких машин:

from fabric import env
env.hosts = ['user1@host1:port1', 'user2@host2.port2']
env.passwords = {'user1@host1:port1': 'password1', 'user2@host2.port2': 'password2'}

См. Этот ответ: https://stackoverflow.com/a/5568219/552671

1 голос
/ 27 августа 2012

Linux noob здесь, но я нашел этот вопрос, пытаясь установить графитовую матрицу на ECI AMI.Fabric продолжает запрашивать пароль root.

Необычный трюк заключался в передаче файла закрытого ключа ssh в Fabric.

fab -i key.pem graphite_install -H root@servername
0 голосов
/ 29 октября 2016

Недавно я столкнулся с этой же проблемой и обнаружил, что Crossfit_and_Beer answer сбивает с толку.

Поддерживаемый способ достижения этого - использование env.sudo_prefix, как описано в этого коммита github (из это PR )

Мой пример использования:

env.sudo_prefix = 'sudo '
...