Python 我可以防止 Fabric 提示我输入 sudo 密码吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3737003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:30:00  来源:igfitidea点击:

Can I prevent fabric from prompting me for a sudo password?

pythonsudofabric

提问by mipadi

I am using Fabricto run commands on a remote server. The user with which I connect on that server has some sudo privileges, and does not require a password to use these privileges. When SSH'ing into the server, I can run sudo blahand the command executes without prompting for a password. When I try to run the same command via Fabric's sudofunction, I get prompted for a password. This is because Fabric builds a command in the following manner when using sudo:

我正在使用Fabric在远程服务器上运行命令。我在该服务器上连接的用户具有一些 sudo 权限,并且不需要密码即可使用这些权限。当通过 SSH 连接到服务器时,我可以运行sudo blah并执行命令而不提示输入密码。当我尝试通过 Fabric 的sudo函数运行相同的命令时,系统会提示我输入密码。这是因为 Fabric 在使用时以下列方式构建命令sudo

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

Obviously, my user does not have permission to execute /bin/bashwithout a password.

显然,我的用户无权在/bin/bash没有密码的情况下执行。

I've worked around the problem by using run("sudo blah")instead of sudo("blah"), but I wondered if there is a better solution. Is there a workaround for this issue?

我已经通过使用run("sudo blah")代替解决了这个问题sudo("blah"),但我想知道是否有更好的解决方案。这个问题有解决方法吗?

采纳答案by Sam Dolan

Try passing shell=Falseto sudo. That way /bin/bash won't be added to the sudo command. sudo('some_command', shell=False)

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

From line 503 of fabric/operations.py:

fabric/operations.py 的第 503 行:

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

the else block looks like this:

else 块看起来像这样:

                                             # V-- here's where /bin/bash is added
real_command = '%s %s "%s"' % (sudo_prefix, env.shell,
    _shell_escape(cwd + command))

回答by CanSpice

In your /etc/sudoersfile, you could add

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

user ALL=NOPASSWD: /bin/bash

...where useris your Fabric username.

...user您的 Fabric 用户名在哪里。

Obviously, you can only do this if you have root access, as /etc/sudoersis only writable by root.

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

Also obviously, this isn't terribly secure, as being able to execute /bin/bashleaves you open to essentially anything, so if you don't have root access and have to ask a sysadmin to do this for you, they probably won't.

同样显然,这不是非常安全,因为能够执行/bin/bash让您基本上可以接受任何东西,所以如果您没有 root 访问权限并且必须要求系统管理员为您执行此操作,他们可能不会。

回答by sebastian serrano

In your /etc/sudoers file add

在您的 /etc/sudoers 文件中添加

user ALL=NOPASSWD: some_command

where user is your sudo user and some_command the command you want to run with fabric, then on the fabric script run sudo it with shell=False:

其中 user 是您的 sudo 用户, some_command 是您要使用 Fabric 运行的命令,然后在 Fabric 脚本上使用 shell=False 运行 sudo 它:

sudo('some_command', shell=False)

this works for me

这对我有用

回答by fiat

Linux noob here but I found this question while trying to install graphite-fabric onto an EC2 AMI. Fabric kept prompting for a root password.

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

The evntual trick was to pass in the ssh private key file to fabric.

最终的技巧是将 ssh 私钥文件传递给结构。

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

回答by Gabriel Gcia Fdez

You can use:

您可以使用:

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

回答by Dave Halter

You can also use passwords for multiple machines:

您还可以对多台机器使用密码:

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

See this answer: https://stackoverflow.com/a/5568219/552671

看到这个答案:https: //stackoverflow.com/a/5568219/552671

回答by Scott Prive

This is the most direct answer to your question: You do not actually have a problem; you misunderstand how Fabric run() and sudo() work.

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

Your "workaround" is NOT a workaround it is the 100% valid answer to the problem.

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

Here's a simple set of rules: 1) Use "run()" when you don't expect a prompt. 2) use "sudo()" when you do expect a prompt. (this should be true for all or most commands requiring a prompt, even if the executable in question is not Bash or Sudo).

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

This same answer applies to folks trying to run commands under "sudo". Even if sudoers has passwordless config for the current user on some system, if you use sudo() instead of run() then you will force a prompt (unless the Fabric code already contains an ENV password or key).

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

BTW the author of Fabric answered my question - very similar to your question - in #IRC. Nice guy, one of the unsung heroes of open source for persisting in his Fabric and Paramiko work.

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

...In my test environment, there is always 1 username which has full password-less access to sudo. Typing sudo echo hellowill not prompt me. Furthermore, that sudo user is configured with "!requiretty" so all commands can run over SSH (like SSH hopping between hosts). This means I can simply use "run()" with to execute "sudo something", but it's just another command which runs without a prompt. As far as security is concerned, it is someone's job to lock down a production host but not a test host. (If you are being forced to test things by and and can not automate, that is a huge problem).

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

回答by lingfish

I recently faced this same issue, and found Crossfit_and_Beer's answerconfusing.

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

A supported way to achieve this is via using env.sudo_prefix, as documented by this github commit(from this PR)

实现这一点的一种受支持的方法是通过 using env.sudo_prefix如此 github 提交(来自此 PR)所述

My example of use:

我的使用示例:

env.sudo_prefix = 'sudo '