SELinux 和 docker 笔记 | Ozznotes

  • A+
所属分类:系统文档

回到家

2018 年 2 月 13 日

胡安·安东尼奥·奥索里奥·罗伯斯

SELinux 和 docker 笔记

自 Pike 发布以来,我们在容器上运行大部分 TripleO 服务。作为尝试强化部署的一部分,我正在研究在启用 SELinux 的情况下运行我们的容器需要什么。

以下是我学到的一些东西。

为 docker 容器启用 SElinux

Docker--selinux-enabled在 CentOS 7.4.1708 中默认具有该标志。但是,如果您的图像或配置管理工具禁用它,就像我们的 puppet 模块验证这一点一样,您可以通过运行以下命令进行验证:

$ docker info | grep 'Security Options'
Security Options: seccomp

要启用它,您需要修改/etc/sysconfig/docker文件,您可以使用该文件为 docker 启用 SELinux。在此文件中,您会注意到
$OPTIONS此处定义的变量,您可以在其中附加相关选项,如下所示:

OPTIONS="--log-driver=journald --signature-verification=false --selinux-enabled"

重启docker后:

$ systemctl restart docker

您会看到 SELinux 作为安全选项启用:

$ docker info | grep 'Security Options'
Security Options: seccomp selinux

请注意,要使这实际上产生任何效果,SELinux 必须在主机本身中强制执行。

Docker 容器可以读取/etc/usr

SELinux 阻止写入 和 中的文件/etc//usr/但允许读取它们。

假设我们在 /etc/ 目录中创建一个文件:

$ echo "Hello from the host" | sudo tee /etc/my-file.txt
Hello from the host
$ ls -lZ /etc/my-file.txt
-rw-r--r--. root root unconfined_u:object_r:etc_t:s0   /etc/my-file.txt

现在,让我们将文件挂载到容器中并尝试对其进行读写。

$ docker run -ti -v /etc/my-file.txt:/tmp/my-file.txt alpine sh
(container)$ cat /tmp/my-file.txt
Hello from the host
(container)$ echo "Hello from the container" >> /tmp/my-file.txt
sh: can't create /tmp/my-file.txt: Permission denied

如果文件包含更多标准到 /etc/目录的标签,则同样是可能的:

# ls -lZ /etc/my-file.txt
-rw-r--r--. root root system_u:object_r:etc_t:s0       /etc/my-file.txt
$ docker run -ti -v /etc/my-file.txt:/tmp/my-file.txt alpine sh
(container)$ cat /tmp/my-file.txt
Hello from the host
(container)$ echo "Hello from the container" >> /tmp/my-file.txt
sh: can't create /tmp/my-file.txt: Permission denied

如果我们在另一个目录中尝试它,则不会看到相同的行为。比如说,用户的主目录:

$ pwd
/home/stack
$ mkdir test
$ echo "Hello from the host" >> test/my-file.txt
$ ls -lZ test/my-file.txt
-rw-rw-r--. stack stack unconfined_u:object_r:user_home_t:s0 test/my-file.txt
$ docker run -ti -v /home/stack/test/my-file.txt:/tmp/my-file.txt alpine sh
(container)$ cat /tmp/my-file.txt
cat: can't open '/tmp/my-file.txt': Permission denied
(container)$ ls /tmp/
ls: /tmp/my-file.txt: Permission denied

如果我们想为容器安装 CA 证书以信任它,这可能很有用,因为它实际上是只读的:

$ ls -lZ /etc/pki/ca-trust/source/anchors/cm-local-ca.pem
-rw-r--r--. root root unconfined_u:object_r:cert_t:s0  /etc/pki/ca-trust/source/anchors/cm-local-ca.pem
$ docker run -ti -v /etc/pki/ca-trust/source/anchors/cm-local-ca.pem:/tmp/ca.crt alpine sh
(container)$ cat /tmp/ca.crt
-----BEGIN CERTIFICATE-----
MIIDjTCCAnWgAwIBAgIQD6sfY0A+T7SHIG6yzfh//zANBgkqhkiG9w0BAQsFADBQ
MSAwHgYDVQQDDBdMb2NhbCBTaWduaW5nIEF1dGhvcml0eTEsMCoGA1UEAwwjMGZh
YjFmNjMtNDAzZTRmYjQtODcyMDZlYjItY2RmODdmZmYwHhcNMTgwMjAyMTUzNDI5
WhcNMTkwMjAyMTUzNDI5WjBQMSAwHgYDVQQDDBdMb2NhbCBTaWduaW5nIEF1dGhv
cml0eTEsMCoGA1UEAwwjMGZhYjFmNjMtNDAzZTRmYjQtODcyMDZlYjItY2RmODdm
ZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhEJJzGBkWNslk0iav
g1E2p39uYfTE6CCdeIRxFXpiKuPg/AO1lQXkUElGcakWJcJ7bWY/be6PGfp8EoRY
OCXtuggpVHXHdfOWhnPwhwdv51frFZwchL6jiaqDz+yEB9nTlhJ6cy4JQMcriZUP
6I/Djl1lzQQiBI/leA0ieNxTfGYifXHEGCDnNiyxIq32BzLcKUaMkl1sNmXjLZ1U
JW5ThPNs7IR/2zZgTyicDZTgLNUsn7oAQMXDffBOLOrx+MpX9k3o+XqBVcnb2+5Q
eQBxOAEjhbjel7GTTbkEajlCohcxvcycTot6hrd9xY3MTM3NHE/ysIs0zdnEkwLx
84v7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAQEwHQYDVR0OBBYEFDWB9zN+m0K6
xSauu4CUYdrcdtr/MB8GA1UdIwQYMBaAFDWB9zN+m0K6xSauu4CUYdrcdtr/MA4G
A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEAlrTvxDBUNqx/nbF5DSkk
R1WqbfNLt07u3kqo+dBfYo4XTEfu2kQ2UzngzirAKokJfm7D8aNJqn6lLVpP0ffc
5VM+mW96tHFearImVZS3Z8gWe5MoD7hDziF3BKW1E0vBYqKOR773H4GpLkYcBLaP
sfujE/uxle2MpNn6i56AeiRwOVIejFSKFKA6rlUDuffu9NE9eKXmO5PW0KT/ojak
JoeC4LnDug+eOU3DrLCmBYEPU+JrHwtuPDCZgVoldVHbd/k+2vvOOvEWoSrTpmoH
3PH2UINW9t7cVxGipyPX3DYu1MrLJ+k73bny5pORgx0sqWh+RoWv8yKE92PP/O5r
Pw==
-----END CERTIFICATE-----
(container)$ echo "I'm trying to tamper with the CA" >> /tmp/ca.crt
sh: can't create /tmp/ca.crt: Permission denied

