18.4 核心能力機制

傳統 Linux 的許可權模型非常粗放:程序分為『特權程序』(以 root 使用者 UID 0 執行)和『非特權程序』(其他 UID 執行)。這帶來了一個致命問題——只要一個後台服務需要一個微小的特權(例如繫結低於 1024 的連接埠),就必須被賦予所有的 root 許可權。一旦該服務被攻陷,系統便會全面淪陷。

為了解決這一問題,Linux 引入了 能力機制(Capabilities)。它將傳統的全能 root 許可權劃分為幾十個細粒度的操作能力。

18.4.1 容器內建的 Capability 白名單

在預設情況下,即便一個容器是在以 root 使用者執行,Docker 也只為其內核授予了所有可用能力中的 一小部分『白名單』能力

常見的 Linux Capabilities 包含:

  • CAP_CHOWN: 修改檔案所有者。
  • CAP_NET_BIND_SERVICE: 繫結特權連接埠(即 1024 以下的連接埠)。
  • CAP_NET_ADMIN: 網路管理的最高許可權(例如調整路由設定,設定防火牆規則等)。
  • CAP_SYS_ADMIN: 被譽為『Linux 核心的特權網管』,允許各種高危操作(掛載磁碟、訪問敏感裝置等)。

為了在 『最小特權原則』 的指導下加強安全,Docker 預設 移除了 大量可能導致容器大範圍破壞宿主機的能力,例如:

  • 完全禁止了任何透過 CAP_SYS_ADMIN 進行的核心掛載或裝置操作。
  • 禁止修改核心模組。
  • 禁止直接訪問硬體套接字。

這種『非完整』的 root 使用者能保證大部分應用在擁有其所需許可權的同時,把惡意行為對系統的影響降到最低。

18.4.2 實戰:新增與剝奪能力

當啟動一個 Docker 容器時,我們可以利用 --cap-add(增加特權)和 --cap-drop(剝奪特權)兩個引數精細地控制程序環境。

實戰場景一:建立極限安全的 Web 靶機

假設你正在提供一個公共的 Web 容器。你不希望裡面的任何惡意指令碼修改程序許可權或者建立裝置節點,你可以透過指令先移除 所有 預設能力,然後再按需授權該守護程序一個僅僅能綁連接埠的能力。

$ docker run -d \
  --name max_secure_web \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  nginx:alpine

這裡的 --cap-drop ALL 是實現『特權最小化』的最強殺手鐗。此時,即便某駭客利用 0-Day 手段拿到了 Web 服務的容器 root Shell,當他試圖改變任何不屬於他自己的程序設定或者所有權時,系統都會報錯拒絕訪問。

實戰場景二:需要捕獲網路資料套件的網路實驗

假設容器內的主程式是一個網路嗅探器(如 tshark 或 tcpdump),這顯然不在 Docker 提供的預設白名單之內,因為該程式試圖直接操縱底層網絡卡流量,會觸發 Permission Denied。

此時,我們需要給它適當補發缺失的部分核心管理能力:

$ docker run -it --rm \
  --name network_sniffer \
  --cap-add NET_ADMIN \
  --cap-add NET_RAW \
  tshark-image /bin/bash

我們只授予了所需的網路管理控制(NET_ADMIN)和偵聽底層套接字的許可權(NET_RAW),而免去了賦予整個容器終極殺器 --privileged 引數。

⚠️ Warning

大量開發人員遇到了『許可權遭到拒絕』的錯誤時,往往習慣性圖省事新增 --privileged 這個核選項。但這將把 宿主機上一切特權和所有訪問裝置完全投射給容器內的根使用者,其危險性等價於根本沒有做隔離!請務必查明程序出錯的實際原因,精準施加必要的隔離 CAP_* 能力。

18.4.3 總結

利用能力機制(Capabilities)是進行精細化系統級訪問控制的關鍵一環。遵循『白名單剝奪一切不必要權利(--cap-drop ALL)』的極端設定並不過分,這將使得即便程式本身漏洞百出,攻擊面也被死死壓縮在一個幾乎毫無後續伸展潛力的受限維度中。

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