如何让sudo保留我的环境变量?


45

在Solaris 5.10上使用sudo 1.7.4p4,在RHEL4 u6上使用sudo 1.6.7p5我看不到如何保存我的环境变量,例如$ PYTHONPATH。我已将此行添加到sudoers,但它没有任何区别:

Defaults !env_reset

我做错了什么,或者sudo安装是否只是不尊重env_reset标志?

编辑: 至少在Solaris上,我们发现这个问题取决于shell!如果我们在sudo下运行bash,标准的root shell就是Bourne( sudo bash 另一方面,!env_preset将保留环境(包括PATH和LD_LIBRARY_PATH)。这是我不得不说的相当混乱的行为。


Answers:


42

谨慎使用,sudo和变量存在安全问题。

man sudoers 我发现你应该使用

Defaults        env_reset
Defaults        env_keep += "PYTHONPATH OTHERVARIABLE YETANOTHER"

在Ubuntu, sudo 确实保留了一些变量。 sudo -i 更像是以root身份登录然后运行命令。 两者都可能不方便,前者为 sudo nano myfile 将根拥有的文件留在你的家里,而后者则留给你 sudo -i nano myfile 将尝试打开/ root / myfile。


sudo printenv PATH

看看它给了什么。在这里给出

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

例如。现在跑 sudo visudo 并添加该行

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

替换你之前发现的东西。如果需要,可以为其添加新路径。

关于图书馆:

sudo LD_LIBRARY_PATH=/usr/lib/path/to/a/safe/library your command

Linux发行版需要很多 关心 PATH,在玩它之前你应该小心。 添加路径时要特别小心“ . “ 要么 /home/username,这是不安全的。

添加路径的一个危险是它打开了这些路径上的文件被执行的可能性 root,打开可能被恶意软件利用的系统安全窗口。可能还有其他危险。只要确保你知道自己在做什么。通过传递 sudo 安全措施可能使您的Solaris像Windows XP一样安全。


谢谢你的建议。至少在Solaris上,似乎env_keep只能部分工作,因为它忽略了PATH和LD_LIBRARY_PATH。也许sudo是使用设置使其拒绝保留“危险”变量?
aknuds1

它是否适用于另一种可用的,如AKNUDS?你也可以运行sudo sudo -V(是的,两次sudo!)并看看它说的是什么。上面的解决方案适用于PYTHONPATH,但PATH看起来很特别。真正的问题是PATH。在Ubuntu中,他们建立sudo故意重置PATH。
user39559

env_keep为我保留了PYTHONPATH和HOME,因此显然有一些过滤正在进行中。
aknuds1

在你修改过的解决方案中,你建议我通过修改secure_path来硬连接sudo PATH,对吧?我不认为我想这样做。我们可能接近于我的问题的答案;我认为sudo是为忽略reset_env而构建的,并且在使用env_keep指定时忽略PATH和LD_LIBRARY_PATH等变量。我想我可以不在sudo下保留PATH / LD_LIBRARY_PATH,这不是什么大问题,但知道为什么它不起作用仍然很有趣:)
aknuds1

它不起作用,因为 sudo 作家小心翼翼地阻止你这样做。您不希望加载恶意库,因为它们是在sudo使用的路径中找到的。所以,这就是重置的原因。如果您要编写要由root运行的内容,请将它们复制到相应的系统目录中。
user39559

8

摆弄 sudoers 正如其他人所说的那样,要谨慎行事。

对于想要保留特定环境变量的简单案例,更简单的方法是直接通过sudo传递您想要的环境变量(这显示为 [VAR=value] 在sudo cmdline帮助)。

看到这个小例子,我也为多个变量演示了它。

$ export MY_V1=1
$ export MY_V2=2
$ printenv | grep MY_V
MY_V2=2
MY_V1=1
$ sudo MY_V1=$MY_V1 MY_V2=$MY_V2 printenv | grep MY_V
MY_V2=2
MY_V1=1

对于原始 PYTHONPATH 问题中的示例,只需使用以下内容:

$ sudo PYTHONPATH=$PYTHONPATH python some_script.py
<script_output_here>

为这类事物创建别名非常方便。像这样:

$ alias sudopy='sudo PYTHONPATH=$PYTHONPATH'

3

您的 Defaults !env_reset 看起来不错,假设你还没有用sudo调用sudo -E 选项。

您可以尝试完全删除该条目。

你确认你正在编辑正确的sudoers文件吗?我猜它可能是 /etc/sudoers 要么 /usr/local/etc/sudoers 取决于它的安装方式。你用它编辑了吗? visudo

你是怎么运行sudo的? sudo pythonsudo susudo su -sudo -s还有什么?只要 sudo pythonsudo su 会保护你的环境。

是什么 env | grep PYTHONPATH 说?如果没有,请确保通过运行导出PYTHONPATH export PYTHONPATH 然后再试一次。

是什么 sudo env | grep PYTHONPATH 说?如果它打印出预期值,则其他东西会覆盖您的PYTHONPATH值。也许是root的.bashrc或.bash_profile或系统范围的配置文件。


1
我很确定我正在编辑正确的sudoers,安装前缀对应于sudo。我正在运行sudo作为“sudo su”。不幸的是,几天后我将不得不回复你的其他建议。谢谢!
aknuds1

1
尝试更改一个不重要的设置,如 editor 要么 passprompt 看看你是否有正确的文件。或者使用strace,dtrace,truss或类似文件,查看它打开的文件。
Mikel

环境| grep PYTHONPATH,因为我的用户打印了期望的值,但在sudo下,没有打印任何内容。编辑sudoers,我可以通过修改“env_keep”来确保保留PYTHONPATH。但是,env_keep不会保留PATH或LD_LIBRARY_PATH。我想sudo有一个安全限制,不保留像PATH和LD_LIBRARY_PATH这样的变量?也许构建时间设置?
aknuds1

1
!据我所知,env_reset被忽略,但明天我可以仔细检查。我很确定env_delete没有被设置,但我也可以检查一下。
aknuds1

1
我已经确认了!env_reset被忽略,并且没有设置env_delete。
aknuds1

-1

根据 LD_LIBRARY_PATH的Ubuntu文档

您必须使用/etc/ld.so.conf.d/*.conf配置文件

然后:

  1. 添加一个 ld.so 配置文件 /etc/ld.so.conf.d/ 与你的道路 LD_LIBRARY_PATH

  2. 更新缓存:

    sudo ldconfig -v
    

很好,但问题不在于Ubuntu。提示:下次查看问题下的标签。
DavidPostill
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.