真正起作用的是运行时强制拦截:Seccomp掐断危险系统调用,AppArmor锁死文件、网络和能力访问;两者配合可使被攻破容器无法操作关键资源。
Linux 容器的内核安全不能只靠“不以 root 运行”或“扫镜像漏洞”来应付。真正起作用的是运行时层面的强制拦截:Seccomp 负责掐断危险系统调用,AppArmor 负责锁死文件、网络和能力访问。两者配合,能让即使被攻破的容器也动不了关键资源。
Seccomp 是内核提供的轻量级过滤机制,通过 BPF 程序在系统调用入口处做判断。默认 Docker 的 seccomp 配置已禁用 init_module、ptrace、mount、umount、keyctl 等高危调用,但生产环境需进一步收紧:
"defaultAction": "SCMP_ACT_ERRNO" 设为默认动作,未明确允许的调用一律返回 EPERM
clone(带 CLONE_NEWUSER)、mount、chroot 等逃逸关键调用,使用 "SCMP_ACT_KILL_PROCESS" 直接终止整个进程SeccompProfilePath = "/etc/containerd/seccomp/restrictive.json"
docker run --security-opt seccomp=... --rm -it alpine strace -e trace=... 观察真实调用,再裁剪 default.jsonAppArmor 按路径限制进程行为,配置直观但生效依赖严格流程。它不是写完 profile 就自动起效,必须加载、验证、挂载三步到位:
/etc/apparmor.d/ 下,命名需将二进制路径中的 / 替换为 .(如 /usr/bin/containerd → usr.bin.containerd)/var/log/myapp/** rw,;避免 /var/** 这类宽泛写法deny /proc/sys/** wklx,、deny /sys/fs/cgroup/** w,、deny /dev/kmsg r,
capability sys_admin 或 capability dac_override,除非绝对必要;网络只开 network inet tcp, 这类具体协议无论是 Docker、containerd 还是 Kubernetes,启用后必须确认策略真正在 enforce 状态下运行:
--security-opt seccomp=/path/to/profile.json --security-opt apparmor=my-profile
container.apparmor.security.beta.kubernetes.io/<container-name>: localhost/my-profile
sudo aa-status 查 profile 是否在 “profiles in enforce mode” 列表;sudo dmesg | grep -i denied 查拦截日志sudo apparmor_parser -r /etc/apparmor.d/my-profile 重载;若 containerd 不识别,确认其配置中启用了 AppArmor 支持(enable_apparmor = true)很多配置看似启用,实则形同虚设。以下细节决定防护是否真实落地:
--security-opt apparmor=unconfined,哪怕调试也不推荐;临时测试可用 complain 模式:sudo aa-complain /path/to/binary
--security-opt apparmor=xxx 中的 xxx 完全一致,且不含路径前缀(如 localhost/xxx 是 Kubernetes 注解格式,profile 文件名仍是 xxx)/proc/sys,两者缺一不可runc、containerd)也应有对应 AppArmor profile,否则攻击者可能绕过容器策略直接攻击运行时