经过多次令人沮丧的头砖墙接触后,我发现了这一点:
$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/steve/bin
$ sudo bash
# echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
但
$ sudo bash -c 'echo $PATH'
/sbin:/bin:/usr/sbin:/usr/bin
$ sudo bash -Ec 'echo $PATH'
/sbin:/bin:/usr/sbin:/usr/bin
我收集自另一个帖子路径sudo
是从读取的/etc/sudoers
- 但为什么呢?设置是否$PATH
有意义/root/.profile
,或者这只是造成上述混乱的一个原因(即,生成一个实际的 shell 会导致$PATH
与临时sudo
命令中使用的不同......)?
我在 RHEL 6.4 上使用 bash。
答案1
保护措施
sudo
具有内置保护,您在运行其中几个命令时会注意到。这些保护措施可以做很多事情,例如强制执行安全$PATH
。
从/etc/sudoers
文件中:
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
这是您运行命令时显示的内容sudo -c ....
。您可以通过-E
切换到 来禁用此行为sudo
。
笔记:对于某些设置,该-E
开关将不起作用。要“解决”它,您可以使用sudo env "PATH=$PATH" bash
.这也会将您$PATH
当前的电流转移到您的sudo
环境中。
交互与登录
当您运行此命令时:
$ sudo bash
您运行的是交互式bash
shell 与登录bash
shell。这与bash
配置文件的来源有关。
- 互动,又名
bash
或bash -i
, 来源$HOME/.bashrc
- 登录,又名
bash -l
, 来源$HOME/.bash_profile
那么为什么不起作用呢-E
?
TylerRick 对这个问题的回答(sudo 更改路径 - 为什么?)涵盖了很多原因。主要是它在sudo
编译时通常是硬编码的,就像 Ubuntu 的情况一样,导致这些开关毫无用处。 Launchpad 中长期以来一直存在与这些相关的未解决问题,并且从未得到解决,这让我们意识到 Canonical 认为最好将此行为保留为默认行为。
答案2
当规则sudoers
授权用户运行特定命令时wibble
,通常需要设置PATH
一个安全值:仅包含用户无法植入自己的程序的目录。如果wibble
调用外部命令foo
,并且PATH
没有重置,那么用户可以~/bin
在其前面放置PATH
, 链接/bin/sh
到~/bin/foo
,然后运行sudo wibble
以调用~/bin/foo
,这让他可以键入任意 shell 命令。
因此,重置 PATH 是安全的默认设置。虽然并非在所有情况下都需要这样做,但将其设为默认设置会更容易、更安全。
当规则sudoers
授权用户运行任意命令时,重置 PATH 没有直接的安全优势。还有一个间接的好处,即用户可能不小心设置了包含潜在有害程序的 PATH,而重置 PATH 可以避免这些程序被意外调用的风险。还有一个功能优势:以 root 身份运行命令时通常需要有/usr/local/sbin
,/usr/sbin
和/sbin
,但作为普通用户则不需要。
如果您不希望在运行时重置路径sudo
,请将自己添加到以下位置的豁免组中sudoers
:
Defaults exempt_group+=stevebennet
如果您运行登录 shell(sudo -I
或sudo bash -l
其他方法),该 shell 通常会读取.profile
目标用户的主目录,并且该文件可能会更改 PATH。
答案3
这是出于安全原因。 PATH 设置为明确定义的路径,而不是源用户可能拥有的任何被黑客攻击的 PATH。
看https://superuser.com/questions/98686/passing-path-through-sudo作为一种解决方法。