chroot解决文件系统路径隔离问题,仅限制进程可见的根目录及子目录;seccomp解决系统调用行为控制问题,通过内核级过滤器禁止危险syscall,两者分别管控“能看什么”和“能做什么”,协同实现轻量级安全隔离。

chroot 和 seccomp 各自解决什么问题
chroot 只改进程看到的“根目录”,让程序只能访问指定目录下的文件,但它不碰系统调用、不隔离进程、不限制网络或权限。一个有 root 权限的进程在 chroot 环境里仍能调用 mount、clone、ptrace 等危险 syscall,轻松逃逸。
seccomp 则相反:它不管文件路径、不管用户身份、也不管网络端口,只专注拦截系统调用。哪怕进程在宿主机根目录下运行,只要加载了 seccomp 过滤器,调用 reboot 或 unshare 就会直接被内核拒绝(或终止)。
两者互补——chroot 控制“能看什么文件”,seccomp 控制“能做什么操作”。合起来,才构成更扎实的轻量级隔离。
手动组合:先 chroot 再加载 seccomp
关键点是顺序和权限:必须在 chroot 之后、执行业务逻辑之前加载 seccomp 规则,且进程需已放弃特权(如调用 prctl(PR_SET_NO_NEW_PRIVS, 1)),否则内核会拒绝安装 BPF 过滤器。
- 准备一个最小根环境:
debootstrap --variant=minbase jammy /mnt/chroot http://archive.ubuntu.com/ubuntu/ - 挂载必要伪文件系统:
mount -t proc proc /mnt/chroot/proc、mount -t sysfs sysfs /mnt/chroot/sys - 进入环境并启用 seccomp:
chroot /mnt/chroot /bin/bash -c 'prctl --set-no-new-privs && ./my_sandboxed_app' - 你的 my_sandboxed_app 需在代码中调用
seccomp_init(SCMP_ACT_KILL),添加允许的 syscall(如 read、write、exit_group),最后seccomp_load()
容器中协同使用(Docker/Kubernetes)
Docker 原生支持两者叠加。chroot 效果由容器镜像文件系统天然提供(即每个容器都有独立的 rootfs),seccomp 则通过 JSON profile 加载:
- 写一个 seccomp profile,设
"defaultAction": "SCMP_ACT_ERRNO",只放行必需 syscall(例如 openat、mmap、getpid) - 禁用高危调用:
"name": "capset"、"name": "setns"、"name": "pivot_root"(后者可防绕过 chroot 的尝试) - 启动容器:
docker run --security-opt seccomp=./profile.json --read-only --cap-drop=ALL ubuntu:22.04 sh -c 'cat /etc/os-release' - 注意:
--read-only和--cap-drop是对 chroot 级隔离的强化,配合 seccomp 后,即使攻击者突破应用层,也极难完成提权或逃逸
常见陷阱与验证方法
容易忽略但后果严重的问题:
- chroot 后未重新挂载
/proc和/sys→ seccomp 初始化可能失败(因依赖/proc/self/status等) - seccomp profile 中遗漏 sigreturn 或 rt_sigreturn → 多线程程序立即崩溃(信号返回是系统调用链关键环节)
- 在容器中启用 seccomp 但未关闭
no_new_privs→ 某些旧版内核会静默跳过过滤器
验证是否生效:docker exec -it <container> cat /proc/1/status | grep Seccomp 应显示 2(表示 seccomp-BPF 已启用);再用 strace -e trace=reboot,unshare your_binary 确认调用被拦截。


















