优先使用 /etc/security/limits.d/ 而非 limits.conf,因其支持模块化管理、按字母顺序加载且后配置覆盖前配置,避免污染主文件、便于审计和版本控制,并默认被主流发行版pam加载。

直接在 /etc/security/limits.d/ 下新建配置文件,专为高危账号(如运维、开发、测试类账户)设置独立、严格的 nproc 限制,是最清晰、可维护性最强的防 fork 炸弹做法。它避免污染主配置,支持按需启用/禁用,也便于审计和版本管理。
为什么优先用 limits.d 而非 limits.conf
/etc/security/limits.d/ 是设计用于模块化管理的目录,系统按字母顺序加载其中的 .conf 文件,后加载的同项配置会覆盖先加载的。相比直接改 limits.conf:
- 不破坏原始配置,升级系统时不易被覆盖
- 可为不同用途建不同文件,比如
10-admins.conf、20-devs.conf、99-default.conf - 禁用某类限制只需重命名或移除文件,无需注释多行
- 多数发行版(如 CentOS/RHEL 7+、Ubuntu 18.04+)默认已通过
system-auth或common-session加载该目录
具体配置步骤(以限制账号 alice 和组 devs 为例)
执行以下操作(需 root 权限):
- 创建专用配置文件:
sudo tee /etc/security/limits.d/20-highrisk-nproc.conf alice soft nproc 150<br>alice hard nproc 150<br>@devs soft nproc 200<br>@devs hard nproc 200<br>EOF
- 确认 PAM 已加载该目录:运行
grep -r "limits.d" /etc/pam.d/{sshd,login,system-auth},应看到类似session required pam_limits.so的行(主流发行版默认已启用) - 切换用户验证:
su - alice -c 'ulimit -u',输出应为150;若仍显示默认值(如 4096),说明未重新登录或 PAM 未生效
关键细节与避坑点
仅写 soft 不够,仅写 hard 也不行——必须两者都设,且 hard ≥ soft:
- 软限制是用户登录后实际生效的初始值;硬限制是不可逾越的天花板
- 如果只设
hard nproc 150,用户登录后ulimit -u仍可能显示 4096(继承自系统默认),因为软限制没被覆盖 - root 用户不受
*或组规则影响,如需限制 root,必须显式写root soft/hard nproc 1000 - 慎用通配符
*给高危账号设兜底限制,否则可能误限syslog、dbus等服务账户,导致cron失效或用户 session 异常
配套验证与应急响应
配置不是一劳永逸,需主动验证是否真正起作用:
- 测试 fork 炸弹拦截:在目标账号下运行
:(){ :|:& };:,几秒内应报bash: fork: Resource temporarily unavailable - 检查进程树上限:运行
ps -U alice --no-headers | wc -l,接近但不超过设定值即正常 - 临时应急可用
ulimit -u 50快速压制当前会话,但仅限排查或抢救,不能替代持久配置 - 容器环境不适用此法——Docker/Podman 中需用
--pids-limit=150,宿主机的limits.d对容器内进程无约束力











