cmnd_alias 是为高危命令定义不可扩展的绝对路径别名,需绑定用户/组才生效,并配合 ! 否定、noexec 等机制加固。如 reboot_cmd = /sbin/shutdown -r now, /sbin/reboot;%ops all = (root) nopasswd: reboot_cmd, !escape。

Cmnd_Alias 不是“让 sudo 使用别名”,而是你在 /etc/sudoers 或 /etc/sudoers.d/ 文件里,用它来给一组高危命令起个统一、可复用的名字,后续所有授权、限制、审计都基于这个名字展开——相当于把零散的危险操作打包成一个“指令集”,再整体管控。
定义时必须写死路径和参数
高危命令(如 reboot、rm、systemctl)一旦参数放开,就等于开放 root 权限。所以 Cmnd_Alias 的每一条命令都得是完整、绝对、不可扩展的形式:
- ✅ 正确:
Cmnd_Alias REBOOT_CMD = /sbin/shutdown -r now, /sbin/reboot - ✅ 正确(带服务名限定):
Cmnd_Alias NGINX_CTRL = /bin/systemctl start nginx, /bin/systemctl reload nginx - ❌ 错误:
/bin/systemctl restart *(通配符可能匹配 mysql 或 sshd) - ❌ 错误:
rm -rf /(没写路径,sudo 不认;且参数不全、无约束) - ❌ 错误:
/bin/rm -rf /*(通配符覆盖根目录,等同于删库)
把别名和用户/组绑定才真正生效
Cmnd_Alias 本身只是命名,不授予权限。你需要用系统组(推荐)或 User_Alias 把它连起来:
- 直接授权运维组:
%ops ALL = (root) NOPASSWD: REBOOT_CMD, NGINX_CTRL - 按角色分组更清晰:
User_Alias DEPLOYERS = %deploy,再写DEPLOYERS app-servers = (root) NOPASSWD: NGINX_CTRL - 限制执行身份:
%dbadmin db-node-01 = (postgres) NOPASSWD: PG_BACKUP(只允许以 postgres 身份在指定机器跑备份)
用 ! 否定机制封死逃逸路径
光列白名单不够,还得主动拦截常见提权入口。最佳实践是单独定义一个逃逸命令别名,再全局禁止:
- 先定义:
Cmnd_Alias ESCAPE = /bin/bash, /bin/sh, /usr/bin/python3 -c *, /usr/bin/perl -e *, /usr/bin/find * -exec sh \; - 再禁止:
%ops ALL = (ALL) !ESCAPE - 关键细节:否定项必须和白名单出现在同一授权行,或至少确保它不被后续宽松规则覆盖(建议放在
/etc/sudoers.d/05-restrict这类靠前文件中)
配套加固不能省
别名再严谨,若执行环境松动,照样被绕过:
- 启用
Defaults noexec:阻止命令内部调用 shell(如 less 中按 ! 执行命令) - 设置
Defaults requiretty:禁止 cron、webshell 等非终端场景提权 - 确认
secure_path包含你写的命令路径,否则 sudo 会拒绝执行 - 所有修改必须用
sudo visudo或sudo visudo -f /etc/sudoers.d/xxx编辑,避免语法错误锁死 sudo











