我可以阻止结构提示我输入sudo密码吗?

时间:2010-09-17 16:06:18

标签: python sudo fabric

我正在使用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 个答案:

答案 0 :(得分:32)

尝试将shell=False传递给sudo。那样/ bin / bash就不会被添加到sudo命令中。 sudo('some_command', shell=False)

来自fabric/operations.py的第503行:

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))

答案 1 :(得分:13)

您可以使用:

fabric.api import env
# [...]
env.password = 'yourpassword'

答案 2 :(得分:13)

这是您问题的最直接答案:   你实际上没有问题;你误解了Fabric run()和sudo()是如何工作的。

您的“解决方法”不是解决方法,它是对问题的100%有效答案。

这是一套简单的规则: 1)当你不期望提示时使用“run()”。 2)当你期望提示时使用“sudo()”。 (对于需要提示的所有或大多数命令,这应该是正确的,即使有问题的可执行文件不是Bash或Sudo)。

同样的答案适用于试图在“sudo”下运行命令的人。即使sudoers在某些系统上为当前用户配置了无密码配置,如果你使用sudo()而不是run(),那么你将强制提示(除非Fabric代码已经包含ENV密码或密钥)。

BTW的作者在#IRC中回答了我的问题 - 与你的问题非常相似。好人,开源的无名英雄之一坚持他的Fabric和Paramiko工作。

...在我的测试环境中,总有一个用户名具有对sudo的完全无密码访问权限。输入sudo echo hello不会提示我。此外,该sudo用户配置了“!requiretty”,因此所有命令都可以通过SSH运行(如主机之间的SSH跳转)。这意味着我可以简单地使用“run()”来执行“sudo something”,但它只是另一个在没有提示的情况下运行的命令。就安全性而言,锁定生产主机而不是测试主机是某人的工作。 (如果您被迫通过并且无法自动化进行测试,那么这是一个很大的问题。)

答案 3 :(得分:6)

在/ etc / sudoers文件中添加

user ALL=NOPASSWD: some_command

其中user是你的sudo用户,some_command你要用fabric运行的命令,然后在fabric脚本上运行sudo it with shell = False:

sudo('some_command', shell=False)

这对我有用

答案 4 :(得分:2)

/etc/sudoers文件中,您可以添加

user ALL=NOPASSWD: /bin/bash

...其中user是您的Fabric用户名。

显然,只有拥有root访问权限才能执行此操作,因为/etc/sudoers只能由root写入。

同样显然,这并不是非常安全,因为能够执行/bin/bash会让您对任何内容开放,所以如果您没有root访问权限并且必须让系统管理员为您执行此操作,他们可能不会。

答案 5 :(得分:1)

Linux noob在这里,但我在尝试将石墨织物安装到EC2 AMI时发现了这个问题。 Fabric继续提示输入root密码。

实际的诀窍是将ssh私钥文件传递给fabric。

fab -i key.pem graphite_install -H root@servername

答案 6 :(得分:1)

您还可以为多台计算机使用密码:

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

答案 7 :(得分:0)

我最近遇到了同样的问题,发现Crossfit_and_Beer的answer令人困惑。

实现此目标的支持方式是使用env.sudo_prefixthis github commit(来自this PR

我的使用示例:

env.sudo_prefix = 'sudo '