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
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.