linux seccomp-bpf 无内核默认策略,进程默认禁用;docker/k8s 的“默认”是各自预定义的白名单策略,自定义需基于实际系统调用行为和最小权限原则裁剪。

Linux seccomp-bpf 没有全局“默认 profile”,其行为完全取决于应用是否显式启用 seccomp 并加载 BPF 过滤器。Docker 和 Kubernetes 的所谓“默认”实为各自预定义的白名单策略,而非内核内置规则;自定义过滤器需基于系统调用语义、容器最小权限原则和实际 workload 行为来编写,不能套用通用模板。
seccomp 在内核中无默认策略
内核本身不提供任何 seccomp 默认配置。进程默认处于 seccomp-disabled 状态(SECCOMP_MODE_DISABLED)。只有当进程调用 prctl(PR_SET_SECCOMP, ...) 或通过 clone/execve 继承已启用的 seccomp 状态时,才进入受限模式。这意味着:
- 裸机上运行的普通进程不受 seccomp 限制
- 未显式配置 seccomp 的容器(如直接用
runC启动且未传入--seccomp)也不会自动启用 - “默认”一词在 seccomp 上下文中仅指 Docker/K8s 工具链的预设策略,非内核行为
Docker 的默认 seccomp profile 是白名单 + 安全裁剪
Docker 20.10+ 内置的默认 profile(default.json)允许约 60–70 个常用系统调用,拒绝其余所有调用(SCMP_ACT_ERRNO),并禁用高风险调用如 ptrace、mount、setuid、syslog 等。关键特点包括:
- 基于 syscall 白名单,而非黑名单 —— 显式列出允许项,其余一律拒绝
- 对
personality、capset、keyctl等能力相关调用默认禁止 - 允许
openat但限制open(因后者更易绕过路径约束) - 对
socket调用按 domain/type/protocol 做细粒度放行(如只允AF_INET,SOCK_STREAM)
可通过 docker run --seccomp-default(显式启用)或 --seccomp ./profile.json 加载自定义文件;禁用则用 --seccomp=unconfined。
Kubernetes 的 seccomp 配置依赖 Pod 安全策略与运行时支持
K8s 本身不解析或执行 seccomp 规则,而是将策略透传给容器运行时(如 containerd 或 CRI-O)。seccomp 配置通过 Pod 或 Container 的 securityContext.seccompProfile 字段声明:
-
type: RuntimeDefault:交由运行时决定(containerd 默认使用与 Docker 相同的 default.json) -
type: Localhost+localhostProfile: "profiles/my-policy.json":从节点本地路径加载 JSON 文件(需提前部署到每个节点的/var/lib/kubelet/seccomp/下) -
type: Unconfined:跳过 seccomp 限制(不推荐)
注意:K8s v1.19+ 才正式支持该字段(GA),且要求 kubelet 启用 SeccompDefault 特性门控(v1.25+ 默认开启)。
编写自定义 seccomp 过滤器的关键实践
有效的自定义 profile 不是靠“加功能”,而是靠“减攻击面”。推荐步骤如下:
-
先观测再限制:用
strace -f -e trace=raw_syscall或auditd+ausearch -m avc -ts recent记录容器真实 syscall 流量,识别必需调用 -
继承 default.json 再裁剪:以 Docker 默认 profile 为起点,用
jq删除明确不需要的条目(如移除chmod若容器只读文件系统) -
慎用
SCMP_ACT_TRACE:在调试阶段可设为 trace 并配合seccomp-tools dump或bpftrace分析被拦截行为,避免误杀 -
按 syscall 参数过滤:例如限制
socket仅允许 TCP/IPv4:"action": "SCMP_ACT_ALLOW", "args": [{"index":0,"value":2,"valueMask":4294967295},{"index":1,"value":1,"valueMask":4294967295}](domain=AF_INET=2, type=SOCK_STREAM=1) -
避免硬编码 errno:用
SCMP_ACT_ERRNO时指定标准错误码(如"errnoRet": 1对应 EPERM),而非随意返回值
工具链建议:用 docker-seccomp CLI 生成初始 profile;用 jq 和 git diff 管理 profile 版本;CI 中集成 check-seccomp 验证 JSON 结构与 syscall 存在性。










