应通过/etc/sudoers精确授权,仅允许指定用户用绝对路径执行特定systemctl restart命令,禁用关机类命令,并用Cmnd_Alias统一管理、显式排除高危操作,配置后须用sudo -l验证。

要让普通用户只能通过 sudo 重启特定服务(比如 nginx 或 redis),不能关机、不能重启系统、也不能操作其他服务,核心是不给权限,只开一条缝——用 /etc/sudoers 做精确白名单授权。
必须写绝对路径,且参数固定
sudoers 不解析命令逻辑,只做字符串匹配。所以不能写 systemctl restart *,也不能只写 systemctl。必须明确到完整路径 + 完整参数:
devuser ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart redis
-
/usr/bin/systemctl是 systemd 的实际路径(不是/bin/systemctl,不同发行版可能不同,先用which systemctl确认) -
restart nginx是完整子命令,中间不能有空格变量、通配符或 shell 转义 - 多个命令用英文逗号分隔,末尾不加空格
推荐用 Cmnd_Alias 统一管理
当要授权的服务变多(比如 nginx、redis、haproxy、postgresql),直接在用户行里列太乱。改用别名更清晰、易维护:
Cmnd_Alias RESTART_WEB = /usr/bin/systemctl restart nginx, \
/usr/bin/systemctl restart haproxy, \
/usr/bin/systemctl restart php-fpm
%webops ALL=(root) NOPASSWD: RESTART_WEB-
Cmnd_Alias定义在/etc/sudoers文件靠前位置(在任何用户规则之前) -
\表示续行,提高可读性 -
%webops表示webops用户组,所有组员自动获得这些权限
显式禁止高危命令,防绕过
光“允许重启”不够,还要防止用户执行 sudo systemctl reboot 或 sudo reboot。最稳妥方式是显式排除:
Cmnd_Alias SHUTDOWN_CMDS = /sbin/shutdown, /sbin/reboot, /sbin/halt, \
/sbin/poweroff, /usr/bin/systemctl reboot, \
/usr/bin/systemctl poweroff, /usr/bin/systemctl halt
devuser ALL=(ALL) ALL, !SHUTDOWN_CMDS- 这条规则表示:“允许全部命令,但明确禁止
SHUTDOWN_CMDS列表里的每一条” - 注意顺序:这条规则必须放在通用授权规则(如
%sudo ALL=(ALL:ALL) ALL)之后,否则会被提前匹配跳过
验证是否生效
配置完别急着退出,立即验证:
- 查看该用户实际能执行什么:
sudo -l -U devuser - 测试允许的命令:
sudo systemctl restart nginx→ 应成功 - 测试被禁的命令:
sudo systemctl restart mysql→ 应提示“command not allowed”sudo reboot→ 应拒绝
同时检查日志确认拦截:sudo grep "COMMAND" /var/log/auth.log | tail -5
补充建议
- 所有修改必须用
sudo visudo编辑,避免语法错误锁死 sudo - 如果用户属于
sudo或wheel组,且该组已有宽泛规则(如%sudo ALL=(ALL:ALL) ALL),你的精细规则可能被覆盖——务必把新规则放在该行之前 - 想免输密码?在命令前加
NOPASSWD:,格式为:devuser ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx - 不要依赖别名或函数封装,
sudoers只认真实路径和静态参数
不复杂但容易忽略


















