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跟踪/分析系统调用。在 4.8 之前的 Linux 内核版本中被阻止以避免 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:jessie \
    unshare --map-root-user --user sh -c whoami