增強型容器隔離
增強型容器隔離 (ECI) 可防止惡意容器破壞 Docker Desktop 或宿主系統。它自動應用高階安全技術,同時保持開發人員的生產力和工作流的完全相容性。
ECI 加強了容器隔離,並鎖定管理員建立的安全配置,例如登錄檔訪問管理策略和設定管理控制。
注意ECI 與其他 Docker 安全功能協同工作,例如簡化的 Linux 功能、seccomp 和 AppArmor。
誰應該使用增強型容器隔離?
增強型容器隔離專為以下使用者設計:
- 希望防止基於容器的攻擊並減少開發環境中安全漏洞的組織
- 需要更強容器隔離而又不影響開發人員工作流的安全團隊
- 在執行不受信任或第三方容器映象時需要額外保護的企業
增強型容器隔離的工作原理
Docker 使用 Sysbox 容器執行時實現 ECI,它是標準 OCI runc 執行時的安全增強型分支。啟用 ECI 後,透過 docker run
或 docker create
建立的容器會自動使用 Sysbox 而不是 runc,而無需更改開發人員工作流。
即使是使用 --privileged
標誌的容器也能透過增強型容器隔離安全執行,從而防止它們突破 Docker Desktop 虛擬機器或其他容器。
注意啟用 ECI 後,Docker CLI
--runtime
標誌將被忽略。Docker 的預設執行時仍為 runc,但所有使用者容器都會隱式地使用 Sysbox 啟動。
主要安全特性
Linux 使用者名稱空間隔離
藉助增強型容器隔離,所有容器都利用 Linux 使用者名稱空間來獲得更強的隔離。容器根使用者對映到 Docker Desktop VM 中的非特權使用者。
$ docker run -it --rm --name=first alpine
/ # cat /proc/self/uid_map
0 100000 65536
此輸出顯示容器根 (0) 對映到 VM 中的非特權使用者 100000,使用者 ID 範圍為 64K。每個容器都獲得獨佔對映。
$ docker run -it --rm --name=second alpine
/ # cat /proc/self/uid_map
0 165536 65536
如果沒有增強型容器隔離,容器將以真正的根使用者身份執行。
$ docker run -it --rm alpine
/ # cat /proc/self/uid_map
0 0 4294967295
透過使用 Linux 使用者名稱空間,ECI 確保容器程序絕不會在 Linux VM 中使用有效的使用者 ID 執行,從而將其功能限制在容器內的資源。
安全特權容器
特權容器(`docker run --privileged`)通常會帶來重大的安全風險,因為它們提供對 Linux 核心的無限制訪問。如果沒有 ECI,特權容器可以:
- 以擁有所有功能的真正根使用者身份執行
- 繞過 seccomp 和 AppArmor 限制
- 訪問所有硬體裝置
- 修改全域性核心設定
保護開發者環境的組織面臨特權容器的挑戰,因為它們可以控制 Docker Desktop VM 並更改登錄檔訪問管理和網路代理等安全設定。
增強型容器隔離透過確保特權容器只能訪問其容器邊界內的資源來改造特權容器。例如,特權容器無法訪問 Docker Desktop 的網路配置。
$ docker run --privileged djs55/bpftool map show
Error: can't get next map: Operation not permitted
如果沒有 ECI,特權容器可以輕鬆訪問和修改這些設定。
$ docker run --privileged djs55/bpftool map show
17: ringbuf name blocked_packets flags 0x0
key 0B value 0B max_entries 16777216 memlock 0B
18: hash name allowed_map flags 0x0
key 4B value 4B max_entries 10000 memlock 81920B
Docker-in-Docker 和 Kubernetes-in-Docker 等高階容器工作負載仍可與 ECI 配合使用,但執行起來更安全。
注意ECI 不會阻止使用者執行特權容器,但會透過限制其訪問來確保它們的安全。修改全域性核心設定(載入核心模組、更改 Berkeley Packet Filter 設定)的特權工作負載會收到“許可權被拒絕”錯誤。
名稱空間隔離強制執行
增強型容器隔離可防止容器與 Docker Desktop VM 共享 Linux 名稱空間,從而保持隔離邊界。
PID 名稱空間共享被阻止
$ docker run -it --rm --pid=host alpine
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: error in the container spec: invalid or unsupported container spec: sysbox containers can't share namespaces [pid] with the host (because they use the linux user-namespace for isolation): unknown.
網路名稱空間共享被阻止
$ docker run -it --rm --network=host alpine
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: error in the container spec: invalid or unsupported container spec: sysbox containers can't share a network namespace with the host (because they use the linux user-namespace for isolation): unknown.
使用者名稱空間覆蓋被忽略
$ docker run -it --rm --userns=host alpine
/ # cat /proc/self/uid_map
0 100000 65536
使用 --network-host
的 Docker 構建操作和 Docker buildx 許可權(network.host
、security.insecure
)也被阻止。
受保護的繫結掛載
增強型容器隔離支援標準檔案共享,同時防止訪問敏感的 VM 目錄。
主機目錄掛載繼續有效
$ docker run -it --rm -v $HOME:/mnt alpine
/ # ls /mnt
# Successfully lists home directory contents
VM 配置掛載被阻止
$ docker run -it --rm -v /etc/docker/daemon.json:/mnt/daemon.json alpine
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: error in the container spec: can't mount /etc/docker/daemon.json because it's configured as a restricted host mount: unknown
這可以防止容器讀取或修改 Docker Engine 配置、登錄檔訪問管理設定、代理配置以及其他與安全相關的 VM 檔案。
注意預設情況下,ECI 會阻止繫結掛載 Docker Engine 套接字(/var/run/docker.sock),因為這會授予容器對 Docker Engine 的控制權。管理員可以為受信任的容器映象建立例外。
高階系統呼叫保護
增強型容器隔離攔截敏感系統呼叫,防止容器惡意使用合法功能。
$ docker run -it --rm --cap-add SYS_ADMIN -v $HOME:/mnt:ro alpine
/ # mount -o remount,rw /mnt /mnt
mount: permission denied (are you root?)
即使擁有 CAP_SYS_ADMIN
能力,容器也無法將只讀繫結掛載更改為讀寫,從而確保它們無法突破容器邊界。
容器仍可在其檔案系統內建立內部掛載
/ # mkdir /root/tmpfs
/ # mount -t tmpfs tmpfs /root/tmpfs
/ # mount -o remount,ro /root/tmpfs /root/tmpfs
/ # findmnt | grep tmpfs
├─/root/tmpfs tmpfs tmpfs ro,relatime,uid=100000,gid=100000
ECI 透過僅攔截控制路徑系統呼叫(很少使用)來高效執行系統呼叫過濾,同時不影響資料路徑系統呼叫,從而保持容器效能。
自動檔案系統使用者 ID 對映
增強型容器隔離透過自動檔案系統對映解決了具有不同使用者 ID 範圍的容器之間的檔案共享挑戰。
每個容器都獲得獨佔的使用者 ID 對映,但 Sysbox 透過 Linux 核心 ID 對映掛載(2021 年新增)或替代的 shiftsfs 模組執行檔案系統使用者 ID 重新對映。這會將容器實際使用者 ID 的檔案系統訪問對映到標準範圍,從而實現:
- 跨不同使用者 ID 範圍的容器共享卷
- 無論容器使用者 ID 對映如何,都保持一致的檔案所有權
- 無需使用者干預即可透明地訪問檔案
透過檔案系統模擬隱藏資訊
ECI 模擬容器內 `/proc` 和 `/sys` 檔案系統的部分內容,以隱藏敏感主機資訊並提供每個容器的核心資源檢視。
$ docker run -it --rm alpine
/ # cat /proc/uptime
5.86 5.86
這顯示的是容器的執行時間,而不是 Docker Desktop VM 的執行時間,從而防止系統資訊洩露到容器中。
Linux 核心未名稱空間化的幾個 `/proc/sys` 資源會按容器進行模擬,Sysbox 在程式設計核心設定時會協調這些值。這使得通常需要特權訪問的容器工作負載能夠安全執行。
效能和相容性
增強型容器隔離保持最佳化的效能和完全相容性。
- 無效能影響:系統呼叫過濾僅針對控制路徑呼叫,不影響資料路徑操作。
- 完全工作流相容性:現有開發流程、工具和容器映象無需更改即可工作。
- 高階工作負載支援:Docker-in-Docker、Kubernetes-in-Docker 和其他複雜場景可安全工作。
- 自動管理:使用者 ID 對映、檔案系統訪問和安全策略均自動處理。
- 標準映象支援:無需特殊容器映象或修改。
重要ECI 保護因 Docker Desktop 版本而異,目前尚未保護擴充套件容器。Docker 構建和 Docker Desktop 中的 Kubernetes 的保護級別因版本而異。有關詳細資訊,請參閱增強型容器隔離限制。