為什麼Podman執行容器更安全?
Podman 使用傳統的 fork/exec 模型(相對於客戶端/伺服器模型)來執行容器。 |
在進入本文的主要主題 Podman 和容器之前,我需要了解一點 Linux 審計功能的技術。
Linux 核心有一個有趣的安全功能,叫做審計。它允許管理員在系統上監視安全事件,並將它們記錄到 audit.log 中,該檔案可以本地儲存或遠端儲存在另一臺機器上,以防止黑客試圖掩蓋他的蹤跡。
/etc/shadow 檔案是一個經常要監控的安全檔案,因為向其新增記錄可能允許攻擊者獲得對系統的訪問許可權。管理員想知道是否有任何程式修改了該檔案,你可以通過執行以下 命令來執行此操作:
# auditctl -w /etc/shadow
現在讓我們看看當我修改了 /etc/shadow 檔案會發生什麼:
# touch /etc/shadow # ausearch -f /etc/shadow -i -ts recent type=PROCTITLE msg=audit(10/10/2018 09:46:03.042:4108) : proctitle=touch /etc/shadow type=SYSCALL msg=audit(10/10/2018 09:46:03.042:4108) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7ffdb17f6704 a2=O_WRONLY|O_CREAT|O_NOCTTY| O_NONBLOCK a3=0x1b6 items=2 ppid=2712 pid=3727 auid=dwalsh uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts1 ses=3 comm=touch exe=/usr/bin/touch subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)`
審計記錄中有很多資訊,但我重點注意到它記錄了 root 修改了 /etc/shadow 檔案,並且該程式的審計 UID(auid)的所有者是 dwalsh。
核心修改了這個檔案了麼?
登入 UID(loginuid),儲存在 /proc/self/loginuid 中,它是系統上每個程式的 proc 結構的一部分。該欄位只能設定一次;設定後,核心將不允許任何程式重置它。
當我登入系統時,登入程式會為我的登入過程設定 loginuid 欄位。
我(dwalsh)的 UID 是 3267。
$ cat /proc/self/loginuid 3267
現在,即使我變成了 root,我的登入 UID 仍將保持不變。
$ sudo cat /proc/self/loginuid 3267
請注意,從初始登入過程 fork 並 exec 的每個程式都會自動繼承 loginuid。這就是核心知道登入的人是 dwalsh 的方式。
現在讓我們來看看容器。
sudo podman run fedora cat /proc/self/loginuid 3267
甚至容器程式也保留了我的 loginuid。 現在讓我們用 Docker 試試。
sudo docker run fedora cat /proc/self/loginuid 4294967295
Podman 對於容器使用傳統的 fork/exec 模型,因此容器程式是 Podman 程式的後代。Docker 使用客戶端/伺服器模型。我執行的 docker 命令是 Docker 客戶端工具,它通過客戶端/伺服器操作與 Docker 守護程式通訊。然後 Docker 守護程式建立容器並處理 stdin/stdout 與 Docker 客戶端工具的通訊。
程式的預設 loginuid(在設定 loginuid 之前)是 4294967295(LCTT 譯註:232 - 1)。由於容器是 Docker 守護程式的後代,而 Docker 守護程式是 init 系統的子代,所以,我們看到 systemd、Docker 守護程式和容器程式全部具有相同的 loginuid:4294967295,審計系統視其為未設定審計 UID。
cat /proc/1/loginuid 4294967295
讓我們來看看如果 Docker 啟動的容器程式修改 /etc/shadow 檔案會發生什麼。
$ sudo docker run --privileged -v /:/host fedora touch /host/etc/shadow $ sudo ausearch -f /etc/shadow -i type=PROCTITLE msg=audit(10/10/2018 10:27:20.055:4569) : proctitle=/usr/bin/coreutils --coreutils-prog-shebang=touch /usr/bin/touch /host/etc/shadow type=SYSCALL msg=audit(10/10/2018 10:27:20.055:4569) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7ffdb6973f50 a2=O_WRONLY|O_CREAT|O_NOCTTY| O_NONBLOCK a3=0x1b6 items=2 ppid=11863 pid=11882 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=touch exe=/usr/bin/coreutils subj=system_u:system_r:spc_t:s0 key=(null)
在 Docker 情形中,auid 是未設定的(4294967295);這意味著安全人員可能知道有程式修改了 /etc/shadow 檔案但身份丟失了。
如果該攻擊者隨後刪除了 Docker 容器,那麼在系統上誰修改 /etc/shadow 檔案將沒有任何跟蹤資訊。
現在讓我們看看相同的場景在 Podman 下的情況。
$ sudo podman run --privileged -v /:/host fedora touch /host/etc/shadow $ sudo ausearch -f /etc/shadow -i type=PROCTITLE msg=audit(10/10/2018 10:23:41.659:4530) : proctitle=/usr/bin/coreutils --coreutils-prog-shebang=touch /usr/bin/touch /host/etc/shadow type=SYSCALL msg=audit(10/10/2018 10:23:41.659:4530) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7fffdffd0f34 a2=O_WRONLY|O_CREAT|O_NOCTTY| O_NONBLOCK a3=0x1b6 items=2 ppid=11671 pid=11683 auid=dwalsh uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=3 comm=touch exe=/usr/bin/coreutils subj=unconfined_u:system_r:spc_t:s0 key=(null)
由於它使用傳統的 fork/exec 方式,因此 Podman 正確記錄了所有內容。
這只是觀察 /etc/shadow 檔案的一個簡單示例,但審計系統對於觀察系統上的程式非常有用。使用 fork/exec 容器執行時(而不是客戶端/伺服器容器執行時)來啟動容器允許你通過審計日誌記錄保持更好的安全性。
在啟動容器時,與客戶端/伺服器模型相比,fork/exec 模型還有許多其他不錯的功能。例如,systemd 功能包括:
SD_NOTIFY:如果將 Podman 命令放入 systemd 單元檔案中,容器程式可以通過 Podman 返回通知,表明服務已準備好接收任務。這是在客戶端/伺服器模式下無法完成的事情。
套接字啟用:你可以將連線的套接字從 systemd 傳遞到 Podman,並傳遞到容器程式以便使用它們。這在客戶端/伺服器模型中是不可能的。
在我看來,其最好的功能是作為非 root 使用者執行 Podman 和容器。這意味著你永遠不會在宿主機上授予使用者 root 許可權,而在客戶端/伺服器模型中(如 Docker 使用的),你必須開啟以 root 身份執行的特權守護程式的套接字來啟動容器。在那裡,你將受到守護程式中實現的安全機制與宿主機作業系統中實現的安全機制的支配 —— 這是一個危險的主張。
原文連結: https://www.linuxprobe.com/podman-docker.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2656702/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Podman:一個更安全的執行容器的方式
- 無需sudo使用Podman在Linux上執行容器Linux
- 為什麼?為什麼StringBuilder是執行緒不安全的?UI執行緒
- 為什麼 HTTPS 比 HTTP 更安全?HTTP
- RHCE(podman容器)
- 為什麼容器和 Kubernetes 有潛力執行一切
- 為什麼 Random.Shared 是執行緒安全的random執行緒
- 容器不是執行緒安全執行緒
- 什麼是執行緒安全和執行緒不安全執行緒
- 為什麼建議一個容器中只執行一個程式
- 為什麼使用 HTTP 爬蟲代理更安全?HTTP爬蟲
- 為什麼 Go map 和 slice 是非執行緒安全的?Go執行緒
- 以沙箱的方式執行容器:安全容器gvisor
- HTTP與HTTPS:為什麼HTTPS比HTTP更安全?HTTP
- 如果雲更安全 為什麼還是被入侵?
- 為什麼我們需要更注重原始碼安全?原始碼
- 29-HashMap 為什麼是執行緒不安全的?HashMap執行緒
- 以沙箱的方式執行容器:安全容器Kata ContainersAI
- python為什麼要用執行緒Python執行緒
- 為什麼要有 Servlet ,什麼是 Servlet 容器,什麼是 Web 容器?ServletWeb
- 什麼時候執行緒不安全?怎樣做到執行緒安全?怎麼擴充套件執行緒安全的類?執行緒套件
- 用 Podman Compose 管理容器
- Promise為什麼比setTimeout先執行?Promise
- 為什麼執行緒安全的List推薦使用CopyOnWriteArrayList,而不是Vector執行緒
- 為什麼redis是單執行緒的以及為什麼這麼快?Redis執行緒
- 執行緒池管理(1)-為什麼需要執行緒池執行緒
- redis為什麼用單執行緒不用多執行緒Redis執行緒
- 什麼叫執行緒安全,舉例說明。執行緒
- Redis為什麼是單執行緒?為什麼有如此高的效能?Redis執行緒
- [20220422]為什麼執行不報錯.txt
- 什麼是K8S的容器執行時CRI介面?K8S
- 為什麼python執行效率低?原來因為它!Python
- 蘋果mac電腦為什麼比win系統更安全呢?蘋果Mac
- 為什麼要虛擬化,為什麼要容器,為什麼要Docker,為什麼要K8S?DockerK8S
- 為什麼在 Plasma 上難以執行 EVMASM
- Redis單執行緒,為什麼速度快Redis執行緒
- 為什麼Python停止執行?該如何應對?Python
- python按f5為什麼不執行Python