Linux 权限与登录审计实战:sudo 授权规范与日志追溯
出了事想追溯,打开服务器发现 sudoers 里躺着一行 ALL=(ALL) NOPASSWD: ALL,日志又被轮转冲得七零八落——这是很多线上环境审计时的真实画面。本文把三件事一次做规范:sudo 授权的写法、登录与提权日志的追溯套路、auditd 的最小监控规则集。环境口径:Rocky Linux 9 / RHEL 系为主,Debian 系差异处会注明日志路径。
前置条件
- 具有 root 或现管理员账号的服务器操作权限,操作前已留好一个可用的 root 控制台或已验证的登录通道(改 sudoers 改错会把所有人锁在门外)。
- 服务器已启用 rsyslog 与 systemd-journald(主流发行版默认如此)。
- 如需启用 auditd,确认 auditd 服务可安装且内核审计未被关闭(启动参数无 audit=0)。
第一步:sudoers 的规范写法
规矩先立住:永远用 visudo 编辑,它在保存时做语法校验,写错会拦住;批量下发时把规则拆到 /etc/sudoers.d/ 下按用途分文件,主文件只保留系统默认。授权按"人或组 + 能在哪台机 + 以什么身份 + 执行哪些命令"四段写,用命令组(Cmnd_Alias)把命令集合命名管理:
# /etc/sudoers.d/ops-app —— 应用运维组:只允许管本应用的服务与看日志
Cmnd_Alias APP_SVC = /usr/bin/systemctl restart myapp, /usr/bin/systemctl status myapp
Cmnd_Alias APP_LOG = /usr/bin/journalctl -u myapp, /usr/bin/tail /var/log/myapp/*
%opsapp ALL=(root) APP_SVC, APP_LOG
几个关键写法要点。命令必须写绝对路径,且要意识到带通配的命令参数(如上面的 tail 路径)意味着该范围内的任意文件可读,范围要收敛。允许执行编辑器、find、less、systemctl 这类"能逃逸出 shell"的命令,等同于给 root,评审时要单独标红。Defaults 里建议显式写上三项:
Defaults env_reset
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults logfile="/var/log/sudo.log"
Defaults timestamp_timeout=5
secure_path 固定可避免 PATH 劫持类的提权绕过;timestamp_timeout 控制免密时间窗口,不要为了省事设成 -1。坚决避免的写法有三类:一是 NOPASSWD: ALL 全量免密,账号一旦被盗就是 root 被盗;二是给普通业务账号 ALL=(ALL) ALL 图省事;三是直接用文本编辑器改 /etc/sudoers 且不校验,语法错误会导致全机 sudo 瘫痪。改完必须用 visudo -c 全量校验,并拿被授权账号实测一遍"该通的通、该拦的拦"。
第二步:sudo 与登录日志去哪找、怎么读
RHEL 系的认证与提权日志在 /var/log/secure,Debian 系在 /var/log/auth.log;同时 journald 里也有副本,两边对照着看能防单点缺失。sudo 的三类关键记录要分清:授权成功执行、认证失败、以及"不在 sudoers 里"的尝试(最值得告警)。常用提取套路:
# 谁用 sudo 执行过什么(secure 里的 COMMAND 字段)
grep "COMMAND=" /var/log/secure | tail -n 50
# 用 journal 按 sudo 维度查同一时间段
journalctl _COMM=sudo --since "2026-11-08 00:00:00" | grep "COMMAND="
# 不在授权名单内的尝试与密码错误
grep -E "NOT in sudoers|authentication failure" /var/log/secure
补充一个容易被低估的工具:sudoreplay。当 sudoers 里启用了 log_input/log_output(I/O 日志)时,每次会话的输入输出会录在 /var/log/sudo-io/ 下,可按会话 ID 回放当时的完整操作过程,事后复盘误操作时比翻命令流水账直观得多。录像文件占空间且含敏感信息,按需开启并配合保留周期管理。另外,sudo 自身的日志行里 TTY、PWD、USER 三个字段要会读:它能告诉你操作者在哪个终端、哪个目录下、以什么目标身份执行的命令——这是定责的关键上下文。
第三步:登录审计
登录痕迹分布在三组文件里:wtmp 记录成功登录(last 读),btmp 记录失败尝试(lastb 读,需 root),lastlog 记录每个账号最后一次登录(lastlog 读)。排查时的基本动作:
# 近期成功登录与来源 IP
last -i | head -n 30
# 失败登录尝试,找爆破与异常来源
lastb -i | head -n 30
# 直接从 secure 里提 SSH 成功/失败明细
grep -E "Accepted|Failed password" /var/log/secure | tail -n 50
# 按来源 IP 聚合失败次数,快速识别爆破源
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head
两个提醒:一是 last 的输出依赖 wtmp 未被截断,查更久以前的记录要去翻轮转后的 wtmp-YYYYMMDD 归档文件用 last -f 指定读取;二是发现陌生 IP 成功登录时,先别忙着删记录取证——先冻结账号、留存 secure 与 wtmp/btmp 的副本再处置,日志本身就是证据链。
第四步:auditd 最小规则集
secure 与 journal 记录的是"认证与提权",但"谁改了 /etc/passwd""谁执行了 useradd"这类动作要靠 auditd。在 /etc/audit/rules.d/audit.rules 放入最小集:监控关键身份文件、sudoers 变更与提权命令的执行:
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid!=unset -k rootcmd
-w /var/log/secure -p wa -k log-tamper
augenrules --load
# 按 key 检索审计事件,复盘时先定位时间再展开
ausearch -k identity --start "2026-11-08 09:00:00" -i
ausearch -k rootcmd --start today | aureport -x --summary
规则不在多在精:execve 全量记录会产生巨大的日志量,先用上面这组覆盖身份文件与 root 命令两个高风险面,其余按合规要求增补。每条规则的 -k 标签就是日后检索的索引,命名要统一。注意 rules 修改后需重新加载才生效,且 auditd 本身的日志在 /var/log/audit/audit.log,它的轮转与保留要在 /etc/audit/auditd.conf 里按磁盘容量规划好 num_logs 与 max_log_file_action,别让审计把根分区写满。
第五步:日志集中与防篡改(一句交代)
本机日志只防得住误操作,防不住拿到 root 的人删日志:把 secure、sudo.log 与 audit.log 通过 rsyslog/syslog 转发到独立的日志服务器集中留存,并给日志目录设置只追加属性或接入带完整性校验的日志平台,本机侧的记录只作缓存。细节属于日志平台建设的范畴,这里不展开,但"日志要出本机"这条要在制度上先定下来。
验证
- 用 opsapp 组成员账号执行授权内命令成功,执行名单外命令被拒且 secure 中出现对应记录。
- 故意输错一次 sudo 密码、用未授权账号尝试一次 sudo,两个事件都能在日志中检索到。
- 修改一个测试文件的属主模拟触碰 /etc/passwd 类操作后,
ausearch -k identity能查到事件。 last与 secure 中的 SSH 登录记录在时间与来源 IP 上能相互对上。
常见问题
授权越收越细,最后大家都喊不方便又加回 ALL。这通常是命令组没按实际工作拆:把一周内真实用到的命令从 sudo 日志里统计出来,按高频操作补命令组,低频高危操作走临时授权(限时 sudoers 文件 + 到期自动删除)。用数据补授权,比拍脑袋放权稳。
日志被轮转冲掉,查不到上周的记录。logrotate 默认按周或按大小轮转且只留 4 份,审计类日志要单独调保留策略并压缩归档到大容量目录,同时靠集中转发兜底;另外确认 journald 的持久化存储已开启(/var/log/journal 存在),否则重启后 journal 只剩本次开机。
各台机器日志时间对不齐,拼不出事件线。全网先统一 chrony 时间同步,再统一时区口径(建议都用 Asia/Shanghai 或都用 UTC,选一种并写进基线),跨日志对时差控制在 1 秒内,追溯才做得下去。
auditd 规则加载了但没事件。先确认 auditd 服务运行、auditctl -l 能列出规则,再检查是否在 rules 文件里写了 -D 把规则清空或与 -e 2(锁定配置)冲突;锁定模式下改规则必须重启,生产上慎用。
小结
审计能力是平时攒出来的:sudoers 按最小授权写、日志落点与提取套路烂熟于心、auditd 盯住关键文件与提权动作、日志集中出本机。做到这四条,真出问题时才有据可查,而不是对着一台干净得可疑的服务器猜。






