跳转到内容

sudo 配置

适用于 CentOS Stream 9 & 10 / AlmaLinux 9.x & 10.x / Rocky Linux 9.x & 10.x

sudo 允许普通用户以其他用户(通常是 root)的身份执行命令,而无需知道 root 密码。正确配置 sudo 是服务器安全管理的关键环节。

  • sudo 的工作原理和基本使用
  • 使用 visudo 安全编辑 sudoers 文件
  • sudoers 文件语法
  • 为用户和组配置 sudo 权限
  • NOPASSWD 配置
  • sudo 日志审计
  • EL 系统上的 wheel 组
  • 一台已安装 EL 9.x 的系统
  • 当前拥有 sudo 权限或能以 root 登录
  • 了解用户和组管理的基本操作

当你执行 sudo <命令> 时:

  1. 系统检查 /etc/sudoers 文件,确认当前用户是否有权限
  2. 要求用户输入自己的密码(不是 root 密码)
  3. 验证通过后,以目标用户身份(默认 root)执行命令
  4. 执行结果记录到系统日志
以 root 身份执行命令
$ sudo systemctl restart nginx
[sudo] password for admin:
以其他用户身份执行命令
$ sudo -u postgres psql
查看当前用户的 sudo 权限
$ sudo -l

输出示例:

Matching Defaults entries for admin on myserver:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin,
env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS",
secure_path=/sbin:/bin:/usr/sbin:/usr/bin
User admin may run the following commands on myserver:
(ALL) ALL

在 EL 系统中,wheel 组是默认的管理员组。属于 wheel 组的用户拥有完整的 sudo 权限。

查看 wheel 组成员
$ getent group wheel
wheel:x:10:admin
将用户添加到 wheel 组以获得 sudo 权限
$ sudo usermod -aG wheel newadmin

这是 /etc/sudoers 中默认的 wheel 组配置:

查看 sudoers 中的 wheel 配置
$ sudo grep wheel /etc/sudoers
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL

visudo 命令会在保存时自动检查语法错误:

使用 visudo 编辑 sudoers
$ sudo visudo

如果想使用其他编辑器:

使用 vim 作为 visudo 编辑器
$ sudo EDITOR=vim visudo

推荐将自定义配置放在 /etc/sudoers.d/ 目录下,而不是直接修改 /etc/sudoers 主文件:

创建自定义 sudoers 配置
$ sudo visudo -f /etc/sudoers.d/custom-rules

确认主文件中包含了对该目录的引用(EL 9 默认已包含):

确认 sudoers 引用了 sudoers.d 目录
$ sudo grep "includedir" /etc/sudoers
#includedir /etc/sudoers.d
用户 主机=(目标用户:目标组) 命令

各部分说明:

部分说明
用户被授权的用户名,组名前加 %
主机该规则适用的主机,ALL 表示所有主机
目标用户可以切换到的用户,ALL 表示所有用户
目标组可以切换到的组(可选)
命令允许执行的命令,ALL 表示所有命令
允许用户 deploy 执行所有命令
deploy ALL=(ALL) ALL
允许 developers 组的所有成员执行所有命令
%developers ALL=(ALL) ALL
允许用户只执行特定命令
webadmin ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
允许用户以 postgres 身份执行命令
dbadmin ALL=(postgres) ALL
禁止用户执行某些命令
operator ALL=(ALL) ALL, !/usr/bin/su, !/usr/bin/passwd root

当多个用户需要相同的权限时,可以使用别名简化配置:

定义命令别名
Cmnd_Alias WEB_CMDS = /usr/bin/systemctl restart nginx, \
/usr/bin/systemctl reload nginx, \
/usr/bin/systemctl status nginx
Cmnd_Alias PKG_CMDS = /usr/bin/dnf install *, \
/usr/bin/dnf update *, \
/usr/bin/dnf remove *
使用命令别名
webadmin ALL=(ALL) WEB_CMDS
pkgadmin ALL=(ALL) PKG_CMDS

也可以定义用户别名和主机别名:

定义用户别名
User_Alias WEBTEAM = zhangsan, lisi, wangwu
WEBTEAM ALL=(ALL) WEB_CMDS

默认情况下,使用 sudo 需要输入用户自己的密码。可以配置免密码执行:

