核心是“脚本可执行但不可修改”——需同时满足授权执行路径、严格属主权限和文件系统级防护。具体包括:在 /etc/sudoers.d/deploy 中配置绝对路径无参命令;脚本设为 root:root 且权限 0755;用 setfacl 限制用户写权;目录设为 root 所有且 0755;验证 sudo -l、权限拒绝及执行成功。

核心是“脚本可执行但不可修改”——授权执行路径 + 严格属主权限 + 文件系统级防护,三者缺一不可。
只授权绝对路径的无参脚本
在 /etc/sudoers.d/ 下新建配置(如 /etc/sudoers.d/deploy),用 visudo 编辑:
- 写法必须是 deploy ALL=(root) NOPASSWD: /opt/scripts/deploy.sh —— 路径绝对、无引号、无参数、无通配符
- 禁止写成 /opt/scripts/deploy.sh --prod 或 /opt/scripts/*.sh,否则存在参数注入或路径遍历风险
- 确认主 /etc/sudoers 包含 #includedir /etc/sudoers.d,且子配置文件权限为 0440
脚本本身设为 root 所有且不可写
普通用户能执行 ≠ 能改内容。执行前必须固化脚本所有权和权限:
- sudo chown root:root /opt/scripts/deploy.sh
- sudo chmod 0755 /opt/scripts/deploy.sh(所有者可读写执行,组和其他仅可读可执行)
- 验证:ls -l /opt/scripts/deploy.sh 应显示 -rwxr-xr-x 1 root root
- 若脚本依赖配置文件(如 /etc/deploy/config.yaml),同样设为 root:root 且权限 ≤ 0600
防止本地绕过:加固文件系统层
仅靠 sudoers 不够,用户可能直接编辑或替换脚本。需叠加防护:
- 用 setfacl 显式禁止目标用户写入:sudo setfacl -m u:deploy:rx /opt/scripts/deploy.sh(保留执行权,撤掉写权)
- 对整个脚本目录加锁:sudo chown root:root /opt/scripts && sudo chmod 0755 /opt/scripts,确保用户无法新建、重命名或删除脚本
- 检查是否启用文件系统 ACL 支持:mount | grep "$(df /opt/scripts | tail -1 | awk '{print $1}')" | grep acl,未启用需在 /etc/fstab 添加 acl 参数并重挂载
验证与日常维护
每次变更后务必实测,避免静默失败:
- 切换到目标用户:sudo -u deploy bash
- 运行 sudo -l -U deploy,确认只列出该脚本,且标记 (NOPASSWD)
- 尝试修改脚本:echo "bad" >> /opt/scripts/deploy.sh 应报 Permission denied
- 尝试执行脚本:sudo /opt/scripts/deploy.sh 应成功,且不提示密码











