Docker 的 Seccomp 安全性設定檔
安全運算模式(seccomp)是一種 Linux 核心功能。您可以使用它來限制容器內可執行的動作。seccomp() 系統呼叫會對呼叫進程的 seccomp 狀態進行操作。您可以使用此功能來限制應用程式的存取權限。
此功能僅在 Docker 建置時包含 seccomp 且核心已啟用 CONFIG_SECCOMP 時才可用。若要檢查您的核心是否支援 seccomp:
$ grep CONFIG_SECCOMP= /boot/config-$(uname -r)
CONFIG_SECCOMP=y
為容器傳遞設定檔
預設的 seccomp 設定檔為執行容器提供了合理的預設值,並禁用了 300 多個系統呼叫中的約 44 個。它在提供廣泛應用程式相容性的同時,具有中等程度的保護能力。Docker 的預設設定檔可以在這裡找到。
實際上,該設定檔是一個允許清單,預設會拒絕所有系統呼叫,隨後再開放特定的系統呼叫。其運作方式是將 defaultAction 定義為 SCMP_ACT_ERRNO,並僅針對特定系統呼叫覆寫該動作。SCMP_ACT_ERRNO 的效果是產生一個「拒絕存取」(Permission Denied) 錯誤。接著,設定檔定義了一份完全允許的系統呼叫清單,因為它們的 action 被覆寫為 SCMP_ACT_ALLOW。最後,針對某些個別系統呼叫(如 personality 等)設有特定規則,以允許在帶有特定參數的情況下執行這些變體呼叫。
seccomp 對於以最小權限執行 Docker 容器至關重要。不建議更改預設的 seccomp 設定檔。
當您執行容器時,除非您使用 --security-opt 選項覆寫它,否則它會使用預設設定檔。例如,以下明確指定了一個策略:
$ docker run --rm \
-it \
--security-opt seccomp=/path/to/seccomp/profile.json \
hello-world
預設設定檔封鎖的重要系統呼叫
Docker 的預設 seccomp 設定檔是一個指定允許呼叫的清單。下表列出了因未包含在允許清單中而實際上被封鎖的重要(但非全部)系統呼叫。該表包含了每個系統呼叫被封鎖而非加入允許清單的原因。
| 系統呼叫 (Syscall) | 描述 |
|---|---|
acct | 帳戶統計系統呼叫,可能讓容器停用自身的資源限制或處理程序統計。同時受 CAP_SYS_PACCT 權限控管。 |
add_key | 防止容器使用未命名空間化的核心金鑰環。 |
bpf | 拒絕將潛在的持續性 BPF 程式載入核心,此操作已受 CAP_SYS_ADMIN 權限控管。 |
clock_adjtime | 時間/日期未命名空間化。同時受 CAP_SYS_TIME 權限控管。 |
clock_settime | 時間/日期未命名空間化。同時受 CAP_SYS_TIME 權限控管。 |
clone | 拒絕複製新的命名空間。除了 CLONE_NEWUSER 旗標外,CLONE_* 旗標皆受 CAP_SYS_ADMIN 權限控管。 |
create_module | 拒絕核心模組的操控與功能。已棄用。同時受 CAP_SYS_MODULE 權限控管。 |
delete_module | 拒絕核心模組的操控與功能。同時受 CAP_SYS_MODULE 權限控管。 |
finit_module | 拒絕核心模組的操控與功能。同時受 CAP_SYS_MODULE 權限控管。 |
get_kernel_syms | 拒絕檢索匯出的核心與模組符號。已棄用。 |
get_mempolicy | 修改核心記憶體與 NUMA 設定的系統呼叫。已受 CAP_SYS_NICE 權限控管。 |
init_module | 拒絕核心模組的操控與功能。同時受 CAP_SYS_MODULE 權限控管。 |
ioperm | 防止容器修改核心 I/O 特權等級。已受 CAP_SYS_RAWIO 權限控管。 |
iopl | 防止容器修改核心 I/O 特權等級。已受 CAP_SYS_RAWIO 權限控管。 |
kcmp | 限制處理程序檢視能力,透過移除 CAP_SYS_PTRACE 已封鎖此功能。 |
kexec_file_load | kexec_load 的姊妹系統呼叫,功能相同但參數略有不同。同時受 CAP_SYS_BOOT 權限控管。 |
kexec_load | 拒絕載入新核心以備後續執行。同時受 CAP_SYS_BOOT 權限控管。 |
keyctl | 防止容器使用未命名空間化的核心金鑰環。 |
lookup_dcookie | 追蹤/剖析系統呼叫,可能洩漏主機上的大量資訊。同時受 CAP_SYS_ADMIN 權限控管。 |
mbind | 修改核心記憶體與 NUMA 設定的系統呼叫。已受 CAP_SYS_NICE 權限控管。 |
mount | 拒絕掛載,已受 CAP_SYS_ADMIN 權限控管。 |
move_pages | 修改核心記憶體與 NUMA 設定的系統呼叫。 |
nfsservctl | 拒絕與核心 NFS 守護程序互動。自 Linux 3.1 起已棄用。 |
open_by_handle_at | 曾導致舊版容器逃逸漏洞。同時受 CAP_DAC_READ_SEARCH 權限控管。 |
perf_event_open | 追蹤/剖析系統呼叫,可能洩漏主機上的大量資訊。 |
personality | 防止容器啟用 BSD 模擬。本身並不危險,但測試不足,存在許多核心漏洞的潛在風險。 |
pivot_root | 拒絕 pivot_root,應為特權操作。 |
process_vm_readv | 限制處理程序檢視能力,透過移除 CAP_SYS_PTRACE 已封鎖此功能。 |
process_vm_writev | 限制處理程序檢視能力,透過移除 CAP_SYS_PTRACE 已封鎖此功能。 |
ptrace | 追蹤/剖析系統呼叫。在 Linux 核心 4.8 以前的版本中被封鎖以避免 seccomp 繞過。由於可能洩漏主機上的大量資訊,對任意處理程序進行追蹤/剖析的功能,已透過移除 CAP_SYS_PTRACE 進行封鎖。 |
query_module | 拒絕核心模組的操控與功能。已棄用。 |
quotactl | 配額系統呼叫,可能讓容器停用自身的資源限制或處理程序統計。同時受 CAP_SYS_ADMIN 權限控管。 |
reboot | 不允許容器重新啟動主機。同時受 CAP_SYS_BOOT 權限控管。 |
request_key | 防止容器使用未命名空間化的核心金鑰環。 |
set_mempolicy | 修改核心記憶體與 NUMA 設定的系統呼叫。已受 CAP_SYS_NICE 權限控管。 |
setns | 拒絕將執行緒關聯至命名空間。同時受 CAP_SYS_ADMIN 權限控管。 |
settimeofday | 時間/日期未命名空間化。同時受 CAP_SYS_TIME 權限控管。 |
stime | 時間/日期未命名空間化。同時受 CAP_SYS_TIME 權限控管。 |
swapon | 拒絕啟動/停止檔案或裝置的交換空間 (swapping)。同時受 CAP_SYS_ADMIN 權限控管。 |
swapoff | 拒絕啟動/停止檔案或裝置的交換空間 (swapping)。同時受 CAP_SYS_ADMIN 權限控管。 |
sysfs | 已棄用的系統呼叫。 |
_sysctl | 已棄用,由 /proc/sys 取代。 |
umount | 應為特權操作。同時受 CAP_SYS_ADMIN 權限控管。 |
umount2 | 應為特權操作。同時受 CAP_SYS_ADMIN 權限控管。 |
unshare | 拒絕為處理程序複製新的命名空間。除 unshare --user 外,同時受 CAP_SYS_ADMIN 權限控管。 |
uselib | 與共用程式庫相關的舊版系統呼叫,已長期未使用。 |
userfaultfd | 使用者空間頁面錯誤處理,主要用於處理程序遷移。 |
ustat | 已棄用的系統呼叫。 |
vm86 | 核心內 x86 真實模式虛擬機器。同時受 CAP_SYS_ADMIN 權限控管。 |
vm86old | 核心內 x86 真實模式虛擬機器。同時受 CAP_SYS_ADMIN 權限控管。 |
在不安裝預設 seccomp 設定檔的情況下執行
您可以傳遞 unconfined 來執行不使用預設 seccomp 設定檔的容器。
$ docker run --rm -it --security-opt seccomp=unconfined debian:latest \
unshare --map-root-user --user sh -c whoami