推荐使用 /etc/sudoers.d/ 目录拆分管理 sudo 权限,避免直接修改 /etc/sudoers;需满足文件名不以.或~开头、权限为0440、语法经 visudo -cf 校验三个条件。

服务器上管理 sudo 权限,不建议直接改 /etc/sudoers 主文件——它结构敏感、易出错,且难以追踪变更。现代运维的主流做法是用 /etc/sudoers.d/ 目录做权限拆分:按用户、角色或业务功能,把权限规则写进独立文件,由系统自动包含生效。
为什么用 sudoers.d 而不是直接改主文件
sudo 从 1.7.2 版本起就支持 #includedir /etc/sudoers.d 指令(默认已启用)。它的优势很实在:
- 避免语法错误导致整个 sudo 失效:单个文件出错,只影响该规则,主配置仍可用
- 权限变更可版本化:每个
.sudoers文件可单独提交 Git,记录谁在何时加了哪条权限 - 多人协作更安全:不同团队(如 DBA、SRE、安全组)各自维护自己的片段,互不干扰
- 便于 Ansible/Puppet 等工具批量部署和回滚
/etc/sudoers.d/ 的硬性要求
这个目录下文件不是“随便放就能生效”的,必须满足三个条件:
- 文件名不能以点(
.)或波浪号(~)开头,否则被忽略 - 文件权限必须是
0440(即-r--r-----),只有 root 可读;否则 sudo 启动时会跳过并报 warning - 内容必须通过
visudo -cf 文件路径校验语法正确,否则不会加载
典型权限拆分实战示例
假设你有三类运维人员:数据库管理员(dba)、应用部署员(deploy)、日志分析员(logview)。可以这样拆分:
-
/etc/sudoers.d/dba-mysql:dba ALL=(mysql) NOPASSWD: /usr/bin/mysql, /usr/bin/mysqldump -
/etc/sudoers.d/deploy-nginx:deploy ALL=(root) NOPASSWD: /usr/bin/systemctl start nginx, /usr/bin/systemctl reload nginx -
/etc/sudoers.d/logview-access:logview ALL=(root) NOPASSWD: /bin/cat /var/log/app/*.log, /usr/bin/zcat /var/log/app/*.log.gz
每条规则都限定到具体命令、目标用户、免密开关,不开放 shell 或通配符路径(如 /bin/sh、/usr/bin/*),符合最小权限原则。
验证与日常维护要点
新增或修改后,务必执行以下检查:
- 用
sudo -l -U username查看某用户实际获得的权限列表 - 用
sudo -n -l -U username测试是否真免密(-n表示不提示输入密码) - 定期运行
sudo visudo -c全局校验所有 sudoers 文件语法 - 禁止在
/etc/sudoers.d/下留空文件、备份文件(如deploy.bak)或临时测试文件
不复杂但容易忽略。拆分不是为了多建几个文件,而是让每一份权限都清晰、可审计、可撤销。

















