为啥 sudo 会更改 PATH?

Posted

技术标签:

【中文标题】为啥 sudo 会更改 PATH?【英文标题】:Why does sudo change the PATH? [closed]为什么 sudo 会更改 PATH? 【发布时间】:2010-09-20 10:24:09 【问题描述】:

这是不带 sudo 的 PATH 变量:

$ echo 'echo $PATH' | sh 
/opt/local/ruby/bin:/usr/bin:/bin

这是带有 sudo 的 PATH 变量:

$ echo 'echo $PATH' | sudo sh
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

据我所知,sudo 应该保持 PATH 不变。这是怎么回事?我该如何改变? (这是在 Ubuntu 8.04 上)。

更新:据我所知,没有任何脚本以 root 更改 PATH 开始。

来自man sudo

为了防止命令欺骗,sudo 检查 ``.'' 和 ``'' (都表示 当前目录)搜索时最后 对于用户路径中的命令(如果 一个或两个都在 PATH 中)。 注意, 但是,实际的 PATH 环境变量未修改 并原封不动地传递给程序 sudo 执行。

【问题讨论】:

root 是否有任何东西可以在 .bashrc 中设置 PATH?这是假设由于您使用的是 Linux,因此 sh 确实是 bash。 unix.stackexchange.com/questions/83191/… || unix.stackexchange.com/questions/8646/… || superuser.com/questions/98686/passing-path-through-sudo 【参考方案1】:

这是 sudo 在许多发行版上的一个烦人的功能 一个特性

要在 ubuntu 上解决这个“问题”,我会 我的 ~/.bashrc 中的以下内容

alias sudo='sudo env PATH=$PATH'

请注意,以上内容适用于不会自行重置 $PATH 的命令。 但是 'su' 将它重置为 $PATH,因此您必须使用 -p 告诉它不要这样做。即:

sudo su -p

【讨论】:

这个“烦人的功能”可以防止你被木马感染。我说强制一个特定的 $PATH 是一个特性,而不是一个错误——它让你写出一个在 $PATH 之外的程序的完整路径。 是的,但这完全违反直觉。它可能比坏人更愚弄好人。 这不仅违反直觉,而且记录不正确。阅读 sudo 的手册页,并将配置与 Fedora 盒子进行比较,我认为应该保留路径。事实上,“sudo -V”甚至说“要保留的环境变量:PATH”。 这很烦人。时期。如果它可以通过 sudo '让你被木马感染',它可以让你在没有它的情况下被同样的木马感染。理所当然,更难,但如果你在错误的地方运行代码,即使是你的普通用户,那么事情已经够糟糕了。 不要别名 sudo;请参阅@Jacob 关于默认值 env_reset 的回答。【参考方案2】:

如果其他人在此运行并只想禁用所有用户的所有路径变量更改。 使用命令:visudo 访问您的 sudoers 文件。您应该在某处看到以下行:

默认 env_reset

你应该在下一行添加以下内容

默认值 !secure_path

secure_path 默认启用。此选项指定在 sudoing 时生成 $PATH 的内容。感叹号禁用该功能。

【讨论】:

另一种方式:Defaults env_keep = "PATH" Defaults !secure_path 在现代系统上对我来说非常有用;在旧的 ubuntu 8.04 机器上,默认值 env_keep = "PATH" 成功了。 您可以添加到它而不是禁用secure_path。例如,在我的情况下,我添加了行“Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/some/custom/directory”,其中“some/custom/directory”是我需要的路径提供给 sudo。 @HectorCorrea 解决方案是 IMO 的更好方法。【参考方案3】:

PATH 是一个环境变量,因此默认由 sudo 重置。

您需要获得特殊权限才能执行此操作。

来自man sudo

-E -E(保留环境)选项将覆盖 env_reset sudoers(5) 中的选项)。它仅在匹配时可用- ing 命令具有 SETENV 标记或在 sudo- 中设置了 setenv 选项 人(5)。 为命令设置的环境变量也可以传递 VAR=value 形式的命令行,例如 LD_LIBRARY_PATH=/usr/local/pkg/lib.命令传递的变量 线受到与正常环境变量相同的限制 除了一个重要的例外。如果 setenv 选项设置在 sudoers,要运行的命令设置了 SETENV 标记或命令 匹配为 ALL,用户可能会设置过度适用的变量 - 投标。有关详细信息,请参阅 sudoers(5)。

