我有一个连接到我的服务器的蜂窝调制解调器,我想用它在固定电话中断时发送通知电子邮件。
为了很好地分离正常的网络访问和这种特殊的蜂窝调制解调器访问,我创建了一个网络命名空间,并在其中创建了网络设备作为唯一的设备。要让程序使用蜂窝调制解调器,我只需使用ip netns exec
.
问题是我希望允许任何用户在命名空间中运行他们希望运行的任何程序,但netns exec
需要 root 权限。我的解决方案如下:
/usr/local/sbin/_oob_shim:
#!/bin/sh
cmd_line="$@"
/bin/ip netns exec oob \
/usr/bin/sudo -u "#$SUDO_UID" -g "#$SUDO_GID" /bin/sh -c "$cmd_line"
/etc/sudoers:
ALL ALL=NOPASSWD: /usr/local/sbin/_oob_shim
我认为在没有 root 权限或不知道 root 密码的情况下运行 shim 的唯一方法是通过 sudo,并且我可以信任 sudo 将 $SUDO_UID 和 $SUDO_GID 设置为正确的值。
我是否面临重大风险?或者,我应该说我错过了任何明显的警告吗?
答案1
sh -c
我在您的代码中看到的唯一错误是,当您应该直接运行它时,您不必要地运行用户的命令。运行它sh -c
不会给你带来任何好处,但它会破坏用户最初输入命令的引用。例如,试试这个:
sudo /usr/local/sbin/_oob_shim ls -l "a b"
a b
应该列出一个在命名空间上下文中调用的文件,但它列出了两个名为a
和 的文件b
。
sudo /usr/local/sbin/_oob_shim ls -l "*"
应该列出一个名为*
(字面星号)的文件,但由于同样的原因而失败。
所以它应该看起来像这样:
#!/bin/sh
/bin/ip netns exec oob \
/usr/bin/sudo -u "#$SUDO_UID" -g "#$SUDO_GID" -- "$@"
使脚本启动更简单!
我可以指出的另一点是,尽管在这种情况下,该错误只是一个功能错误,而不是安全错误,但在审核安全敏感代码并发现它通过 shell 运行事物时,人们总是会感到怀疑,因为这几乎总是一个问题。
最后,用户的补充组不会传播到命名空间中(它们仅获得其 uid 和主 gid),但这似乎不是一个大问题,而且解决这个问题也不是小事。
除此之外,它对我来说看起来不错。