允许用户执行所有命令无需密码
deploy ALL=(ALL) NOPASSWD: ALL
仅特定命令免密码
monitor ALL=(ALL) NOPASSWD: /usr/bin/systemctl status *, /usr/bin/journalctl
wheel 组免密码(不推荐用于生产环境)
%wheel ALL=(ALL) NOPASSWD: ALL
部分命令免密码,其他需要密码
operator ALL=(ALL) NOPASSWD: /usr/bin/systemctl status *, PASSWD: /usr/bin/systemctl restart *

sudo 的所有操作都会记录到系统日志,这对于安全审计非常重要。

查看 sudo 日志(使用 journalctl)
$ sudo journalctl -u sudo
在 /var/log/secure 中查看 sudo 记录
$ sudo grep sudo /var/log/secure

输出示例:

Mar 24 14:30:22 myserver sudo: admin : TTY=pts/0 ; PWD=/home/admin ; USER=root ; COMMAND=/usr/bin/systemctl restart nginx

可以在 sudoers 中配置额外的日志选项:

编辑 sudoers 添加日志配置
$ sudo visudo -f /etc/sudoers.d/logging
启用 sudo 命令日志
Defaults log_input, log_output
Defaults logfile="/var/log/sudo.log"
Defaults iolog_dir="/var/log/sudo-io/%{seq}"

以下示例展示如何为不同角色配置不同的 sudo 权限。

  1. 创建角色配置文件

    创建自定义 sudoers 文件
    $ sudo visudo -f /etc/sudoers.d/team-roles
  2. 定义命令别名

    # 服务管理命令
    Cmnd_Alias SVC_CMDS = /usr/bin/systemctl start *, \
    /usr/bin/systemctl stop *, \
    /usr/bin/systemctl restart *, \
    /usr/bin/systemctl reload *, \
    /usr/bin/systemctl status *
    # 只读监控命令
    Cmnd_Alias MON_CMDS = /usr/bin/systemctl status *, \
    /usr/bin/journalctl *, \
    /usr/bin/top, \
    /usr/bin/htop, \
    /usr/bin/ss, \
    /usr/bin/df, \
    /usr/bin/free
  3. 分配权限

    # 运维人员:完整服务管理权限
    %ops ALL=(ALL) SVC_CMDS
    # 监控人员:只读权限,且无需密码
    %monitors ALL=(ALL) NOPASSWD: MON_CMDS
    # 部署账户:完整权限,免密码
    deploy ALL=(ALL) NOPASSWD: ALL
  4. 创建对应的组并添加用户

    创建组和添加用户
    $ sudo groupadd ops
    $ sudo groupadd monitors
    $ sudo usermod -aG ops zhangsan
    $ sudo usermod -aG monitors lisi
  5. 验证配置

    验证 zhangsan 的权限
    $ sudo -U zhangsan sudo -l
命令说明
sudo <命令>以 root 身份执行命令
sudo -u <用户> <命令>以指定用户身份执行命令
sudo -l列出当前用户的 sudo 权限
sudo -U <用户> -l列出指定用户的 sudo 权限(需 root)
sudo -i切换到 root 的登录 Shell
sudo -s以 root 启动一个 Shell(不切换环境)
sudo -k清除 sudo 密码缓存
sudo -v刷新密码缓存的超时时间

提示 “xxx is not in the sudoers file”

Section titled “提示 “xxx is not in the sudoers file””

用户没有 sudo 权限。以 root 身份将用户加入 wheel 组:

以 root 身份操作
$ su -
# usermod -aG wheel username
# exit

提示 “syntax error” 后无法使用 sudo

Section titled “提示 “syntax error” 后无法使用 sudo”

如果错误地直接编辑了 /etc/sudoers 导致语法错误:

方法一:如果有其他有 sudo 权限的用户或能以 root 登录:

修复 sudoers 语法
$ su -
# visudo

方法二:如果无法登录 root,需要进入 rescue mode。

设置密码缓存超时为 15 分钟
$ sudo visudo -f /etc/sudoers.d/timeout
Defaults timestamp_timeout=15

设为 0 表示每次都要求输入密码。设为 -1 表示永不过期(不推荐)。

在自动化脚本中,建议为执行脚本的用户配置 NOPASSWD 权限(限定具体命令),避免脚本执行时卡在密码输入环节。

为自动化脚本配置免密
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/dnf update myapp