4. 特权管理与sudo加固
在 Linux 主机安全中,root 权限是最核心的攻击目标。一旦攻击者获得 root,系统上几乎所有防护措施都可能被绕过。因此,特权管理的目标不是“让管理员更方便地用 root”,而是把 root 权限拆解、委派、记录和约束,让每一次高权限操作都有明确的身份、范围、命令和审计痕迹。本节围绕 sudo 的配置语法、最小权限委派、日志审计、su 与 sudo 的差异,以及禁用 root 直接登录展开。
一、su 与 sudo 的本质差异
su 的语义是“切换用户”。执行 su - 后输入 root 密码,当前会话就变成 root 的登录 shell,之后所有命令都以 root 身份运行,且不再区分具体执行了什么。它的关键问题是:要使用 root,必须知道 root 密码;一旦切换成功,权限边界就消失了,审计也只能看到“某人 su 成了 root”,无法精确到命令级别。
sudo 的语义是“以另一个用户身份执行一条命令”。它校验的是执行者自己的密码(也可配置为免密),然后根据 /etc/sudoers 中的规则判断该用户能否以目标身份运行指定命令。sudo 的权限粒度可以细到“某用户在某主机上以某身份运行某条命令”,并且每次调用都会记录日志。因此,现代 Linux 加固普遍推荐:日常管理走 sudo,root 密码尽量不扩散,root 直接登录关闭。
二、sudoers 语法与安全配置
sudo 的规则集中在 /etc/sudoers,但生产环境不应直接编辑该文件,而应使用 visudo,它会在保存前做语法检查,避免写坏后所有人无法提权。更推荐的做法是在 /etc/sudoers.d/ 下按用途拆分文件,例如 10-admins、20-dba,便于审计和回收。
一条 sudoers 规则的基本形式是:
用户 主机=(目标用户:目标组) 命令列表
例如,允许运维组成员 alice 在任意主机上以 root 身份重启 nginx 和查看服务状态:
alice ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
这里有几个安全细节必须注意。第一,命令要写绝对路径,否则可能被同名恶意程序劫持。第二,命令参数要尽量限定,例如只允许 systemctl restart nginx,而不是允许 /usr/bin/systemctl 全部子命令,否则用户可以通过 systemctl 的其他子命令间接获得更高权限。第三,慎用 ALL 和通配符 *,alice ALL=(ALL) ALL 等价于把 root 权限完整交出。第四,NOPASSWD 只应在自动化脚本等确有必要时使用,且必须配合命令白名单。
/usr/bin/vi /var/log/* 看似只允许编辑日志,但 vi 可以执行 shell 命令,用户进入 vi 后输入 :!sh 即可获得 root shell。凡是允许交互式程序、编辑器、解释器、分页器的规则,都要按“可逃逸”对待。三、最小权限委派
最小权限委派的核心是:按角色拆分命令集,而不是按人给权限。建议先定义角色,再把用户加入角色对应的 sudoers 文件。例如:
- 运维角色:允许
systemctl restart/status指定服务、journalctl查看日志。 - 数据库角色:允许
systemctl restart mysqld、以 mysql 用户执行备份脚本。 - 审计角色:只允许读取
/var/log/下日志和last、who等命令。
委派时还要考虑“目标用户”维度。很多操作不需要 root,只需要以服务账号身份运行,例如 dba ALL=(mysql) /usr/local/bin/backup.sh,这样即使脚本被利用,影响范围也限制在 mysql 用户内。对于需要 root 的操作,优先使用 sudoedit 而不是 sudo vi,因为 sudoedit 会以调用者身份编辑临时副本,再以目标身份写回,避免编辑器逃逸。
四、sudo 日志审计
sudo 默认会把每次调用记录到系统日志,Debian/Ubuntu 通常在 /var/log/auth.log,RHEL/CentOS 在 /var/log/secure。典型记录包含执行用户、目标用户、终端、工作目录、完整命令和结果。例如:
Mar 12 10:22:41 web01 sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/systemctl restart nginx
要提升审计能力,可以在 sudoers 中启用日志输入输出:
Defaults log_input, log_output
Defaults iolog_dir=/var/log/sudo-io
Defaults logfile=/var/log/sudo.log
这样不仅能记录命令,还能回放会话输入输出,适合对高风险操作做取证。审计时重点关注:非工作时间的 sudo 调用、USER=root 且命令为 shell 或编辑器的记录、失败尝试、以及 NOPASSWD 规则的异常使用。建议把 sudo 日志集中转发到日志服务器,防止本地日志被篡改。
五、禁用 root 直接登录
即使 sudo 配置得当,只要 SSH 允许 root 直接登录,攻击者仍可对 root 账户进行密码爆破。加固方式是编辑 /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
修改后先执行 sshd -t 检查语法,再 systemctl reload sshd 生效。注意:禁用 root 登录前,必须确认已有普通用户可通过密钥登录并能 sudo 提权,否则可能把自己锁在系统外。对于必须保留 root 远程能力的场景,可退而使用 PermitRootLogin prohibit-password,即只允许密钥、禁止密码。
最后给出一个可参考的加固检查清单:确认 /etc/sudoers 无 ALL=(ALL) ALL 的普通用户;确认 /etc/sudoers.d/ 文件权限为 0440 且属主 root;确认无多余 NOPASSWD;确认 sudo 日志已开启并集中收集;确认 PermitRootLogin no 且已用普通用户验证过 sudo 提权。完成这些检查后,root 权限就从“共享密码”转变为“按需委派、全程留痕”的可控能力。