Docker 运行具有 NET_ADMIN 功能的应用程序:涉及风险

Docker 运行具有 NET_ADMIN 功能的应用程序:涉及风险

我正在尝试在 docker 容器中运行应用程序。该应用程序需要 root 权限才能运行。

sudo docker run --restart always --network host --cap-add NET_ADMIN -d -p 53:53/udp my-image

我的问题是:将 NET_ADMIN 功能与 --network host 选项一起添加时有哪些风险。

如果攻击者能够以某种方式从我的应用程序中获取一些代码执行,那么他是否拥有无限的权力,因为我以 root 身份运行它,或者他只能访问内核的网络部分?如果是这样,他的攻击面是什么(换句话说,他可以仅使用 NET_ADMIN 功能集在我的主机操作系统上获得 root 权限吗?)

答案1

Q1.攻击者能否仅使用 NET_ADMIN 功能获得我的主机操作系统的 root 权限?

是的(在某些情况下)。

CAP_NET_ADMIN允许您SIOCETHTOOL在命名空间内的任何网络设备上使用 ioctl()。这包括诸如ETHTOOL_FLASHDEVie 之类的命令ethtool -f

这就是游戏。下面的引用中有更多解释。

SIOCETHTOOL允许在任何网络命名空间内,因为提交 5e1fccc0bfac,“net:允许用户根控制网络堆栈的核心”。在此之前,只能CAP_NET_ADMIN在“根”网络命名空间中进行。这很有趣,因为当时指出了安全考虑。我看了一下内核版本5.0中的代码,我相信以下评论仍然适用:

回复:[PATCH net-next 09/17] net:允许用户根控制网络堆栈的核心。

出于同样的原因,您最好根据 per-user_ns 选择性地选择允许哪些 ethtool 命令CAP_NET_ADMIN。首先考虑一下:

ETHTOOL_SEEPROM=> 使 NIC 变砖
ETHTOOL_FLASHDEV=> 使 NIC 变砖;如果系统不使用 IOMMU,则拥有该系统

默认情况下无法访问真实硬件,从而避免了这些问题。物理网络接口必须移至网络命名空间中才能访问它。

是的,我意识到这一点。问题是您是否期望容器中的任何内容都能够执行这些操作,即使分配了物理网络设备也是如此。

实际上,在不考虑容器的情况下,我们也有同样的问题——CAP_NET_ADMIN仅仅因为它是网络硬件,就真的应该给你对硬件的低级控制吗?我认为其中一些 ethtool 操作以及对非标准 MDIO 寄存器的访问可能需要额外的功能(CAP_SYS_ADMINCAP_SYS_RAWIO?)。

我猜是封锁功能也有类似的问题。我在搜索时没有注意到结果中的锁定补丁。我认为锁定功能的解决方案是某种数字签名,类似于锁定仅允许签名的内核模块。

Q2。如果他们以某种方式从我的应用程序中获得一些代码执行,他们会拥有无限的权力吗?

我将其分为一个更窄的情况,特定于您的命令 -

sudo docker run --restart always --network host --cap-add NET_ADMIN -d -p 53:53/udp my-image

除了功能之外,该docker命令还应该施加 seccomp 限制。如果您的系统(SELinux 或 AppArmor)上可用,它还可能施加基于 LSM 的限制。然而,这些似乎都不适用于SIOCETHTOOL

我认为seccomp-bpf可以用来阻止SIOCETHTOOL。但是,那docker 的默认 seccomp 配置不会尝试过滤任何 ioctl() 调用。

我在查看的内核函数中没有注意到任何 LSM 挂钩。


我认为本·哈钦斯(Ben Hutchings)提出了一个很好的观点;理想的解决方案是将其限制为CAP_SYS_RAWIO.但是如果你改变了类似的东西并且太多人“注意到”——即它破坏了他们的设置——那么你就会被愤怒的莱纳斯对你大喊大叫:-P。 (特别是如果您因为“安全启动”而正在处理此问题)。然后更改就会恢复,您就可以找出最不难看的黑客攻击是什么。

即内核可能被迫保持向后兼容性,并允许CAP_NET_ADMIN根命名空间中的进程。在这种情况下,您仍然需要seccomp-bpf保护您的 docker 命令。我不确定在这种情况下是否值得尝试更改内核,因为它只会保护(某些)容器。也许容器运行时docker可以被固定SIOCETHTOOL为默认阻塞。对于像 LXC / systemd-nspawn 这样的“操作系统容器”来说,这也可能是一个可行的默认值。

相关内容