我在 CentOS 6.5 上运行 sudo-1.8.6。我的问题很简单:如何防止 SHELL 从用户环境传播到 sudo 环境?
通常人们会采取另一种方式——他们想要保留环境变量。但是,我遇到一个问题,我的用户“zabbix”的 shell 尝试/sbin/nologin
通过 sudo 运行命令。 Sudo 正在保留,/sbin/nologin
以便 root 无法运行子 shell。(更新:这部分是正确的,但它不是 SHELL 环境变量。问题是从 /etc/passwd 中提取的 shell 值。)
我提供了一个可以说明问题的测试;这不是我的真实用例,但它只是说明调用用户的 SHELL 被保留。我有一个以 user 身份运行的程序zabbix
。它调用(作为守护进程/usr/bin/sudo -u root /tmp/doit
运行的编程,因此密码文件中的 shell 不会阻止它)。是一个 shell 脚本,它只包含:zabbix
/sbin/nologin
/tmp/doit
#!/bin/sh
env > /tmp/outfile
(显然它的模式是755)。在outfile
我可以看到的SHELL
是/sbin/nologin
。但是,此时脚本正在通过 sudo 以 root 身份运行,因此它不应该具有先前用户的环境变量,对吧?
这是我的 /etc/sudoers:
默认值要求 默认值 !visiblepw 默认值always_set_home 默认值 env_reset 默认值 env_keep = "颜色显示主机名 HISTSIZE INPUTRC KDEDIR LS_COLORS" 默认值 env_keep += "MAIL PS1 PS2 QTDIR 用户名 LANG LC_ADDRESS LC_CTYPE" 默认值 env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASURMENT LC_MESSAGES" 默认值 env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" 默认值 env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" 默认 secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin ## 允许 root 在任何地方运行任何命令 根全部=(全部)全部 #includedir /etc/sudoers.d
这是我的/etc/sudoers.d/zabbix
:
默认值:zabbix !requiretty zabbix ALL=(root) NOPASSWD: /tmp/doit
编辑:更多信息:
运行sudo的进程是zabbix_agentd
,来自Zabbix监控软件。文件中有一个条目/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脚本。我已将其修改为简单地执行此操作:
print 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 术语=Linux 用户=root SUDO_USER=zabbix 苏多_UID=497 用户名=root PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin 邮件=/var/mail/root 密码=/ LANG=en_US.UTF-8 SLVL=1 SUDO_COMMAND=/tmp/doit 首页=/根目录 日志名称=根 SUDO_GID=497 _=/bin/env
那条SHELL
线真让我烦恼。该文件由 root 用户拥有,因此我知道它是由 root 用户创建的,但 shell 来自调用用户 ( zabbix
)。
答案1
那么答案是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 2015 年 10 月 6 日星期二 -0600 +++ b/plugins/sudoers/env.c 2015 年 10 月 6 日星期二 10:04:03 -0600 @@ -939,8 +939,6 @@ CHECK_SETENV2("用户名", runas_pw->pw_name, ISSET(didvar, DID_USERNAME), true); } 别的 { - if (!ISSET(didvar, DID_SHELL)) - CHECK_SETENV2("SHELL", sudo_user.pw->pw_shell, false, true); /* 我们稍后将在 def_set_logname 情况下设置 LOGNAME。 */ if (!def_set_logname) { if (!ISSET(didvar, DID_LOGNAME)) @@ -984,6 +982,8 @@ if (!env_should_delete(*ep)) { if (strncmp(*ep, "SUDO_PS1=", 9) == 0) ps1 = *ep + 5; + else if (strncmp(*ep, "SHELL=", 6) == 0) + SET(didvar, DID_SHELL); 否则 if (strncmp(*ep, "PATH=", 5) == 0) SET(didvar, DID_PATH); 否则 if (strncmp(*ep, "TERM=", 5) == 0) @@ -1039,7 +1039,9 @@ 如果(重置主页) CHECK_SETENV2("HOME", runas_pw->pw_dir, true, true); - /* 如果未设置 $TERM 和 $PATH,则为它们提供默认值。 */ + /* 如果未设置,则为 $SHELL、$TERM 和 $PATH 提供默认值。 */ + if (!ISSET(didvar, DID_SHELL)) + CHECK_SETENV2("SHELL", runas_pw->pw_shell, false, false); if (!ISSET(didvar, DID_TERM)) CHECK_PUTENV("TERM=未知", false, false); if (!ISSET(didvar, DID_PATH))
答案2
问题是我认为问题出在哪里,但事实证明问题不在于 SHELL 变量发生了什么,而是 sudo 实际做了什么。例如:
-bash-4.1$ whoami 测试哥们 -bash-4.1$ grep testdude /etc/passwd testdude:x:1001:10:测试哥们:/tmp:/bin/bash -bash-4.1$ sudo 环境 [sudo] testdude 的密码: ... 外壳=/bin/bash ...
到目前为止,一切都很好。 ...但问题是 sudo 使用调用者的 shell 而不是被调用者,这与文档相反。事实上,如果我通过编辑 /etc/passwd 来更改 shell,您可以看到 sudo 遵循调用者的 shell,而不是SHELL
:
-bash-4.1$ grep root /etc/passwd 根:x:0:0:根:/根:/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:测试哥们:/tmp:/bin/sh -bash-4.1$ sudo 环境 ... 外壳=/bin/sh ... -bash-4.1$ 导出SHELL=/完全/无意义/路径 -bash-4.1$ sudo 环境 ... 外壳=/bin/sh ...
我无法使用,sudo -i
因为我不想模拟初始登录。sudo -s
只要 sudoers 文件中有正确的命令,就可以工作。然而,预期的行为(如手册页中所反映的:“ The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables
”)是 shell 是被调用者的。如果您查看sudo env 的PATH
、HOME
、LOGNAME
和USER
变量,您将看到 root 的内容。SHELL
也应该是 root 的 shell。