保护 root 拥有的脚本免遭篡改,并使用 sudoers 的 NOPASSWD 进行无人值守运行

保护 root 拥有的脚本免遭篡改,并使用 sudoers 的 NOPASSWD 进行无人值守运行

/etc/sudoers授予非 root 用户(anyuser见下文)权限,使其能够使用 sudo 执行 root 拥有的脚本(test-script见下文),并NOPASSWD:设置标签。
该脚本的权限八进制值为。只有使用一个预定义参数(见下文)0550才有可能执行该脚本cache_bak当脚本文件未被篡改时。后者基于 SHA256 摘要条件执行是可能的(相关信息见sudoers手册页)。

事情进展顺利,...直到我测试修改脚本以获取不同的 SHA 摘要并查看如何sudoers处理它。

我所做的是:

$ cat /home/anyuser/Scripts/test-script
#!/bin/bash
/bin/mkdir -p /var/"$1"
/bin/cp -R /var/cache/* /var/"$1" # copies content of /var/cache/ 
                                  # to /var/$1, defined by script's lone arg 
exit $?
# End of test-script

$ sudo chmod 0550 /home/anyuser/Scripts/test-script
$ sudo chown root:admin /home/anyuser/Scripts/test-script
$ ls -lsAF test-*   # check
4 -r-xr-x--- 1 root admin   75 Apr 25 18:23 test-script*

$ cat /etc/group | grep sudo   # check
sudo:x:27:anyuser

$ sudo cat /etc/sudoers         # check
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults    insults
root    ALL = (ALL:ALL) ALL
%sudo   ALL = (root:ALL) ALL
%admin  ALL = (ALL:ALL) ALL
%wheel Somehost = (ALL:ALL) ALL
#includedir /etc/sudoers.d

然后我填充/etc/sudoers.d10_user,其内容是:

$ cat /etc/sudoers.d/10_user
Cmnd_Alias CPVARCACHE = sha256:48805bae82834f323xxxxxxxxxxxxx10145c7bbf80bae183b7de3ea52ef90637 /home/anyuser/Scripts/test-script cache_bak

# GROUP SPECS
%admin Somehost = NOPASSWD: /usr/bin/rsync

# USER SPECS
anyuser Somehost = (root) NOPASSWD: CPVARCACHE

一切运行良好,即无需输入密码,复制任务完成,直到我模拟篡改test-script。我通过添加一行代码来实现这一点,例如再次if [ "$1" ] ;then :; fi运行:sudo /home/anyuser/Scripts/test-script cache_bak

sudo shell 并没有像我预期的那样中止。相反,它检查 SHA 摘要是否已发生变化,并请求密码来anyuser执行该任务。但是,在这种情况下,我希望 cmd 行能够无人值守(安静地)中止。

尝试重定向stdoutstderr/dev/null:

# after modifying the script so its SHA digest is different from
#+ that in '/etc/sudoers.d/10_user'

$ sudo /home/anyuser/Scripts/test-script cache_bak > /dev/null 2>&1
[sudo] password for anyuser: _^C

以上仅重定向子 shell 进程的输出,而不是 sudo 进程的输出。

如果脚本被篡改,我需要中止 sudo 进程,大概是在启动脚本之前...我看到了一些有趣的东西(例如),但没有什么真正相关的内容……

答案1

我的解决方案直接改编自 MarcoS'回答StackOverflow 上是:

$ sudo -n /home/anyuser/Scripts/test-script cache_bak -- 2> sudo-stderr_"$(date+\%Y\%m\&d-\%H\%M\%S)".log

解释:
-n标志抑制了 sudo 的密码请求。因此 上不会显示任何内容stdout
如果仍然需要密码,sudo则在向 发送错误消息后正常终止stdderr。例如:

$ sudo -n ls
sudo: a password is required

紧接着sudo进程就死亡了。

要重定向sudostderr,首先在 sudo 后的 cmd 后添加--,以表示sudo停止将后面的内容解释为 cmd 行参数。 的重定向stderr通常用 表示,2>后跟临时日志文件名。

相关内容