如何禁止 Docker Daemon 将主机的根文件系统挂载到容器中

Vad*_*imo 8 linux selinux chroot apparmor docker

我有以下容器设置。

在裸机服务器上安装并运行了两个 Docker 守护进程。

  1. 主 Docker 守护进程运行我的应用程序容器,将 80/443 暴露给外界。
  2. Plugin Docker Daemon运行客户提供的一些容器,这些容器通过 80/443 与我的应用程序通信。

我想让客户访问Plugin Docker Daemon的 API (2376),以便客户可以部署/启动/停止他自己的容器。客户只能访问 API,而不能访问主机 (SSH)。

我目前面临的问题是,如果客户运行的容器执行诸如docker run -v /:/host/root Ubuntu rm -rf /host/root.

我的问题是我能做些什么来防止插件 Docker 守护程序挂载根目录/或外部的任何其他目录/home/user/

  • 是否可以选择在 Docker 守护进程中启动/home/user/
  • 我可以使用一些 LSM(Linux 安全模块 SELinux/Apparmor)魔法来阻止 docker 守护进程挂载除用户 home 或 var/docker/libs 之外的部分或所有主机路径吗?
  • 可以--userns-remap帮助我实现我的目标吗?
  • 除了虚拟机,还有其他可用的选项吗?

服务器完全属于单个客户。因此,安全性或数据泄漏不是我的主要关注点。我真正想防止的是Plugin Daemon中的某个人正在做一些愚蠢的事情,这会影响我在Main Docker Daemon中运行的容器。我想保持精益并坚持仅使用 docker 的工作流程,并且不会为 VM 创建设置额外的工作流程。

daw*_*wud 8

SELinux 将阻止任何未正确标记的内容挂载为 docker 容器内的卷,作为证明,这里使用单个文件,相同的策略适用于目录:

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      30
Run Code Online (Sandbox Code Playgroud)

使用示例文件:

$ cat sample_script.sh 
echo 'Hello, world'
Run Code Online (Sandbox Code Playgroud)

它的默认安全上下文是:

$ ls -lrtZ sample_script.sh 
-rw-------. 1 david david unconfined_u:object_r:user_home_t:s0 20 Oct  3 17:18 sample_script.sh
Run Code Online (Sandbox Code Playgroud)

尝试在容器内使用此文件会按预期失败:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.sh
bash: sample_script.sh: Permission denied
Run Code Online (Sandbox Code Playgroud)

并且会记录 AVC 拒绝:

$ sudo ausearch -m avc -ts recent
time->Mon Oct  3 17:39:28 2016
type=AVC msg=audit(1475512768.444:784): avc:  denied  { read } for  pid=28720 comm="bash" name="sample_script.sh" dev="dm-13" ino=101062112 scontext=system_u:system_r:svirt_lxc_net_t:s0:c457,c992 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
Run Code Online (Sandbox Code Playgroud)

将安全上下文更改为一个 Docker 后可以使用:

$ sudo chcon -Rt svirt_sandbox_file_t sample_script.sh
$ ls -lrtZ sample_script.sh 
-rw-------. 1 david david unconfined_u:object_r:svirt_sandbox_file_t:s0 20 Oct  3 17:18 sample_script.sh 
Run Code Online (Sandbox Code Playgroud)

容器现在可以访问该文件:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.sh
Hello, world
Run Code Online (Sandbox Code Playgroud)

有关 Docker 和 SELinux 的更多信息,请参阅Red Hat 官方文档和Dan Walsh撰写的这篇文章