293

This is the PATH variable without sudo:

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

This is the PATH variable with sudo:

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

As far as I can tell, sudo is supposed to leave PATH untouched. What's going on? How do I change this? (This is on Ubuntu 8.04).

UPDATE: as far as I can see, none of the scripts started as root change PATH in any way.

From man sudo:

To prevent command spoofing, sudo checks ``.'' and ``'' (both denoting current directory) last when searching for a command in the user's PATH (if one or both are in the PATH). Note, however, that the actual PATH environment variable is not modified and is passed unchanged to the program that sudo executes.

4

18 回答 18

248

This is an annoying function a feature of sudo on many distributions.

To work around this "problem" on ubuntu I do the following in my ~/.bashrc

alias sudo='sudo env PATH=$PATH'

Note the above will work for commands that don't reset the $PATH themselves. However `su' resets it's $PATH so you must use -p to tell it not to. I.E.:

sudo su -p
于 2008-11-03T00:51:10.947 回答
125

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

默认值 env_reset

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

默认值 !secure_path

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

于 2010-12-31T19:46:32.197 回答
33

PATH is an environment variable, and as such is by default reset by sudo.

You need special permissions to be permitted to do this.

From man sudo

       -E  The -E (preserve environment) option will override the env_reset
           option in sudoers(5)).  It is only available when either the match-
           ing command has the SETENV tag or the setenv option is set in sudo-
           ers(5).
       Environment variables to be set for the command may also be passed on
       the command line in the form of VAR=value, e.g.
       LD_LIBRARY_PATH=/usr/local/pkg/lib.  Variables passed on the command
       line are subject to the same restrictions as normal environment vari-
       ables with one important exception.  If the setenv option is set in
       sudoers, the command to be run has the SETENV tag set or the command
       matched is ALL, the user may set variables that would overwise be for-
       bidden.  See sudoers(5) for more information.

An Example of usage:

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

update

man 5 sudoers : 

     env_reset       If set, sudo will reset the environment to only contain
                       the LOGNAME, SHELL, USER, USERNAME and the SUDO_* vari-
                       ables.  Any variables in the caller's environment that
                       match the env_keep and env_check lists are then added.
                       The default contents of the env_keep and env_check
                       lists are displayed when sudo is run by root with the
                       -V option.  If sudo was compiled with the SECURE_PATH
                       option, its value will be used for the PATH environment
                       variable.  This flag is on by default.

So may need to check that this is/is not compiled in.

It is by default in 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}" 
于 2008-11-03T00:29:53.533 回答
18

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


Debian 错误 #85123(“sudo: SECURE_PATH 仍然不能被覆盖”)(从 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 错误 #50797(“使用 --with-secure-path 构建的 sudo 存在问题”)

更糟糕的是,据我所知,无法在 sudoers 文件中重新指定secure_path。因此,例如,如果您想让您的用户轻松访问 /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 错误 #192651(“始终重置 sudo 路径”)

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

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


Ubuntu 错误 #226595(“无法保留/指定 PATH”)

我需要能够在 PATH 中使用其他非标准二进制文件夹运行 sudo。已经将我的要求添加到 /etc/environment 后,当我在 sudo 下运行命令时遇到有关缺少命令的错误时,我感到很惊讶.....

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

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

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

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

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

显然 - 尽管有 man 文档 - sudo 关于 PATH 是完全硬编码的,并且在保留用户 PATH 方面不允许任何灵活性。非常烦人,因为我无法使用 sudo 在 root 权限下运行非默认软件。

于 2008-12-17T19:43:53.213 回答
14

这似乎对我有用

sudo -i 

它采用非 sudoPATH

于 2012-02-21T07:13:34.693 回答
11

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

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

这确实是您使用时会发生的情况

Defaults env_reset

在 /etc/sudoers 中不使用exempt_groupor env_keep

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

Defaults secure_path="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin"
于 2011-12-09T15:16:11.487 回答
7

现在使用来自业力存储库的 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 的情况下最终解决了这个问题真是太好了。

于 2009-07-02T06:54:12.903 回答
4
# 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"
于 2009-12-15T22:09:57.627 回答
3

只需env_keep编辑/etc/sudoers

它看起来像这样:

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"

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

于 2011-08-09T11:13:05.630 回答
3

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

于 2010-03-19T18:07:46.623 回答
2

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

须藤 visudo

并附加

默认值 exclude_group=your_goup

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

于 2010-06-29T00:40:20.653 回答
1

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

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"
于 2011-07-08T18:53:14.073 回答
1

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

于 2014-05-09T23:06:43.523 回答
1

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

    sudo mv $HOME/bash/script.sh /usr/sbin/ 
于 2015-03-25T17:24:59.330 回答
0

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

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#
于 2009-01-23T03:02:10.577 回答
0

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

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

于 2017-06-12T10:59:30.693 回答
0

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

于 2017-01-04T21:19:30.540 回答
0

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

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

# personal ls
usermod -a -G sudo ${USER}
/bin/ls

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

于 2021-11-28T20:15:54.930 回答