请注意,来自容器/etc//usr/装载到容器中的文件不包含任何您不想共享的敏感数据。

启用对受 SELinux 保护的文件的访问

为了让容器访问受 SELinux 保护的文件,您需要使用以下卷选项之一:z 或 Z。

  • z(下):重新标记您要安装到容器中的内容,并使其可在容器之间共享。
  • Z(上):重新标记您要安装到容器中的内容,并将其设为私有。因此,将此文件安装在另一个容器中是行不通的。

让我们展示z(较低的)标志在实践中是如何工作的:

$ ls -lZ test/my-file.txt
-rw-rw-r--. stack stack unconfined_u:object_r:user_home_t:s0 test/my-file.txt
$ docker run -ti -v /home/stack/test/my-file.txt:/tmp/my-file.txt:z alpine sh
(container)$ echo "Hello from container 1" >> /tmp/my-file.txt
(container)$ exit
$ cat test/my-file.txt
Hello from the host
Hello from container 1
$ ls -lZ test/my-file.txt
-rw-rw-r--. stack stack system_u:object_r:svirt_sandbox_file_t:s0 test/my-file.txt

请注意,我们现在可以追加到文件中。正如我们所看到的,从主机我们可以看到文件中反映的更改。最后,检查 SELinux 上下文,我们会注意到 docker 已将类型更改为
svirt_sandbox_file_t,这使得它可以在容器之间共享。

如果我们运行另一个容器并附加到该文件,我们将能够这样做:

$ docker run -ti -v /home/stack/test/my-file.txt:/tmp/my-file.txt:z alpine sh
(container2)$ echo "Hello from container 2" >> /tmp/my-file.txt
(container2)$ exit
$ cat test/my-file.txt
Hello from the host
Hello from container 1
Hello from container 2

现在,让我们尝试使用Z(上部)选项。如果我们使用该选项获取相同的文件并将其挂载到容器中,我们将看到以下内容:

$ docker run -ti -v /home/stack/test/my-file.txt:/tmp/my-file.txt:Z alpine sh
(container3)$ echo "Hello from container 3" >> /tmp/my-file.txt

如果我们打开另一个终端并尝试附加到该文件,我们将无法:

$ docker run -ti -v /home/stack/test/my-file.txt:/tmp/my-file.txt:Z alpine sh
(container4)$ echo "Hello from container 4" >> /tmp/my-file.txt
sh: can't create /tmp/my-file.txt: Permission denied

我们可以验证文件的内容:

$ cat test/my-file.txt
Hello from the host
Hello from container 1
Hello from container 2
Hello from container 3
$ ls -lZ test/my-file.txt
-rw-rw-r--. stack stack system_u:object_r:svirt_sandbox_file_t:s0:c829,c861 test/my-file.txt

现在我们可以看到容器的 MCS 标签发生了变化,并且特定于第一次访问它的容器。假设第一次挂载并访问该文件的容器名为reverent_davinci,我们可以使用以下命令检查容器的标签:

$ docker inspect -f '{{ .ProcessLabel }}' reverent_davinci

system_u:system_r:svirt_lxc_net_t:s0:c829,c861

我们可以看到容器的 MCS 标签与文件的标签匹配。

为特定容器禁用 SELinux

虽然这并不理想,但可以使用以下--security-opt
label:disable
选项来实现:

$ docker run -ti -v /home/stack/test/my-file.txt:/tmp/my-file.txt --security-opt label:disable alpine sh
(container)$ cat /tmp/my-file.txt
Hello from the host
Hello from container 1
Hello from container 2
Hello from container 3

参考

技术标签:docker - selinux

回到家

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin