使用prctl组合PR_SET_NO_NEW_PRIVS和PR_SET_SECCOMP可轻量沙箱化Worker进程:前者禁execve提权,后者通过strict或filter模式限制系统调用;需在fork/exec前设置,并补充禁coredump、设线程名等加固措施。

直接用 prctl 限制 Worker 进程的内核权限,核心是组合使用 PR_SET_NO_NEW_PRIVS 和 PR_SET_SECCOMP 两个选项。它们不依赖 root 权限,可在进程启动早期调用,生效后不可撤销,是构建轻量级沙箱的基础。
禁用权限提升能力(防 execve 提权)
调用 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) 后,该进程及其所有子进程(包括 fork 或 clone 创建的)将无法通过 execve 获得新特权。这意味着:
- 即使二进制文件设置了 setuid/setgid,执行后也不会提权
- 无法加载带文件能力(file capabilities)的程序来绕过限制
- SELinux / AppArmor 等 LSM 的上下文切换也会被拒绝
这一步必须在 fork 子进程前完成,否则子进程可能继承未设限的状态。
启用 seccomp 沙箱(白名单系统调用)
有两种常用方式,按安全强度和灵活性区分:
-
严格模式(SECCOMP_MODE_STRICT):仅允许
read、write、exit、sigreturn四个调用。调用prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)即可,无需额外参数,适合极简场景 -
过滤模式(SECCOMP_MODE_FILTER):用 BPF 规则自定义允许的系统调用及参数。需配合
seccomp_init、seccomp_rule_add等 libseccomp 函数,例如只放行read、write、clock_gettime和getpid,其他一律KILL
注意:过滤模式下,若规则未显式允许 rt_sigreturn 或 sigreturn,信号处理会失败,导致进程异常终止。
配套加固:关闭核心转储与命名控制
仅靠权限和系统调用限制还不够,建议补充以下两项:
- 调用
prctl(PR_SET_DUMPABLE, 0)禁止生成 core dump,防止内存敏感信息泄露 - 调用
prctl(PR_SET_NAME, "worker-sandbox")设置线程名,便于监控识别,避免被误杀或混淆
这些操作都应在 Worker 进程初始化完成、业务逻辑开始前一次性执行完毕。
实际部署注意事项
Worker 进程若由父进程 fork 后 exec 启动,必须确保:
- 父进程在 fork 前已设置
PR_SET_NO_NEW_PRIVS,否则子进程不会继承 - seccomp 规则必须在 exec 之后、业务代码运行之前加载,否则动态链接库初始化阶段可能触发非法系统调用
- 如 Worker 使用多线程,每个线程都应独立设置
PR_SET_NAME,避免 ps/top 中显示混乱
不复杂但容易忽略

















