如何防止在sudo中使用调用方的shell


8

我在CentOS 6.5上运行sudo-1.8.6。我的问题很简单:如何防止SHELL从用户环境传播到sudo环境?

通常人们会选择另一种方式-他们想要保留环境变量。但是,我的用户“ zabbix”的shell /sbin/nologin尝试通过sudo运行命令时遇到问题。Sudo保留,/sbin/nologin以便root无法运行子shell。(更新:这部分是正确的,但不是SHELL环境变量。这是从/ etc / passwd中提取的shell值。)

我提供了一个可以说明问题的测试;这不是我的实际用例,而只是说明保留了调用用户的SHELL。我有一个以用户身份运行的程序zabbix。它调用/usr/bin/sudo -u root /tmp/doit(程序作为zabbix守护程序运行,因此/sbin/nologin密码文件中的shell不会阻止它运行)。/tmp/doit是一个shell脚本,仅具有:

#!/bin/sh
env > /tmp/outfile

(模式显然是755)。在outfile我可以看到的SHELL/sbin/nologin。但是,此时脚本通过sudo以root身份运行,因此它不应该具有先前用户的环境变量,对吗?

这是我的/ etc / sudoers:

默认要求
默认值!visiblepw

默认为always_set_home
默认值env_reset
默认值env_keep =“颜色显示主机名历史记录输入INPUTRC KDEDIR LS_COLORS”
默认值env_keep + =“邮件PS1 PS2 QTDIR用户名LANG LC_ADDRESS LC_CTYPE”
默认值env_keep + =“ LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES”
默认值env_keep + =“ LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE”
默认值env_keep + =“ LC_TIME LC_ALL语言_UA_XKB_CHARSET XAUTHORITY”
默认值secure_path = / sbin:/ bin:/ usr / sbin:/ usr / bin:/ usr / local / bin:/ usr / local / sbin

##允许root在任何地方运行任何命令 
root ALL =(全部)全部

#includedir /etc/sudoers.d

这是我的/etc/sudoers.d/zabbix

默认值:zabbix!requiretty

zabbix ALL = {root} NOPASSWD:/ tmp / doit

编辑:更多信息:

运行sudo的进程是zabbix_agentdZabbix监视软件中的。文件中有一个条目,/etc/zabbix/zabbix_agentd.d/userparameter_disk.conf如下所示:

UserParameter = example.disk.discovery,/ usr / local / bin / zabbix_raid_discovery

/usr/local/bin/zabbix_raid_discovery是Python脚本。我已经对其进行了修改以仅执行此操作:

打印subprocess.check_output(['/ usr / bin / sudo','-u','root','/ tmp / doit'])

/tmp/doit 只是这样做:

#!/ bin / sh
环保>> / tmp / outfile

我在Zabbix服务器上运行以下命令以运行/usr/local/bin/zabbix_raid_discovery脚本:

zabbix_get -s client_hostname -k'example.disk.discovery'

然后,检查/tmp/outfile,然后看到:

SHELL = / sbin / nologin
TERM = Linux
USER =根
SUDO_USER = zabbix
SUDO_UID = 497
USERNAME =根
路径= / sbin:/ bin:/ usr / sbin:/ usr / bin:/ usr / local / bin:/ usr / local / sbin
邮件= / var / mail / root
PWD = /
LANG = zh_CN.UTF-8
SHLVL = 1
SUDO_COMMAND = / tmp / doit
HOME = / root
LOGNAME =根
SUDO_GID = 497
_ = / bin / env

那条SHELL线真的让我很烦。该文件归root用户所有,所以我知道它是由root用户创建的,但是shell来自调用用户(zabbix)。


是否在系统中sudo env SHELL=/bin/sh sh提供将/ bin / sh设置为SHELL变量的提示?

@adonis-看到我更新的问题。顺便说一句,你很帅。
Mike S

@BinaryZebra-是的,我知道env_delete,但是我同意这个问题的症结在于env_reset的默认行为...causes commands to be executed with a new, minimal environment.我们有一个带有PAM的linux系统,因此根据手册页The new environment contains the ... SHELL ... (variable)。从/etc/sudoers上面的文件中可以看到,我们不允许SHELL在中env_keep。因此,SHELL不应保留;我们应该具有root用户的SHELL
Mike S

@BinaryZebra-我已经添加zabbix ALL=(root) NOPASSWD: /bin/env SHELL=/bin/sh /tmp/doit *到我的/etc/sudoers/zabbix文件中,并且它具有正确的外壳。谢谢,我现在有一个解决方法。问题是,为什么我需要包括它?传递调用方的SHELL似乎很危险(而且很麻烦),但是我找不到设置sudo进行修改的地方。我已经奔跑了find /etc/sudoers /etc/sysconfig -type f -exec grep env_ {} \;,没有发现危险信号。/etc/sudoers包含唯一的env_字符串。因此,我认为没有sudoers国旗会干扰...
Mike S

