真正可靠的做法是采用命令级白名单机制:只授权必要命令的绝对路径,禁用通配符和ALL,明确列出如/usr/bin/systemctl restart nginx等具体操作,不支持按-rf等参数做黑名单拦截。

不能靠“禁止 rm -rf”来实现安全,因为 sudoers 语法不支持按命令选项(如 -rf)做细粒度拦截。直接写 !/bin/rm -rf 是无效的,sudo 会忽略带空格和参数的否定规则。真正可靠的做法是:只授权必要命令的绝对路径,且默认拒绝一切未明确列出的操作——即采用白名单机制,而非在 ALL 基础上黑名单剔除。
只授权明确需要的命令,禁用通配符和 ALL
不要使用 ALL 或 /bin/rm * 这类宽泛写法。例如,若用户只需查看日志,就只给 /usr/bin/tail 和 /usr/bin/cat;若需重启服务,只列具体 systemctl 子命令:
alice ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx- 不写
/usr/bin/systemctl *,避免覆盖systemctl reboot或systemctl kill等危险操作 - 不写
NOPASSWD: ALL,哪怕加了! /bin/rm也形同虚设
用绝对路径 + 参数约束替代模糊匹配
某些场景确实需允许有限制的 rm,比如清理自己上传目录下的临时文件。此时应限定路径范围和参数形式:
-
bob ALL=(root) /bin/rm -f /tmp/bob_*.log—— 允许带-f删除指定模式日志 -
carol ALL=(root) /bin/rm /var/www/uploads/carol/*.tmp—— 不带选项,仅删特定后缀、固定目录下文件 - 所有路径必须是完整绝对路径,且目标目录不可被用户写入父级(如
/var/www/uploads/carol的属主应为 root,权限 755)
结合组策略与最小权限原则统一管控
多租户环境下,按职能分组比逐个用户配置更可持续:
- 创建专用组:
groupadd sftpops,把相关用户加入:usermod -aG sftpops alice - 在
/etc/sudoers中统一授权:%sftpops ALL=(root) /usr/bin/systemctl restart vsftpd, /usr/bin/tail -n 100 /var/log/vsftpd.log - 新用户加入该组即继承权限,无需修改 sudoers;移出组即自动失效
- 禁止该组访问
/bin/rm、/bin/chmod、/usr/bin/find等高危命令,不列入白名单即不可用
补充加固:系统层限制无法绕过 sudo 的破坏行为
即便 sudo 配置严谨,仍需防止用户通过其他方式间接执行危险操作:
- 用
chattr +i锁定关键目录(如/etc、/root、/boot),使 root 权限也无法删除或修改 - 设置
fs.protected_hardlinks=1和fs.protected_symlinks=1(写入/etc/sysctl.conf),缓解符号链接攻击 - 对挂载点启用
noexec或nosuid(如/tmp、/var/tmp),阻止执行恶意二进制 - 审计日志开启:
auditctl -w /bin/rm -p x -k rm_exec,记录任何调用行为,便于事后追溯

















