18.1 核心命名空間

命名空間 (Namespace) 是 Linux 容器隔離的基礎,它確保了容器內的程序無法直接干擾主機或其他容器。雖然在本書第 12 章中我們已經從底層實現的角度介紹了 Namespace,但在本節中,我們將重點探討其 安全意義 及相關設定。

18.1.1 隔離的安全本質

Docker 守護程序在啟動容器時,會在後台為容器建立一套獨立的命名空間。命名空間提供了最基礎也是最直接的隔離:

  • PID Namespace:防止容器內的程序檢視或終止宿主機或其他容器的程序。惡意攻擊者即使在容器內獲得了 root 許可權,也無法透過 kill 指令影響宿主機上的關鍵服務。
  • NET Namespace:每個容器都有自己獨立的網路棧。如果沒有顯式地進行連接埠對映或將容器連線到同一網路,容器之間無法網路互通,從而限制了橫向移動的能力。
  • MNT Namespace:為容器提供獨立的檔案系統檢視。這可以防止容器不經意或惡意地修改宿主機的重要系統檔案(如 /etc/passwd)。

18.1.2 命名空間不是絕對安全的護城河

儘管命名空間提供了很好的隔離性,但我們必須認識到:所有的容器依然共享同一個宿主機的 Linux 核心

這意味著,一旦宿主機的核心存在提權漏洞(如著名的 Dirty COW 漏洞),攻擊者有可能透過突破 Namespace 的限制,直接在核心層面執行惡意程式碼,從而實現『容器逃逸』。

⚠️ Warning

為了緩解核心漏洞帶來的威脅,生產環境務必保持宿主機 Linux 核心的及時修補與更新,或者藉助諸如 gVisor、Kata Containers 等提供了獨立核心的安全容器技術。同時,需要及時修補容器執行時(如 runC)的漏洞。2025 年 11 月披露的一系列 runC 容器逃逸漏洞(CVE-2025-31133、CVE-2025-52565、CVE-2025-52881)就表明,即使核心保持更新,執行時層的缺陷仍然可能導致容器隔離被突破。

透過命名空間,Docker 也能限制程序從外部環境獲取訊息。 例如,由於程序環境被隔離,程序在內部通常無法直接感知外部宿主機的程序和掛載命名空間。網路命名空間隔離的是網路棧;預設 bridge 網路通常允許容器主動訪問外部網路,限制的是外部直接訪問容器服務。若要限制出站訪問,需要使用 none 網路、防火牆、Kubernetes NetworkPolicy 或執行時策略。

18.1.3 使用者命名空間與提權防護

在所有的 Namespace 中,User Namespace 對安全的影響尤為關鍵。

在預設情況下,容器內的 root 使用者(UID=0)就是宿主機上的 root 使用者。如果攻擊者設法突破了容器的其他隔離機制獲取了宿主機的訪問許可權,他將擁有宿主機的最高系統許可權。

透過啟用 User Namespace Remapping (使用者命名空間對映),我們可以將容器內的 root 使用者對映到宿主機上的一個無特權普通使用者。

如何設定 User Namespace

要在 Docker 伺服器端啟用這一屬性,需要修改 Docker 的設定檔案 /etc/docker/daemon.json

  1. 設定對映策略

編輯設定檔案,新增 userns-remap 設定項:

{
  "userns-remap": "default"
}

使用 default 值時,Docker 會自動在宿主機上建立一個名為 dockremap 的使用者和使用者組。

  1. 驗證子 UID 和子 GID 分配

Docker 會通過 /etc/subuid/etc/subgid 檔案為 dockremap 分配一個高位的 UID 範圍:

$ cat /etc/subuid
dockremap:165536:65536

這意味著:容器內的 UID 0(root 使用者)在宿主機上實際被對映成了 UID 165536。如果是容器內的 UID 1,對應宿主機的 165537,以此類推。

  1. 重啟 Docker 守護程序
$ sudo systemctl restart docker

驗證對映效果

我們可以執行一個簡單的容器並執行 sleep 指令,同時在宿主機上觀察程序的所有者:

## 在容器內以 root 身份執行
$ docker run -d --name userns_test alpine sleep 3600

## 在宿主機上檢視該 sleep 程序
$ ps aux | grep sleep
165536    12345  0.0  0.0   1568     4 ?        Ss   14:20   0:00 sleep 3600

你會發現,儘管在容器內該程序是由 root 啟動的,但在宿主機上,它的屬主是 165536(一個完全沒有特權的使用者)。

💡 Tip

啟用 User Namespace 會對容器共享宿主機資料卷(Bind Mount)產生許可權影響。你需要確保對映後的高位 UID 對宿主機上的掛載目錄具有合適的讀寫許可權。

18.1.4 總結

核心命名空間從 Linux 2.6.15 版本 (2006 年) 被引入,十餘年間,這些機制的可靠性在諸多大型生產系統中被實踐驗證。透過合理利用命名空間(尤其是 User Namespace),可以極大地收窄攻擊面,顯著提升容器部署的安全性。

第 148 页,共 196 页
使用 mdPress 构建