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 配置文件。
实际上,此配置文件是一个允许列表,默认拒绝访问系统调用,然后允许特定的系统调用。配置文件通过定义一个 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 配置文件是一个允许列表,其中指定了允许的调用。下表列出了因不在允许列表中而被有效阻止的主要(但非全部)系统调用。表中包含了阻止每个系统调用而非将其列入允许列表的原因。
系统调用 | 描述 |
---|---|
acct | 审计系统调用,可能允许容器禁用自身的资源限制或进程审计。也受 CAP_SYS_PACCT 限制。 |
add_key | 阻止容器使用内核密钥环,该密钥环未进行命名空间隔离。 |
bpf | 拒绝加载可能持久存在的 BPF 程序到内核,已受 CAP_SYS_ADMIN 限制。 |
clock_adjtime | 时间/日期未进行命名空间隔离。也受 CAP_SYS_TIME 限制。 |
clock_settime | 时间/日期未进行命名空间隔离。也受 CAP_SYS_TIME 限制。 |
clone | 拒绝克隆新的命名空间。对于 CLONE_* 标志,已受 CAP_SYS_ADMIN 限制,CLONE_NEWUSER 除外。 |
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 | 拒绝启动/停止向文件/设备交换。也受 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