Mike:在第一层:一个简单的用户sudo bash应该以root身份启动bash shell,并且必须将SHELL变量设置为/ etc / password中的值。您报告SHELL被设置为(或保留为)/sbin/nologin。这是一个安全问题,由root启动的shell不能由用户设置的环境变量控制。这是您必须调查的事情。

Answers:


5

然后答案是sudo有一个错误。首先,解决方法:我将其放入/etc/sudoers.d/zabbix file

zabbix ALL = {root} NOPASSWD:/ bin / env SHELL = / bin / sh / usr / local / bin / zabbix_raid_discovery

现在从zabbix_raid_discovery工作中调用子命令。

解决此问题的补丁将在sudo 1.8.15中。从维护者Todd Miller:

这只是“一向如此”的情况。没有
确实是一个很好的理由。下面的差异应该使行为
匹配文档。

 -托德

diff -r adb927ad5e86插件/sudoers/env.c
--- a / plugins / sudoers / env.c Tue Oct 06 09:33:27 2015 -0600
+++ b / plugins / sudoers / env.c Tue Oct 06 10:04:03 2015 -0600
@@ -939,8 +939,6 @@
            CHECK_SETENV2(“ USERNAME”,runas_pw-> pw_name,
                ISSET(didvar,DID_USERNAME),true);
        }其他{
-如果(!ISSET(didvar,DID_SHELL))
-CHECK_SETENV2(“ SHELL”,sudo_user.pw-> pw_shell,false,true);
            / *我们稍后将在def_set_logname情况下设置LOGNAME。* /
            如果(!def_set_logname){
                如果(!ISSET(didvar,DID_LOGNAME))
@@ -984,6 +982,8 @@
            如果(!env_should_delete(* ep)){
                如果(strncmp(* ep,“ SUDO_PS1 =”,9)== 0)
                    ps1 = * ep + 5;
+ else if(strncmp(* ep,“ SHELL =”,6)== 0)
+ SET(didvar,DID_SHELL);
                否则(strncmp(* ep,“ PATH =”,5)== 0)
                    SET(didvar,DID_PATH);
                否则(strncmp(* ep,“ TERM =”,5)== 0)
@@ -1039,7 +1039,9 @@
     如果(reset_home)
        CHECK_SETENV2(“ HOME”,runas_pw-> pw_dir,true,true);

-/ *如果未设置$ TERM和$ PATH的默认值,则为它们提供默认值。* /
+ / *如果未设置,请提供$ SHELL,$ TERM和$ PATH的默认值。* /
+如果(!ISSET(didvar,DID_SHELL))
+ CHECK_SETENV2(“ SHELL”,runas_pw-> pw_shell,false,false);
     如果(!ISSET(didvar,DID_TERM))
        CHECK_PUTENV(“ TERM = unknown”,false,false);
     如果(!ISSET(didvar,DID_PATH))

优秀的迈克!,感谢您的侦探工作。

迈克,您是否有可能将链接指向(未来?)补丁。

@BinaryZebra Diff在这里:sudo.ws/repos/sudo/rev/b77adbc08c91我还没有看到补丁。
Mike S

迈克:我相信您在吠错树。这里的关键点Provide default values for $SHELL, $TERM and $PATH if not set.是:... if not set.。sudo将保留任何设置的值。谁在设置SHELL?

@BinaryZebra-那不是我的阅读方式。未设置SHELL(默认情况下为env_reset)。由于未设置,旧代码说要使用sudo_user的pw条目。新代码说使用runas用户的pw条目。
Mike S

4

问题是关于我认为问题出在哪里,但事实证明,问题不是SHELL变量发生什么,而是sudo实际做什么。例如:

-bash-4.1 $ whoami
Testdude
-bash-4.1 $ grep testdude / etc / passwd
testdude:x:1001:10:Test dude:/ tmp:/ bin / bash
-bash-4.1 $ sudo环境
[sudo] testdude的密码: 
...
外壳= / bin / bash
...

到目前为止,一切都很好。...但是问题是sudo使用了调用者的外壳而不是被调用者的外壳,与文档相反。确实,如果我通过编辑/ etc / passwd来更改外壳程序,则可以看到sudo跟随调用方的外壳,而不是SHELL

-bash-4.1 $ grep root / etc / passwd
root:x:0:0:root:/ root:/ bin / bash
-bash-4.1 $ sudo sed -i -e'/ testdude / s / bash / sh /'/ etc / passwd
-bash-4.1 $ grep testdude / etc / passwd
testdude:x:1001:10:Test dude:/ tmp:/ bin / sh
-bash-4.1 $ sudo环境
...
SHELL = / bin / sh
...
-bash-4.1 $ export SHELL = /完全/无意义/路径
-bash-4.1 $ sudo环境
...
SHELL = / bin / sh
...

我无法使用,sudo -i因为我不想模拟初始登录。sudo -s只要我在sudoers文件中有正确的命令,它将起作用。但是,预期的行为(反映在手册页:“ The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables”中)是外壳程序被调用方的行为。如果你看一下PATHHOMELOGNAME,和USERsudo的变量env中,你会看到根本的东西。SHELL也应该是root的shell。

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.