Omn*_*ous 8 security namespaces docker
我需要在 Docker 容器内创建命名空间。作为其中的一部分,我需要将/proc私有挂载到内部命名空间。我意识到我必须以特定权限运行容器才能实现这一点,但我更愿意启用最小集。
这有效:
$ sudo docker run --privileged --security-opt=seccomp=unconfined \
-it fedora:rawhide /usr/bin/unshare -Ufmp -r \
/bin/sh -c 'mount -t proc proc /proc'
Run Code Online (Sandbox Code Playgroud)
这不会:
$ sudo docker run --cap-add=sys_admin --security-opt=seccomp=unconfined \
-it fedora:rawhide /usr/bin/unshare -Ufmp -r \
/bin/sh -c 'mount -t proc proc /proc'
mount: /proc: cannot mount proc read-only.
Run Code Online (Sandbox Code Playgroud)
因此,仅关闭 seccomp 过滤器并添加CAP_SYS_ADMIN是不够的。什么是足够了吗?
更新: Selinux 是问题的一部分。如果您全局关闭 selinux 强制,它会起作用。但是,您也可以使用 关闭对特定容器的强制执行--security-opt label:disable,这在在线 Docker 手册的安全配置部分有记录:
sudo docker run --cap-add=sys_admin --security-opt label:disable \
-it fedora:rawhide /usr/bin/unshare -fmp /bin/sh -c \
'mount --make-private / ; mount -t proc proc /proc'
Run Code Online (Sandbox Code Playgroud)
但是如果-U和-r标志被添加回unshare. 而且,当然,--privileged即使使用-U和-r标志,添加到 docker run 命令也能正常工作。
我目前正在尝试使用内核跟踪的东西来弄清楚究竟是什么给了我一个 EPERM。这是一个非常无益的非特定错误。
该命令的工作原理:
sudo docker run --cap-add=sys_admin --security-opt label:disable -it fedora:rawhide /bin/sh -c 'for dir in $(awk '"'"'/\/proc\// { print $5; }'"'"' /proc/1/mountinfo ); do umount "$dir"; done; /usr/bin/unshare -Ufmp -r /bin/sh -c '"'"'mount --make-private / ; mount -t proc proc /proc ; ls /proc'"'"
Run Code Online (Sandbox Code Playgroud)
我没有将其分成多行,因为引用非常重要。/proc基本上,它在运行 unshare 并/proc在子用户命名空间中安装之前卸载了一大堆东西。
/procDocker使用自己的目录挂载了一堆目录和文件,这些目录是空的 tmpfs 目录和空文件。中的各个文件/proc代表适用于整个系统的值。事实上,/proc/kcore如果您是 root,则允许您读取容器内的内核内存,因为很多人希望相信容器是某种轻量级虚拟机或其他东西,这会让很多人感到惊讶。
内核(至少从版本 4.14 开始)fs/namespace.c:mnt_already_visible检查是否正在挂载已挂载的文件系统,如果该文件系统将某些内容挂载为子文件系统,并且这些挂载具有 MNT_LOCKED 标志,则会失败。每当您创建用户命名空间时,MNT_LOCKED 标志似乎都会应用于所有挂载(我没有找到它在内核中的位置),以防止您卸载该命名空间中的东西(因为您获得了用户命名空间)并使隐藏的内容再次可见。
我发布的命令使用 awk 脚本来提取Docker 已挂载的/proc/1/mountinfo所有子目录和文件,并将它们全部卸载。/proc这使得/proc文件系统可以再次安装在嵌套用户命名空间中。
| 归档时间: |
|
| 查看次数: |
6955 次 |
| 最近记录: |