普通用户应通过visudo配置四要素权限:用户、主机、目标身份、绝对路径命令,禁用shell逃逸命令,用别名提升可维护性,并验证权限。

要让普通用户只能执行特定命令(比如重启服务、查看日志),不能获得完整 root 权限,关键不是加一行 ALL=(ALL) ALL,而是用 visudo 写明“谁、在哪、以谁身份、能运行哪些具体命令”——四要素缺一不可,路径必须绝对,且要防参数滥用。
用 visudo 编辑,别直接改文件
sudoers 文件语法极其严格,写错一个空格或括号就可能锁死 sudo。必须用 sudo visudo(root 下)或 sudo -u root visudo(已有 sudo 权限的用户),它会在保存前自动校验。编辑前建议先备份:sudo cp /etc/sudoers /etc/sudoers.bak.$(date +%s)
也可以把规则单独写进 /etc/sudoers.d/ 目录下的文件,比如:sudo visudo -f /etc/sudoers.d/webadmin
写清楚四要素:用户、主机、目标身份、命令路径
每条规则格式固定:用户名 主机=(目标用户) 命令列表
- 用户名可以是单个用户(如
deployer)或组(如%devops,注意前缀 %) - 主机一般写
ALL,生产环境可限定为web01或192.168.1.0/24 - 目标用户括号里写明确身份,例如
(www-data)表示只能以 www-data 身份运行,不写或写(ALL)风险更高 - 命令必须用绝对路径,
/usr/bin/systemctl≠systemctl;多个命令用英文逗号分隔
示例:deployer ALL=(www-data) /usr/bin/systemctl reload nginx, /usr/bin/journalctl -u nginx -n 50
限制参数和拦截危险操作
只写命令名不够,还得防绕过:alice ALL=(root) /usr/bin/cat /var/log/*.log, !/usr/bin/rm /var/log/*
表示允许查看所有日志,但禁止删除任何日志文件。
- 用
!排除特定命令或参数组合 - 对有 shell 逃逸能力的命令(如
/bin/bash、/usr/bin/python3 -c、/usr/bin/less)坚决不放行 - 避免通配符泛匹配:
/usr/bin/*或/bin/sh是高危写法,应显式列出每个合法路径 - 如需分页查看日志,可用
Defaults!PAGERS noexec禁用子进程,防止通过less调起 shell
用别名提升可维护性
多人多命令时,硬编码规则难管理。推荐在 /etc/sudoers.d/ 中定义别名:
- 定义命令别名:
Cmnd_Alias DB_CMD = /usr/bin/mysql, /usr/bin/mysqldump, /usr/bin/mysqladmin - 定义用户别名:
User_Alias DB_TEAM = alice, bob, charlie - 绑定授权:
DB_TEAM ALL=(root) DB_CMD
后续增减命令或人员,只需改别名定义,不用动权限行本身。
配置完务必验证:
切换到该用户,运行 sudo -l 查看被授权的命令列表;再实际执行一两个授权命令,确认能跑通、没越权。日志会记录每次 sudo 使用,可通过 journalctl -u sudo 或 /var/log/auth.log 审计。











