为什么sudo会改变路径?
为什么sudo会改变路径?
这是没有使用sudo时的PATH
变量:\n
$ echo 'echo $PATH' | sh /opt/local/ruby/bin:/usr/bin:/bin
\n这是使用sudo时的PATH
变量:\n
$ echo 'echo $PATH' | sudo sh /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin
\n据我所知,sudo
应该不会改变PATH
。发生了什么?我该如何更改?(这是在Ubuntu 8.04上)\n更新:据我的观察,没有一个以root身份启动的脚本会以任何方式改变PATH
。\n根据man sudo
:\n
\n为了防止命令欺骗,sudo在搜索用户的PATH时最后检查“.”和“”(都表示当前目录)(如果PATH中有一个或两个)。然而,实际的PATH环境变量不会被修改,并且不变地传递给sudo执行的程序。\n
为什么sudo会改变PATH?
sudo是一个用于以其他用户身份执行命令的工具。而PATH是一个环境变量,用于指定系统在哪些目录中查找可执行文件。sudo会重置环境变量,包括PATH。
sudo重置PATH的原因是为了安全考虑。当使用sudo执行命令时,为了避免潜在的安全风险,sudo会重置环境变量,只保留一些必要的变量。这样可以防止用户通过修改环境变量来执行恶意命令。
然而,有时候我们确实需要在sudo环境中保留原来的PATH。为了实现这个目的,我们可以使用sudo的-E选项,该选项会覆盖sudoers文件中的env_reset选项,从而保留环境变量。
除了使用-E选项外,我们还可以在命令行中直接传递环境变量。例如,可以使用VAR=value的形式来设置环境变量,如LD_LIBRARY_PATH=/usr/local/pkg/lib。需要注意的是,通过命令行传递的环境变量与普通环境变量一样受到限制,除非sudoers文件中设置了setenv选项,或者命令拥有SETENV标签,或者匹配的命令是ALL,否则用户是不能设置被禁止的变量的。
下面是一个使用示例:
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命令查看sudoers文件的说明。其中,env_reset选项用于设置sudo是否重置环境变量。如果env_reset选项被设置了,sudo将只保留LOGNAME、SHELL、USER、USERNAME和SUDO_*这几个变量,并根据env_keep和env_check列表添加其他指定的变量。默认情况下,sudo会将SECURE_PATH选项的值用于PATH环境变量。这个选项默认是开启的。
因此,需要检查系统是否编译了SECURE_PATH选项。在Gentoo系统中,默认是开启的。可以通过查看构建脚本来确认是否启用了SECURE_PATH选项。
,sudo会改变PATH环境变量是为了安全考虑。但是我们可以通过使用sudo的-E选项或在命令行中传递环境变量来保留原来的PATH。
为什么sudo会改变PATH?
有时候我们希望禁用所有用户的路径变量更改,解决方法如下:
1. 使用命令visudo
来访问sudoers文件。
2. 在文件中找到以下行:
Defaults env_reset
3. 在该行的下一行添加以下内容:
Defaults !secure_path
secure_path默认是启用的,这个选项指定了在sudo时要设置的$PATH值。感叹号禁用了该功能。
另外一种方法是:Defaults env_keep = "PATH"
在现代系统上,Defaults !secure_path对我来说效果很好;在一个旧的Ubuntu 8.04系统上,Defaults env_keep = "PATH"解决了问题。
除了禁用secure_path,你还可以添加路径到它中。例如,我添加了以下行:
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/some/custom/directory
其中,"some/custom/directory"是我需要在sudo中使用的路径。
解决方案中IMO较好的一种方式是添加路径到secure_path中。
sudo更改PATH的原因是为了阻止被木马植入。这一功能可以强制用户在执行程序时使用完整路径,从而增加安全性。然而,这也可能会给用户带来不便,因为他们需要写出完整的路径名。
为了解决这个问题,可以在用户的~/.bashrc文件中添加以下命令:
alias sudo='sudo env PATH=$PATH'
这个命令会在执行sudo时将当前用户的PATH环境变量传递给sudo。
然而,这个解决方法并不适用于那些会重置PATH的命令,比如su命令。对于这种情况,需要使用-p选项来告知su命令不要重置PATH。例如:
sudo su -p
需要注意的是,这种解决方法可能会导致一些问题,比如"sudo -s"命令无法正常工作。
有人认为这一功能不仅令人不便,而且文档中的解释也不正确。根据sudo的man页面以及与Fedora系统的比较,人们认为sudo应该保留PATH环境变量。然而,实际情况并非如此。
另外,有人建议不要使用alias来解决这个问题,而是使用默认的env_reset选项。
总之,sudo更改PATH的原因是为了增加安全性,避免被木马植入。然而,这也可能给用户带来不便。为了解决这个问题,可以使用alias命令将当前用户的PATH环境变量传递给sudo,但这种解决方法可能会导致其他问题。另外,也可以使用默认的env_reset选项来解决这个问题。