为什么sudo会改变PATH?

时间:2008-11-03 00:05:44

标签: path environment-variables sudo

这是没有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中。 注意,   但是,实际的PATH   环境变量未被修改   并且不加改变地传递给程序   sudo执行。

17 个答案:

答案 0 :(得分:232)

这是许多发行版上的恼人的函数 sudo的一个特性

要在ubuntu上解决这个“问题”,我会这样做 我的〜/ .bashrc

中的以下内容
alias sudo='sudo env PATH=$PATH'

注意以上内容适用于不重置$ PATH的命令。 但是`su'重置它的$ PATH所以你必须使用-p告诉它不要。即:

sudo su -p

答案 1 :(得分:116)

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

  

默认值env_reset

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

  

默认值!secure_path

默认情况下启用secure_path。此选项指定在sudoing时使$ PATH成为什么。感叹号会禁用该功能。

答案 2 :(得分:32)

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

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

来自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.

用法示例:

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

更新

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.

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

默认情况下, 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}" 

答案 3 :(得分:17)

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


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

  

似乎Bug#20996仍然存在于此版本的sudo中。该   changelog说它可以在运行时被覆盖,但我还没有   发现了如何。

他们提到在你的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   其他非std二进制文件夹   路径。已经添加了我的   对/ etc / environment的要求我是   我遇到错误时感到很惊讶   运行它们时缺少命令   在sudo下......

     

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

     
      
  1. 使用“sudo -E”选项 - 无效。我现有的PATH仍然被sudo重置

  2.   
  3. 在/ etc / sudoers中将“Defaults env_reset”更改为“Defaults !env_reset” - 也无效(即使与sudo -E结合使用)

  4.   
  5. 在/ etc / sudoers中取消注释env_reset(例如“#Defaults env_reset”) - 也无效。

  6.   
  7. 将“Defaults env_keep += "PATH"”添加到/ etc / sudoers - 也无效。

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

答案 4 :(得分:13)

这似乎对我有用

sudo -i 

采用非sudo PATH

答案 5 :(得分:11)

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

(当然让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"

答案 6 :(得分: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:~$ 

终于在不使用黑客的情况下解决这个问题真是太好了。

答案 7 :(得分: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"

答案 8 :(得分:3)

只需在/ etc / sudoers

中注释掉“Defaults env_reset”

答案 9 :(得分: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"

关闭终端然后再打开。

答案 10 :(得分:2)

Secure_path是你的朋友,但是如果你想从secure_path中免除

sudo visudo

并追加

Defaults exempt_group=your_goup

如果您想免除一大堆用户创建一个组,请将所有用户添加到该组中,并将其用作您的exempt_group。 man 5 sudoers for more。

答案 11 :(得分: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"

答案 12 :(得分:1)

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

答案 13 :(得分:1)

您还可以在sudoers used目录中移动文件:

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

答案 14 :(得分:0)

呃,如果你不在你的路径上添加一些东西,那真的不是一个考验:

bill@bill-desktop:~$ ls -l /opt/pkg/bin
total 12
-rwxr-xr-x 1 root root   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# 

答案 15 :(得分:0)

当使用su或sudo定义ENV_SUPATH时,将重置PATH,并在/etc/login.defs中定义ENV_PATH

答案 16 :(得分: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$ 

这就是原因。我觉得你很清楚。