docker daemon 选项--selinux-enabled 有什么作用

Mic*_*Sun 5 selinux docker

我想它会标记它启动的容器,但是从 的输出来看ps -eZ,我看不出任何区别。例如,容器etcd有相同的域,不管守护进程有没有这个选项:

system_u:system_r:container_runtime_t:s0 16212 ? 00:00:00 dnsmasq-nanny
Run Code Online (Sandbox Code Playgroud)

但它确实阻止了我的容器 (k8s-dns-dnsmasq-nanny-amd64:1.14.8) 启动,并且拒绝日志显示对/etc/localtime/usr/sbin/dnsmasq 的访问被拒绝。我认为这些是容器文件系统中的文件。如何编写 SELinux 策略以允许访问容器文件系统?

moe*_*ius 10

简答

  • --selinux-enabled将启用 selinux 策略,该策略允许标记为 的容器进程svirt_lxc_net_t读取和写入带有该svirt_sandbox_file_t标签的文件。
  • 可以通过使用docker inspect -f '{{ .ProcessLabel }}' <container name>和检查容器来检查容器标签docker inspect -f '{{ .MountLabel }}' <container name>

长答案

--selinux-enabled选项使泊坞窗SELinux安全策略,它详细描述这里。启用后,此策略将:

  • svirt_sandbox_file_tsvirt_lxc_net_t标签标记容器。这可以通过运行容器并检查应用到它的标签来确认:

    docker inspect <container id> | grep "Label"
    
    "MountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c557,c611",
    "ProcessLabel": "system_u:system_r:svirt_lxc_net_t:s0:c557,c611",
    
    Run Code Online (Sandbox Code Playgroud)

    svirt_sandbox_file_t是一个 MountLabel,它限制对主机文件系统上的文件的访问。该搬运工SELinux的文档说:

    如果一个文件被标记为 svirt_sandbox_file_t,那么默认情况下所有容器都可以读取它。但是如果容器写入具有 svirt_sandbox_file_t 所有权的目录,它们会使用自己的类别进行写入

    上例中的类别是c557,c611

    svirt_lxc_net_t是用来保护的进程。根据这里的redhat解决方案,它用于:

    ... 将容器进程与主机隔离,并生成唯一的多类别安全标签,以允许 SELinux 防止一个容器进程攻击其他容器进程和内容。

您的访问问题很可能是因为主机文件系统上的 selinux 标签阻止了容器内的访问。例如,selinux 文档说:

默认情况下,docker 可以访问 /usr 中的所有内容和 /etc 中的大部分内容。

所以你的选择是:

  1. 手动重新标记主机系统上的文件system_u:object_r:svirt_sandbox_file_t。对于系统文件和目录,通常不建议这样做,因为它可能会对主机产生意想不到的影响。

  2. 以无限制类型运行容器。这将仅禁用此容器的隔离,同时仍继续在主机上强制执行 selinux:

    docker run -it --security-opt label:disable alpine sh
    
    Run Code Online (Sandbox Code Playgroud)