docker - docker daemon 选项 --selinux-enabled 有什么作用
问题描述
我猜它会标记它启动的容器,但是从 的输出来看ps -eZ
,我看不出有什么区别。例如,容器etcd
具有相同的域,无论守护程序是否带有此选项:
system_u:system_r:container_runtime_t:s0 16212 ? 00:00:00 dnsmasq-nanny
但它确实阻止了我的容器(k8s-dns-dnsmasq-nanny-amd64:1.14.8)启动,并且拒绝日志显示访问/etc/localtime
和 /usr/sbin/dnsmasq 被拒绝。我认为这些是容器文件系统中的文件。如何编写 SELinux 策略以允许访问容器文件系统?
解决方案
简答
--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
选项启用 docker selinux 安全策略,此处详细描述。启用后,此策略将:
svirt_sandbox_file_t
用和标签标记容器svirt_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",
这
svirt_sandbox_file_t
是一个 MountLabel,它限制对主机文件系统上文件的访问。docker selinux 文档说:如果一个文件被标记为 svirt_sandbox_file_t,那么默认情况下所有容器都可以读取它。但是,如果容器写入具有 svirt_sandbox_file_t 所有权的目录,它们会使用自己的类别写入
上例中的类别是
c557,c611
.svirt_lxc_net_t
用于保护进程。根据这里的redhat解决方案,它用于:... 将容器进程与主机隔离,并生成唯一的多类别安全标签,以允许 SELinux 防止一个容器进程攻击其他容器进程和内容。
您的访问问题很可能发生,因为主机文件系统上的 selinux 标签阻止了容器内的访问。例如,selinux 文档说:
默认情况下,docker 可以访问 /usr 中的所有内容以及 /etc 中的大多数内容。
所以你的选择是:
使用 .手动重新标记主机系统上的文件
system_u:object_r:svirt_sandbox_file_t
。这通常不建议用于系统文件和目录,因为它可能会对主机产生意想不到的影响。将容器作为无限制类型运行。这将仅禁用此容器的隔离,同时仍继续在主机上强制执行 selinux:
docker run -it --security-opt label:disable alpine sh
推荐阅读
- python - 如何根据不同列中的唯一变量获取 csv 文件中列的运行总计?
- php - ReCaptcha 在调用 siteverify 时随机返回空值
- c++ - 面向 Windows Server Core 的 C++
- seaborn - 是否可以更改使用 FacetGrid.add_legend() 创建的图例的列数?
- python - 由每小时的开始和结束时间戳定义的拆分持续时间
- java - 数字序列的反转(堆栈和队列)
- python - 我无法解决这个问题有人可以帮助我吗?“'NoneType' 对象没有属性 'send_keys'”
- reactjs - 如何删除嵌套数组中的项目以作为反应状态传递
- c - GetSystemMetrics() 在 RDP 会话上报告错误的鼠标值
- java - Java 算术方程字符串 java min(x,y),max(x,y),+,-,/,*