使用 SELinux 保护您的容器
破解您的系统,了解为什么将 SELinux 配置为容器防御的第一道防线如此重要。
当您的 Linux 环境中出现问题时,最简单的方法是禁用安全增强型 Linux (SELinux)。事情突然开始发挥作用,而您却忘记了这一点,但这是一个常见的陷阱,意味着您失去了一个非常强大的安全工具。
随着容器、微服务和分布式架构的兴起,威胁也在不断增加。这是由于一个众所周知的老问题:速度。容器的优势在于它们使您能够快速移动、执行更多操作并快速更改。这意味着容器的采用已经飞速发展,但它提供的速度也意味着您将遇到更多问题和漏洞。当你越来越快地做越来越多的事情时,这种情况就会自然发生。
如何减轻威胁
正如孙子所说:“明智的战士避免战斗。”当谈到容器的基本防御时,这句话确实引起了共鸣。为了避免出现问题(冲突),请确保您的容器主机是安全的并且可以使用 SELinux 作为第一道防线。
SELinux 是一个于 2000 年发布的开源项目,并于 2003 年集成到 Linux 内核中。据 Red Hat 的解释者介绍,“SELinux 是 Linux 系统的一个安全架构,允许管理员对谁可以访问系统有更多的控制权。它最初是由美国国家安全局 (NSA) 开发,作为使用 Linux 安全模块 (LSM) 的 Linux 内核的一系列补丁。”
开始使用
说到容器,大家第一个想到的可能就是Docker。 Docker 自 2013 年出现以来,引发了一场容器采用革命。这是容器爆炸式流行的主要原因之一,但如上所述,高水平的采用增加了用户面临安全风险的脆弱性。
在使用 SELinux 保护 Docker 容器之前,您需要进行一些设置。
先决条件:
- CentOS 8/RHEL 8 安装和配置
- Docker CE 安装并配置
- 创建了两个帐户:root 帐户和非 root 帐户(下面示例中的
mcalizo
)
如果您需要在 RHEL 8/CentOS 8 服务器上设置 Docker,可以按照以下说明进行操作。如果您运行的是 RHEL 8,则需要在开始之前删除预安装的 Podman 和 runc 软件包。
首先,确保 SELinux 已启用:
[mcalizo@Rhel82 ~]$ 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
Memory protection checking: actual (secure)
Max kernel policy version: 31
[mcalizo@Rhel82 ~]$
然后,验证您的操作系统版本以及 Docker 是否正在运行。以 root 身份登录并运行:
[root@rhel82 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux release 8.2 (Ootpa)
[root@rhel82 ~]#
[root@rhel82 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-10-28 19:10:14 EDT; 15s ago
Docs: https://docs.docker.com
Main PID: 30768 (dockerd)
Tasks: 8
Memory: 39.0M
CGroup: /system.slice/docker.service
└─30768 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.889602941-04:00" level=error msg=">
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903413613-04:00" level=warning msg>
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903427451-04:00" level=warning msg>
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903538271-04:00" level=info msg="L>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.132060506-04:00" level=info msg="D>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.308943088-04:00" level=info msg="L>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.319438549-04:00" level=info msg="D>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.319570298-04:00" level=info msg="D>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.333419209-04:00" level=info msg="A>
Oct 28 19:10:14 rhel82.home.labs.com systemd[1]: Started Docker Application Container Engine
检查您的 Docker 版本:
[root@rhel82 ~]# docker --version
Docker version 19.03.13, build 4484c46d9d
破解你的主机
理解问题的最好方法之一就是体验它。因此,我将向您展示,如果安全设置不正确,向 Docker 主机注入恶意代码是多么容易。
为了能够在 Docker 主机上做坏事,恶意非 root 用户(本教程中的 mcalizo
)必须是可以实例化 Docker 容器的组的一部分。
首先,确认 mcalizo
用户属于哪个组:
[root@Rhel82 ~]# groups mcalizo
mcalizo : mcalizo
输出显示 mcalizo
仅属于其自己的组。这意味着 mcalizo
无法实例化 Docker 容器,如果尝试,将会收到此错误:
[mcalizo@Rhel82 ~]$ docker run -it --rm centos:latest /bin/sh
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.
要允许 mcalizo 实例化容器,请将用户添加到 docker 组:
[root@Rhel82 ~]# usermod -G docker -a mcalizo
[root@Rhel82 ~]# groups mcalizo
mcalizo : mcalizo docker
接下来,部署 fedora:latest
容器并登录到实例化的容器中进行探索:
[mcalizo@Rhel82 ~]$ docker run -it --rm fedora:latest /bin/sh
Unable to find image 'fedora:latest' locally
latest: Pulling from library/fedora
ee7e89337106: Pull complete
Digest: sha256:b9ec86d36fca7b1d3de39cd7c258e8d90c377d312c21a7748071ce49069b8db4
Status: Downloaded newer image for fedora:latest
sh-5.0# cat /etc/redhat-release
Fedora release 33 (Thirty Three)
当您登录到新创建的容器时,您可以看到您自动以 root 身份登录:
sh-5.0# whoami
root
sh-5.0#
作为 root 用户,您可以在此容器中执行任何操作,这意味着您可以利用容器主机并造成大量破坏。由于您可以实例化容器,因此即使您不是主机 sudoers 帐户的一部分,也可以对主机执行操作。
退出刚刚创建的容器,然后创建一个新容器来演示漏洞利用:
[mcalizo@Rhel82 ~]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[root@131043f2e306 /]#
-v 选项将 Docker 主机的 /
目录挂载到容器的 /exploit
目录下:
[root@131043f2e306 /]#ls exploit/
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
因为它已安装,所以您可以在 Docker 主机上执行任何操作。例如,您可以删除文件、编辑特定配置来损害系统,甚至安装特洛伊木马应用程序或其他恶意软件来窃取重要信息。
为什么会发生这种情况?
您可能想知道为什么这是可能的,因为 SELinux 处于强制模式。深入研究 SELinux,看看哪里出了问题。
验证 SELinux 是否具有 Docker 上下文:
[mcalizo@Rhel82 ~]$ ps -eZ | grep docker
system_u:system_r:container_runtime_t:s0 30768 ? 00:00:04 dockerd
[mcalizo@Rhel82 ~]$
正如预期的那样,确实如此。这意味着 SELinux 管理 Docker 守护进程。检查 Docker 守护进程以查看 SELinux 是否默认启用:
[mcalizo@Rhel82 ~]$ docker info | grep Security -A3
Security Options:
seccomp
Profile: default
Kernel Version: 4.18.0-193.el8.x86_64
默认情况下未启用SELinux。 这就是问题! 要修复此问题,请通过更新或创建文件 /etc/docker/daemon.json
来启用 SELinux 来控制和管理 Docker,如此处所述(您必须具有 root 访问权限才能执行此操作):
[root@Rhel82 ~]# cat /etc/docker/daemon.json
{
"selinux-enabled": true
}
[root@Rhel82 ~]#
[root@Rhel82 ~]# systemctl restart docker
创建或更新文件并重新启动 Docker 后,您应该看到 Docker 守护进程中启用了 SELinux 支持:
[root@Rhel82 ~]# systemctl restart docker
[mcalizo@Rhel82 root]$ docker info | grep Security -A3
Security Options:
seccomp
Profile: default
selinux
[mcalizo@Rhel82 root]$
虽然仍然可以在 Docker 容器上挂载 Docker 主机中的特定文件系统,但不再允许更新或访问该文件:
[mcalizo@Rhel82 root]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[root@ecb5836da1f6 /]# touch /exploit/etc/shadow.sh
touch: cannot touch '/exploit/etc/shadow.sh': Permission denied
[root@ecb5836da1f6 /]#
了解更多
您在容器世界中的第一道防线取决于您设置容器主机操作系统的强度。实现 Linux 安全的方法有很多种,包括市场上可用于增强安全状况的选项。
SELinux 是默认内置于 Linux 发行版中的附加安全层。为了利用它并保护您的系统免受损害,请确保 SELinux 保持打开状态。
如果您想了解更多信息,请参阅:
- 如何在 CentOS 8/RH 上安装 Docker CE
- Docker 安全备忘单
- dockerd 文档
- 使用卷文档
- 什么是 SELinux?