使用示例:

cat >> test.sh
env | grep "MYEXAMPLE" ;
^D
sh test.sh 
MYEXAMPLE=1 sh test.sh
# MYEXAMPLE=1
MYEXAMPLE=1 sudo sh test.sh 
MYEXAMPLE=1 sudo MYEXAMPLE=2 sh test.sh 
# MYEXAMPLE=2

更新

男人 5 sudoers : env_reset 如果设置,sudo 会将环境重置为仅包含 LOGNAME、SHELL、USER、USERNAME 和 SUDO_* 变量 能。调用者环境中的任何变量 然后添加匹配 env_keep 和 env_check 列表。 env_keep 和 env_check 的默认内容 当 sudo 由 root 运行时显示列表 -V 选项。如果 sudo 是使用 SECURE_PATH 编译的 选项,其值将用于 PATH 环境 多变的。该标志默认开启。

因此可能需要检查它是否已编译。

默认在 Gentoo

# ( From the build Script )
....
ROOTPATH=$(cleanpath /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/bin$ROOTPATH:+:$ROOTPATH)
....
econf --with-secure-path="$ROOTPATH" 

【讨论】:

【参考方案4】:

看起来这个错误已经存在了很长一段时间了!以下是一些您可能会觉得有帮助的错误参考(并且可能想要订阅/投票、提示、提示...):


Debian bug #85123 ("sudo: SECURE_PATH still can't be overridden") (from 2001!)

这个版本的 sudo 中似乎仍然存在 Bug#20996。这 更改日志说它可以在运行时被覆盖,但我还没有 发现了如何。

他们提到在你的 sudoers 文件中添加这样的内容:

Defaults secure_path="/bin:/usr/bin:/usr/local/bin"

但是当我至少在 Ubuntu 8.10 中这样做时,它给了我这个错误:

visudo: unknown defaults entry `secure_path' referenced near line 10

Ubuntu bug #50797 ("sudo built with --with-secure-path is problematic")

更糟糕的是,据我所知,它 无法重新指定secure_path 在 sudoers 文件中。所以如果,对于 例如,您想为您的用户提供 轻松访问 /opt 下的内容, 你必须重新编译 sudo。


是的。 需要有一种方法 覆盖此“功能”而无需 重新编译。没有比这更糟糕的了 安全偏执者告诉你什么是 最适合您的环境,然后不是 为您提供关闭它的方法。


这真的很烦人。有可能 明智的做法是保持当前行为 出于安全原因默认,但 应该有一种方法可以覆盖它 除了从源代码重新编译 代码!很多人都需要 PATH 遗产。我想知道为什么没有 维护人员对其进行了调查,这似乎 容易想出一个可以接受的 解决方案。


我是这样解决它的:

mv /usr/bin/sudo /usr/bin/sudo.orig

然后创建一个包含以下内容的文件 /usr/bin/sudo:

#!/bin/bash
/usr/bin/sudo.orig env PATH=$PATH "$@"

那么您的常规 sudo 就像非安全路径 sudo 一样工作


Ubuntu bug #192651 ("sudo path is always reset")

鉴于此错误的副本是 最初于 2006 年 7 月提交,我不是 清除无效的 env_keep 多长时间 一直在运行。不管是什么 强迫用户雇佣的好处 上面列出的技巧, 当然是 sudo 的手册页和 sudoers 应该反映这样一个事实: 修改 PATH 的选项是 实际上是多余的。

修改文档以反映 实际执行不会破坏稳定 并且很有帮助。


Ubuntu bug #226595 ("impossible to retain/specify PATH")

我需要能够运行 sudo 其他非标准二进制文件夹 路径。已经添加了我的 我对 /etc/environment 的要求 当我收到错误时感到惊讶 运行时缺少命令 在 sudo 下.....

我尝试了以下方法来解决这个问题 没有成功:

    使用“sudo -E”选项 - 不起作用。我现有的 PATH 仍然由 sudo 重置

    在 /etc/sudoers 中将“Defaults env_reset”更改为“Defaults !env_reset”也不起作用(即使与 sudo -E 结合使用)

    在 /etc/sudoers 中取消注释 env_reset(例如“#Defaults env_reset”)也不起作用。

    将“Defaults env_keep += "PATH"”添加到 /etc/sudoers -- 也不起作用。

显然——尽管这个人 文档 - sudo 完全是 关于 PATH 的硬编码,而不是 允许关于任何灵活性 保留用户路径。非常 烦人,因为我无法运行非默认值 root权限下的软件使用 须藤。

【讨论】:

【参考方案5】:

这似乎对我有用

sudo -i 

采用非sudo PATH

【讨论】:

'sudo -i' 在 Ubuntu 上没有帮助(我检查了 Ubuntu 14.04.3 LTS)。 $PATH 仍然被 sudo 修改。【参考方案6】:

我认为让 sudo 重置 PATH 实际上是可取的:否则入侵您的用户帐户的攻击者可能会将各种工具的后门版本放在用户的 PATH 上,并且在使用 sudo 时会执行它们。

(当然,让 sudo 重置 PATH 并不能完全解决这类问题,但它会有所帮助)

这确实是你使用时会发生的事情

Defaults env_reset

在 /etc/sudoers 中不使用 exempt_groupenv_keep

这也很方便,因为您可以将只对 root 有用的目录(例如 /sbin/usr/sbin)添加到 sudo 路径,而无需将它们添加到用户的路径中。指定 sudo 使用的路径:

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

【讨论】:

获得 sudoer 帐户访问权限的攻击者可以做更糟糕的事情。 一个不错的建议。在 ubuntu 12.04 服务器上,类似的设置是默认设置。【参考方案7】:

现在使用 karmic 存储库中的 sudo 工作。我的配置中的详细信息:

root@sphinx:~# cat /etc/sudoers | grep -v -e '^$' -e '^#'
Defaults    env_reset
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/grub-1.96/sbin:/opt/grub-1.96/bin"
root    ALL=(ALL) ALL
%admin ALL=(ALL) ALL
root@sphinx:~# cat /etc/apt/sources.list
deb http://au.archive.ubuntu.com/ubuntu/ jaunty main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ jaunty main restricted universe

deb http://au.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe

deb http://security.ubuntu.com/ubuntu jaunty-security main restricted universe
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted universe

deb http://au.archive.ubuntu.com/ubuntu/ karmic main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ karmic main restricted universe

deb http://au.archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe

deb http://security.ubuntu.com/ubuntu karmic-security main restricted universe
deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted universe
root@sphinx:~# 

root@sphinx:~# cat /etc/apt/preferences 
Package: sudo
Pin: release a=karmic-security
Pin-Priority: 990

Package: sudo
Pin: release a=karmic-updates
Pin-Priority: 960

Package: sudo
Pin: release a=karmic
Pin-Priority: 930

Package: *
Pin: release a=jaunty-security
Pin-Priority: 900

Package: *
Pin: release a=jaunty-updates
Pin-Priority: 700

Package: *
Pin: release a=jaunty
Pin-Priority: 500

Package: *
Pin: release a=karmic-security
Pin-Priority: 450

Package: *
Pin: release a=karmic-updates
Pin-Priority: 250

Package: *
Pin: release a=karmic
Pin-Priority: 50
root@sphinx:~# apt-cache policy sudo
sudo:
  Installed: 1.7.0-1ubuntu2
  Candidate: 1.7.0-1ubuntu2
  Package pin: 1.7.0-1ubuntu2
  Version table:
 *** 1.7.0-1ubuntu2 930
         50 http://au.archive.ubuntu.com karmic/main Packages
        100 /var/lib/dpkg/status
     1.6.9p17-1ubuntu3 930
        500 http://au.archive.ubuntu.com jaunty/main Packages
root@sphinx:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/grub-1.96/sbin:/opt/grub-1.96/bin
root@sphinx:~# exit
exit
abolte@sphinx:~$ echo $PATH
/home/abolte/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/grub-1.96/sbin:/opt/grub-1.96/bin:/opt/chromium-17593:/opt/grub-1.96/sbin:/opt/grub-1.96/bin:/opt/xpra-0.0.6/bin
abolte@sphinx:~$ 

很高兴最终在不使用 hack 的情况下解决了这个问题。

【讨论】:

也许您会考虑重写此代码,以表明拥有干净 Karmic 安装的人如何更新其配置以解决此特定问题。【参考方案8】:
# cat .bash_profile | grep PATH
PATH=$HOME/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
export PATH

# cat /etc/sudoers | grep Defaults
Defaults    requiretty
Defaults    env_reset
Defaults    env_keep = "SOME_PARAM1 SOME_PARAM2 ... PATH"

【讨论】:

【参考方案9】:

只需在 /etc/sudoers 中注释掉“Defaults env_reset”

【讨论】:

【参考方案10】:

只需在/etc/sudoers 中编辑env_keep

看起来像这样:

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASURE MENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL L ANGUAGE LINGUAS XDG_SESSION_COOKIE"

只需在末尾附加 PATH,因此更改后将如下所示:

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASURE MENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL L ANGUAGE LINGUAS XDG_SESSION_COOKIE PATH"

关闭终端,然后再次打开。

【讨论】:

等待 PATH 需要 2 **?为什么 PATH 需要**? @CMCDragonkai 它被格式化为粗体(在降价中),但有人(堆栈溢出不会让我指指点点)编辑它以将其标记为代码。【参考方案11】:

Secure_path 是你的朋友,但如果你想从 secure_path 中豁免,就这样做

须藤 visudo

并追加

默认值 exclude_group=your_goup

如果您想豁免一群用户,请创建一个组,将所有用户添加到其中,并将其用作您的 exclude_group。 man 5 sudoers 更多。

【讨论】:

【参考方案12】:

OpenSUSE 发行版的 cmets 中推荐的解决方案建议更改:

Defaults env_reset

到:

Defaults !env_reset

然后大概注释掉以下不需要的行:

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASURE    MENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL L    ANGUAGE LINGUAS XDG_SESSION_COOKIE"

【讨论】:

【参考方案13】:

注释掉 /etc/sudores 文件中的“Default env_reset”和“Default secure_path ...”都对我有用

【讨论】:

【参考方案14】:

您还可以将文件移动到 sudoers 使用的目录中:

    sudo mv $HOME/bash/script.sh /usr/sbin/ 

【讨论】:

【参考方案15】:

呃,如果你不向你的路径添加一些东西,这并不是一个真正的测试:

bill@bill-desktop:~$ ls -l /opt/pkg/bin 共 12 个 -rwxr-xr-x 1 根根 28 2009-01-22 18:58 foo bill@bill-desktop:~$ which foo /opt/pkg/bin/foo bill@bill-desktop:~$ sudo su root@bill-desktop:/home/bill# which foo root@bill-desktop:/home/bill#

【讨论】:

【参考方案16】:

使用 su 或 sudo 时 PATH 将根据 ENV_SUPATH 的定义以及 /etc/login.defs 中定义的 ENV_PATH 进行重置

【讨论】:

【参考方案17】:

$PATH 是一个环境变量,这意味着 $PATH 的值可能因其他用户而异。

当您登录系统时,您的配置文件设置决定了 $PATH 的值。

现在,让我们看看:-

User       |        Value of $PATH
--------------------------
root                /var/www
user1               /var/www/user1
user2               /var/www/html/private

假设这些是不同用户的 $PATH 值。现在,当您使用 sudo 执行任何命令时,实际上 root 用户执行该命令。

您可以通过在终端上执行这些命令来确认:-

user@localhost$ whoami
username
user@localhost$ sudo whoami
root
user@localhost$ 

这就是原因。我想你很清楚。

【讨论】:

【参考方案18】:

这可能违反直觉,但第一次发生在我身上时,我就知道发生了什么。相信我,你不希望 root 运行别人的 PATH

“嘿,root?你能帮帮我吗,出了点问题”,他走过来,从我的 shell 中执行 sudo,我写了一个“$HOME/bin/ls”shell 脚本,它首先给了我超级用户权限,然后调用真正的/bin/ls。

个人信息

usermod -a -G sudo $USER /bin/ls

root 用户在我的 shell 中执行“sudo ls”,他已经完成了,盒子对我来说是敞开的。

【讨论】:

以上是关于为啥 sudo 会更改 PATH?的主要内容,如果未能解决你的问题,请参考以下文章

使用 sudo 运行时找不到命令

为啥更改 innerText 值也会更改 innerHTML?

为啥在其中创建新文件时目录的更改时间(ctime)会更改?

为啥我的 UICollectionViewCells 在动画超级视图约束更改时会更改 alpha 值?

为啥覆盖会更改列名

为啥从内部组件中更改 @Input 变量会导致它无法检测到来自外部组件的新更改?