用 SELinux 保護(hù)你的容器
黑掉你的系統(tǒng),了解為什么配置 SELinux 作為你的第一道容器防線是很重要的。
當(dāng)有些事情在你的 Linux 環(huán)境中不能正常工作時(shí),最簡(jiǎn)單的方法就是禁用安全增強(qiáng)型 LinuxSecurity-Enhanced Linux(??SELinux??)。而當(dāng)它突然可以工作了,你就會(huì)忘記了禁用這件事 —— 這是一個(gè)常見(jiàn)的陷阱,意味著你已經(jīng)失去了一個(gè)非常強(qiáng)大的安全工具。
隨著容器、微服務(wù)和分布式架構(gòu)的興起,威脅也在上升。這是由于一個(gè)老的、眾所周知的問(wèn)題:速度。容器的優(yōu)勢(shì)在于它們能讓你快速行動(dòng),做更多的事情,并迅速改變。這意味著容器的采用已經(jīng)飛速發(fā)展,但它所提供的速度也意味著你會(huì)遇到更多的問(wèn)題和漏洞。當(dāng)你越來(lái)越快地做更多的事情時(shí),這自然會(huì)發(fā)生。
如何減輕威脅
正如孫子所說(shuō),“不戰(zhàn)而屈人之兵”。當(dāng)涉及到容器的基本防御時(shí),這句話真的很有共鳴。為了避免問(wèn)題(戰(zhàn)斗),確保你的容器主機(jī)是安全的,你可以使用 SELinux 作為你的第一道防線。
SELinux 是一個(gè)開(kāi)源項(xiàng)目,于 2000 年發(fā)布,2003 年集成到 Linux 內(nèi)核中。根據(jù) ??紅帽公司的解釋??,“SELinux 是 ??Linux 系統(tǒng)?? 的一個(gè)安全架構(gòu),允許管理員對(duì)誰(shuí)可以訪問(wèn)系統(tǒng)有更多的控制。它最初是由美國(guó)國(guó)家安全局(NSA)開(kāi)發(fā)的,是使用 Linux 安全模塊(LSM)對(duì) ??Linux 內(nèi)核?? 的一系列補(bǔ)丁?!?/p>
開(kāi)始吧
當(dāng)你想到容器時(shí),首先想到的可能是 ??Docker??。Docker 在 2013 年出現(xiàn)后掀起了一場(chǎng)容器采用革命。它是容器爆炸性流行的主要原因之一,但如上所述,大量采用增加了用戶對(duì)安全風(fēng)險(xiǎn)的脆弱性。
在你用 SELinux 保護(hù)你的 Docker 容器之前,你需要設(shè)置一些東西。
前置條件
- 安裝并配置了 CentOS 8/RHEL 8。
- 安裝并配置好 Docker CE
- 創(chuàng)建兩個(gè)賬戶:root 和 非 root 用戶(下面的例子中是 ?
?mcalizo?
?)。
如果你需要在你的 RHEL 8/CentOS 8 服務(wù)器上設(shè)置 Docker,你可以按照這些 ??說(shuō)明??。如果你運(yùn)行的是 RHEL 8,你需要在開(kāi)始之前刪除預(yù)裝的 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 ~]$
然后,驗(yàn)證你的操作系統(tǒng)版本和 Docker 正在運(yùn)行。以 root 身份登錄并運(yùn)行:
[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
黑掉主機(jī)
了解一個(gè)問(wèn)題的最好方法之一就是去體驗(yàn)它。因此,我將告訴你,如果你的安全設(shè)置不當(dāng),向 Docker 主機(jī)注入惡意代碼是多么容易。
為了能夠在 Docker 主機(jī)上做壞事,“惡意”的非 root 用戶(本教程中為 ??mcalizo?
?)必須是可以實(shí)例化 Docker 容器的組的成員。
首先,確認(rèn) ??mcalizo?
? 用戶屬于哪個(gè)組:
[root@Rhel82 ~]# groups mcalizo
mcalizo : mcalizo
輸出顯示,??mcalizo?
? 只屬于它自己的組。這意味著 ??mcalizo?
? 不能實(shí)例化 Docker 容器,如果它試圖這樣做,將會(huì)得到這個(gè)錯(cuò)誤:
[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?
? 實(shí)例化容器,將用戶加入 ??docker?
? 組:
[root@Rhel82 ~]# usermod -G docker -a mcalizo
[root@Rhel82 ~]# groups mcalizo
mcalizo : mcalizo docker
接下來(lái),部署一個(gè) ??fedora:latest?
? 的容器,并登錄到實(shí)例化的容器中去探索它:
[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)
當(dāng)你登錄到新創(chuàng)建的容器時(shí),你可以看到你是以 root 身份自動(dòng)登錄的:
sh-5.0# whoami
root
sh-5.0#
作為 ??root?
? 用戶,你可以在這個(gè)容器中做任何事情,這意味著你可以利用容器主機(jī),做很多破壞。因?yàn)槟憧梢詫?shí)例化一個(gè)容器,即使你不屬于主機(jī)的 sudoers 賬戶,你也可以對(duì)主機(jī)做一些事情。
退出你剛剛創(chuàng)建的容器,并創(chuàng)建一個(gè)新的容器來(lái)演示這個(gè)漏洞:
[mcalizo@Rhel82 ~]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[root@131043f2e306 /]#
??-v 選項(xiàng)?? 將 Docker 主機(jī)的 ??/?
? 目錄掛載到 ??/exploit?
? 目錄下的容器:
[root@131043f2e306 /]#ls exploit/
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
因?yàn)樗驯粧燧d,你可以在 Docker 主機(jī)上做任何事情。例如,你可以刪除文件、編輯特定的配置來(lái)破害系統(tǒng),甚至安裝木馬程序或其他惡意軟件來(lái)竊取重要信息。
為什么會(huì)發(fā)生這種情況?
你可能想知道,既然 SELinux 處于強(qiáng)制模式,為什么會(huì)出現(xiàn)這種情況?深入挖掘 SELinux,看看哪里出了問(wèn)題。
驗(yàn)證 SELinux 是否有一個(gè) ??Docker 上下文??:
[mcalizo@Rhel82 ~]$ ps -eZ | grep docker
system_u:system_r:container_runtime_t:s0 30768 ? 00:00:04 dockerd
[mcalizo@Rhel82 ~]$
正如預(yù)期的那樣,它確實(shí)有。這意味著 SELinux 管理著 Docker 守護(hù)進(jìn)程。檢查 Docker 守護(hù)進(jìn)程,看看 SELinux 是否默認(rèn)啟用:
[mcalizo@Rhel82 ~]$ docker info | grep Security -A3
Security Options:
seccomp
Profile: default
Kernel Version: 4.18.0-193.el8.x86_64
Docker 守護(hù)進(jìn)程中的 SELinux 在默認(rèn)情況下是 不啟用 的。 這就是問(wèn)題所在!要解決這個(gè)問(wèn)題,按 ??文檔?? 說(shuō)明,通過(guò)更新或創(chuàng)建文件 ??/etc/docker/daemon.json?
? 來(lái)啟用 SELinux 來(lái)控制和管理 Docker(你必須有 root 權(quán)限才能這樣做):
[root@Rhel82 ~]# cat /etc/docker/daemon.json
{
"selinux-enabled": true
}
[root@Rhel82 ~]#
[root@Rhel82 ~]# systemctl restart docker
在創(chuàng)建或更新該文件并重啟 Docker 后,你應(yīng)該看到 Docker 守護(hù)進(jìn)程中啟用了 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 主機(jī)中的特定文件系統(tǒng),但不再允許更新或訪問(wèn)該文件:
[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 /]#
了解更多
你在容器世界中的第一道防線取決于你對(duì)容器主機(jī)的操作系統(tǒng)的設(shè)置有多強(qiáng)。有許多方法可以實(shí)現(xiàn) Linux 的安全性,包括市場(chǎng)上可供選擇的方案,以增強(qiáng)你的安全態(tài)勢(shì)。
SELinux 是一個(gè)額外的安全層,默認(rèn)情況下內(nèi)置于 ??Linux 發(fā)行版?? 中。為了借助它保護(hù)你的系統(tǒng)不被破壞,請(qǐng)確保 SELinux 保持開(kāi)啟狀態(tài)。