必须通过visudo配置白名单规则:先确认sudo/wheel组状态并排除组授权,再以绝对路径添加NOPASSWD单命令或Cmnd_Alias批量授权,最后启用NOEXEC、secure_path和显式拒绝确保安全。

要在Linux中让普通用户仅能执行特定管理命令(如重启服务、挂载设备),又不暴露完整root权限,必须通过visudo精确配置白名单式规则,跳过组授权这类宽泛方式。
确认系统默认sudo组并验证用户归属
先查清当前发行版默认的sudo权限组名:Ubuntu/Debian系用sudo,RHEL/CentOS/Fedora系用wheel。运行grep -E '^(%sudo|%wheel)' /etc/sudoers可快速定位。
若输出含%sudo ALL=(ALL:ALL) ALL,说明系统已启用sudo组机制;若只有%wheel且无注释说明,则该系统走wheel路线。
执行groups username确认目标用户是否已在对应组中——如果已在,此路径无法实现“受限”,必须放弃组授权,进入手动规则配置。
用visudo添加单命令白名单规则
以root身份运行sudo visudo,在文件末尾插入新行:
username ALL=(root) NOPASSWD: /bin/systemctl restart nginx, /usr/bin/apt update
注意这里用了NOPASSWD:前缀,表示这两条命令免密执行;若需每次输密码,删掉该关键词即可。每条命令必须写全路径,systemctl不能简写为systemctl,否则规则无效。
【必须用绝对路径,相对路径或别名会导致sudo拒绝执行】
保存退出后,立即切换至该用户,运行sudo -l查看生效权限列表,确认只列出你刚写的那两条命令。
用Cmnd_Alias定义命令别名批量管理
当受限命令超过3个,或未来要增删频繁时,用别名更清晰易维护。
第一步:在/etc/sudoers文件顶部空白处(注释块之后、User privilege specification之前)添加:
Cmnd_Alias WEB_CMD = /bin/systemctl start nginx, /bin/systemctl stop nginx, /bin/systemctl reload nginx, /usr/bin/nginx -t
第二步:在文件末尾添加授权行:
username ALL=(root) NOPASSWD: WEB_CMD
这样所有nginx相关操作就收束在一个逻辑单元里,后续只需修改WEB_CMD定义,无需逐条改用户行。
第三步:保存退出,用sudo -U username -l验证,输出中应显示(root) NOPASSWD: WEB_CMD而非展开的具体路径。
禁止用户绕过限制的三项关键措施
方法一:禁用shell通配与管道
在sudoers中同一用户行末尾追加NOEXEC标记:username ALL=(root) NOPASSWD: WEB_CMD, NOEXEC。这能阻止用户通过sudo sh -c "rm -rf /"类方式启动新shell逃逸。
方法二:锁定secure_path防止PATH劫持
检查/etc/sudoers开头是否有Defaults secure_path="..."行。若无,手动加上标准路径:Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"。否则用户可能伪造同名命令放在~/bin下诱骗sudo执行。
方法三:显式拒绝危险命令
在用户规则前插入拒绝行:username ALL=(ALL) !/bin/bash, !/bin/sh, !/usr/bin/python*, !/usr/bin/perl。感叹号表示禁止,优先级高于后面允许行——即使用户被允许多条命令,只要匹配到这一行就立刻拦截。


















