Docker 的 Seccomp 安全配置檔案

安全計算模式(seccomp)是 Linux 核心的一項功能。您可以使用它來限制容器內可用的操作。seccomp() 系統呼叫作用於呼叫程序的 seccomp 狀態。您可以使用此功能來限制您的應用程式的訪問許可權。

僅當 Docker 使用 seccomp 構建並且核心已啟用 CONFIG_SECCOMP 時,此功能才可用。要檢查您的核心是否支援 seccomp

$ grep CONFIG_SECCOMP= /boot/config-$(uname -r)
CONFIG_SECCOMP=y

為容器傳遞配置檔案

預設的 seccomp 配置檔案為使用 seccomp 執行容器提供了一個合理的預設設定,並在 300 多個系統呼叫中停用了大約 44 個。它在提供廣泛的應用程式相容性的同時,具有適度的保護性。預設的 Docker 配置檔案可以在這裡找到。

實際上,該配置檔案是一個白名單,預設情況下拒絕訪問系統呼叫,然後允許特定的系統呼叫。該配置檔案的工作方式是定義一個 defaultActionSCMP_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 配置檔案是一個白名單,它指定了允許的呼叫。下表列出了因未在白名單上而被有效阻止的重要(但不是全部)系統呼叫。該表包含了每個系統呼叫被阻止而不是被列入白名單的原因。

系統呼叫描述
acct記賬系統呼叫,可能讓容器停用自己的資源限制或程序記賬。也受 CAP_SYS_PACCT 限制。
add_key防止容器使用核心金鑰環,該金鑰環沒有名稱空間化。
bpf拒絕將可能持久的 BPF 程式載入到核心中,已受 CAP_SYS_ADMIN 限制。
clock_adjtime時間/日期沒有名稱空間化。也受 CAP_SYS_TIME 限制。
clock_settime時間/日期沒有名稱空間化。也受 CAP_SYS_TIME 限制。
clone拒絕克隆新的名稱空間。對於 CLONE_* 標誌,除了 CLONE_NEWUSER 外,也受 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_loadkexec_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拒絕啟動/停止到檔案/裝置的交換。也受 CAP_SYS_ADMIN 限制。
swapoff拒絕啟動/停止到檔案/裝置的交換。也受 CAP_SYS_ADMIN 限制。
sysfs已過時的系統呼叫。
_sysctl已過時,被 /proc/sys 取代。
umount應為特權操作。也受 CAP_SYS_ADMIN 限制。
umount2應為特權操作。也受 CAP_SYS_ADMIN 限制。
unshare拒絕為程序克隆新的名稱空間。也受 CAP_SYS_ADMIN 限制,除了 unshare --user
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