通过sudo和su运行时,为什么PATH变量不同?


39

在我的fedora VM上,使用用户帐户运行时/usr/local/bin,我的路径是:

[justin@justin-fedora12 ~]$ env | grep PATH
 PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin

同样在运行时su

[justin@justin-fedora12 ~]$ su -
Password: 
[root@justin-fedora12 justin]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin

但是,当通过运行时sudo,该目录不在路径中:

[root@justin-fedora12 justin]# exit
[justin@justin-fedora12 ~]$ sudo bash
[root@justin-fedora12 ~]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/bin:/usr/sbin:/usr/bin

为什么通过via运行时路径会有所不同sudo



Answers:


37

看一看/etc/sudoers。Fedora(以及RHEL,Ubuntu和类似版本)中的默认文件包括以下行:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

这可以确保在sudo下运行二进制文件时路径是干净的。这有助于避免该问题中提到的一些担忧。它也方便,如果你没有/sbin/usr/sbin你自己的路。


啊,我在档案中看到了。所以,这不是我想要的,但是如果我添加/usr/local/bin到该指令,那么在通过运行时,在路径中看到它sudo,对吗?
贾斯汀·埃斯蒂尔

我只是尝试过,现在我明白了/usr/local/bin。非常感谢您对此进行解释!
贾斯汀·埃斯蒂尔

如何为脚本和二进制文件添加用户的路径,这样就不必在必须添加sudo例如脚本~/bin(或使用的任何路径)的情况下编写绝对路径了?我刚刚进行了更改-它起作用了,只是认为可能会有不利的一面?
伊曼纽尔·伯格

@mattdm是的,Ubuntu也是如此,因为我在玩VM时在Ubuntu Vivid中遇到了这个问题。对于Debian也是一样
kenorb

9

该命令su -将执行root用户配置文件,并采用该用户的环境(包括路径等)sudo不执行该操作。

如果您想sudo表现得像,su -那么请使用sudo -i [command将执行用户个人资料的选项

如果您想su -表现得像那样,sudo则不要使用连字符-只需使用su [command]


2

您可以通过运行来检查原因(不同)sudo sudo -V

例如在Linux上运行:

$ sudo sudo -V | grep PATH
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

注意:在macOS / BSD上,只需运行:sudo sudo -V

由于某些Linux发行版中的默认安全策略插件,因此上述列表受到限制。


man sudoers以下内容中进一步解释:

如果secure_path设置了该选项,则其值将用于PATH环境变量。

secure_path-用于从sudo运行的每个命令的路径。如果您不信任运行sudo的人员拥有健全的PATH环境变量,则可能要使用此变量。

另一个用途是,如果要将“根路径”与“用户路径”分开。该exempt_group选项指定的组中的用户不受的影响secure_path。默认情况下未设置此选项。

如果是这种情况,您可以通过运行sudo visudo和编辑配置文件并修改您的secure_path(添加以分隔的额外路径:)或将用户添加到其中来更改它exempt_group(这样您就不会受到secure_path选项的影响)。

或者为了传递用户的PATH临时权限,可以运行:

sudo env PATH="$PATH" my_command

您可以通过以下方式进行检查:

sudo env PATH="$PATH" env | grep ^PATH

另请参阅:如何制作sudo蜜饯$PATH


环境对于可能有所不同的另一个原因sudo是,您可以env_resetsudoers文件中启用选项。这将导致在新的最小环境中执行命令。

因此,您可以使用env_keepoption(出于安全原因不推荐使用)来保留用户的环境变量:

Defaults        env_reset
Defaults        env_keep += "PATH PYTHONPATH"

1

在大多数Linux中,您可以通过软件包管理来安装程序,并以常规方式获取更新。如果您安装了一些规避软件包管理的软件,它将安装在/ usr / local / bin中(例如,或... / sbin或/ opt),并且不会得到定期更新。

因此,我认为这些程序不被认为具有这种安全性,并且默认情况下不将其放入根PATH中。


+1-很酷,我想知道为什么它不在路上,这是有道理的。对于它的价值,我是从头开始构建node.js来使用它的,所以这很有意义,为什么会把它放在这里,以及为什么sudo默认情况下会排除此目录。
贾斯汀·埃斯蒂尔

@Justin Ethier:没话题了,但请参见bugzilla.redhat.com/show_bug.cgi?id=634911
mattdm

1

我只是亲自尝试了一下,却没有看到您看到的行为-我的路径保持不变,所以您的sudo配置可能不同。如果您检查man sudoers一下,就会看到有一个名为secure_path重置的选项PATH-听起来好像这个选项可能已经启用。


有趣。这是在Fedora 12上进行的,它的价值……
Justin Ethier

1

因为当您使用时sudo bashbash不会充当登录​​外壳。再试一次,sudo bash -l您应该会看到与相同的结果su -

如果这是正确的,那么在差别PATH在于配置文件:/etc/profile~/.bash_profile~/.bash_login~/.profile是为登录shell执行(按顺序),而~/.bashrc针对非登录交互式shell执行。


0

我知道有个老问题,但是由于我正在研究这个确切的问题,所以我现在偶然在这里。

由于某种原因/usr/local/bin,仅当通过成为root时才位于PATH中sudo su -。使用sudo -i时不存在。当然,现在我知道可以将其添加到/ etc / sudoers中,但这仍然无法解释为什么它已经存在于此之后su -。PATH的这部分来自哪里?

经过大量的反复搜索之后,我找到了答案:

包含'/ usr / local / bin'的默认路径实际上是在su(1)中硬编码的。

因此,没有pam配置,配置文件,bashrc或任何东西负责选择性地添加此元素。su接管时总是已经在那里。而且由于sudo根本不调用su而是使用其自己的配置,因此在sudo -i

我发现这在RHEL6和RHEL7上是正确的。我没有检查任何其他版本或发行版。


不要问我如何验证此方法。好吧,如果您坚持要说的话:我对su二进制文件的副本进行了十六进制编辑,然后更改/usr/local/bin为其他内容并调用了该副本。我的PATH现在包含修改过的字符串...好孩子和非懒惰的sysadmins当然只需下载源代码并在此处检查。;-)
奥斯卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.