sudo为什么更改PATH?


281

这是PATH没有sudo 的变量:

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

这是PATHsudo 的变量:

$ 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上)。

更新:据我所知,没有一个脚本PATH以任何方式以root身份更改启动。

来自man sudo

为防止命令欺骗,当在用户PATH中搜索命令时(如果一个或两个都在PATH中),sudo会在最后检查``。''和``''(均表示当前目录)。但是请注意,实际的PATH环境变量不会被修改,并且会原样传递给sudo执行的程序。


root是否有任何在.bashrc中设置PATH的东西?这是假设由于您使用的是Linux,所以sh确实是bash。
格雷格(Greg Hewgill)

Answers:


241

这是 烦人的功能 功能须藤的许多分布。

要解决ubuntu上的“问题”,我在〜/ .bashrc中执行以下操作

alias sudo='sudo env PATH=$PATH'

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

sudo su -p

46
此“烦​​人功能”可防止您被木马感染。我说强制特定的$ PATH是一个功能,而不是错误-它使您可以写出$ PATH以外的程序的完整路径。
克里斯·杰斯特·杨

29
是的,但这完全违反直觉。它可能比坏人更愚弄好人。
布赖恩·阿姆斯特朗

31
它不仅违反直觉,而且记录错误。阅读sudo的手册页,并将配置与Fedora盒进行比较,我认为应该保留路径。实际上,“ sudo -V”甚至说“要保留的环境变量:PATH”。
詹森·库姆斯

6
它很烦人。期。如果它可以通过sudo“使您成为特洛伊木马”,那么没有它就可以使您成为特洛伊木马。当然,这很困难,但是如果您用普通用户从错误的位置运行代码,那么事情已经很糟糕了。
gcb 2012年

7
不要为sudo加上别名;请参阅@Jacob有关默认值env_reset的答案。
greg_1_anderson

121

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

默认值env_reset

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

默认值!secure_path

默认情况下启用secure_path。此选项指定在进行sudoing时使$ PATH生效的内容。感叹号将禁用该功能。


6
另一种方式:Defaults env_keep = "PATH"
gcb 2012年

1
默认值!secure_path在现代系统上对我来说非常有用;在旧的ubuntu 8.04机器上,默认设置env_keep =“ PATH”可以解决问题。
greg_1_anderson

29
可以禁用它而不是禁用secure_path。例如,在我的情况下,我添加了“ Defaults secure_path = / sbin:/ bin:/ usr / sbin:/ usr / bin:/ some / custom / directory”行,其中“ some / custom / directory”是我需要的路径提供给sudo。
赫克托·科雷亚

@HectorCorrea解决方案是IMO的更好方法。
chakrit

32

PATH 是环境变量,因此默认情况下由sudo重置。

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

man sudo

       -E -E(保留环境)选项将覆盖env_reset
           sudoers(5)中的选项)。仅当符合以下条件之一时才可用
           命令带有SETENV标记或在sudo-中设置了setenv选项
           ers(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}" 

17

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


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中与其他非std二进制文件夹一起运行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权限下运行非默认软件。



11

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

(当然,通过sudo重置PATH并不是解决这类问题的完整解决方案,但有帮助)

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

Defaults env_reset

在/ etc / sudoers中而不使用exempt_groupenv_keep

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

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

拥有sudoer帐户访问权限的攻击者甚至可能做得更糟。
user508546 2012年

一个体面的建议。在ubuntu 12.04服务器上,默认设置是类似设置。
Tsutomu

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

终于不用黑客就解决了这真是太好了。


4
也许您会考虑重写此内容,以指示具有Karmic全新安装的人如何更新其配置以解决此特定问题。
杰森·库姆斯

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"

3

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


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"

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


等待PATH需要2 **吗?为什么PATH需要**?
CMCDragonkai 2014年

@CMCDragonkai它被格式化为粗体(在markdown中),但是有人(堆栈溢出不会让我指责)对其进行编辑以将其标记为代码。
1j01 2015年

2

Secure_path是您的朋友,但是如果您想使自己免于secure_path,请执行

苏多维苏多

并追加

默认值exempt_group = your_goup

如果要豁免一群用户,请创建一个组,将所有用户添加到该组中,然后将其用作您的exempt_group。男人5个更多。


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"

1

注释掉/ etc / sudores文件中的“默认env_reset”和“默认secure_path ...”


1

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

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

0

嗯,如果您不向路径添加任何内容,那实际上不是测试:

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

0

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


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$ 

这就是原因。我认为这很清楚。

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.