允许任何用户在特定网络命名空间中运行程序的安全方式

Mic*_*ick 9 networking sudo network-namespaces

我有一个连接到我的服务器的蜂窝调制解调器,我想用它作为固定电话断线时获取通知电子邮件的一种方式。

为了很好地分离正常的网络访问和这种特殊的蜂窝调制解调器访问,我创建了一个网络命名空间并在那里创建了网络设备作为唯一的设备。要让程序使用蜂窝调制解调器,我只需使用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"
Run Code Online (Sandbox Code Playgroud)

/etc/sudoers:

ALL ALL=NOPASSWD: /usr/local/sbin/_oob_shim
Run Code Online (Sandbox Code Playgroud)

我认为在尚未成为 root 或知道 root 密码的情况下运行 shim 的唯一方法是通过 sudo,我可以相信 sudo 将 $SUDO_UID 和 $SUDO_GID 设置为正确的值。

我是否让自己面临重大风险?或者,我应该说我错过了任何明显的警告吗?

Cel*_*ada 7

我在您的代码中看到的唯一错误是,sh -c当您应该直接运行它时,您却不必要地运行了用户的命令。运行它sh -c不会给你带来任何好处,但它会破坏用户最初放入命令中的引用。例如,试试这个:

sudo /usr/local/sbin/_oob_shim ls -l "a b"
Run Code Online (Sandbox Code Playgroud)

应该列出a b在命名空间上下文中调用的文件,但它列出了两个名为a和 的文件b

sudo /usr/local/sbin/_oob_shim ls -l "*"
Run Code Online (Sandbox Code Playgroud)

应该列出一个名为*(字面星号)的文件,由于同样的原因失败。

所以它应该看起来像这样:

#!/bin/sh
/bin/ip netns exec oob \
    /usr/bin/sudo -u "#$SUDO_UID" -g "#$SUDO_GID" -- "$@"
Run Code Online (Sandbox Code Playgroud)

使脚本更易于启动!

我可以提出的另一点是,尽管在这种情况下,错误只是一个功能错误,而不是安全错误,但在审核安全敏感代码并发现它通过 shell 运行时总是可疑的,因为这几乎总是一个问题。

最后,用户的补充组不会传播到命名空间(他们只得到他们的 uid 和主 gid),但这似乎不是一个大问题,修复这不是微不足道的。

除此之外,它对我来说看起来不错。