麒麟 V10 上系统时间被人改了,怎么从操作系统里查到具体是谁干的
事情是这样的。
机器上的时间一旦被人手工改掉,最先乱掉的通常不是时钟本身,而是日志、调度、证书校验、任务执行顺序,还有一堆你一时半会儿想不到的联动。更麻烦的是,很多人第一反应是去看 date,看完以后心里只有一个问题,谁改的。
我在 10.0.0.16 这台机器上按这个问题实测了一遍,系统是 Kylin Linux Advanced Server V10 (Lance),内核是 4.19.90-52.22.v2207.ky10.x86_64。先把结论放前面。
如果这台机器在事发之前就开好了 Linux 审计,也就是内核审计没有被关掉,auditd 正常工作,同时管理员是用实名账号加 sudo 做提权,那你基本可以把修改时间的人、来源 IP、TTY、执行命令和发生时间一把捞出来。我后面也在 10.0.0.16 上把这条路真实跑通了。
但如果像这台 10.0.0.16 一样,当前启动参数里带着 audit=0,那就别对事后精准归因抱太大幻想了。你还能从 sudo 日志、登录日志、chronyd 日志里拼出一条证据链,可一旦对方是直接用共享的 root 账号改时间,或者审计本来就没开,那操作系统未必能帮你还原到具体那个人。
这不是技巧问题,是证据有没有提前落盘的问题。
一、现场验证和前提
1.1 先看这台机器的真实现状
我在 10.0.0.16 上先查了几件事。
cat /proc/cmdline
systemctl status auditd --no-pager -l
auditctl -s
timedatectl status
关键结果是这样的。
BOOT_IMAGE=/vmlinuz-4.19.90-52.22.v2207.ky10.x86_64 ... audit=0
auditd 虽然装了,但根本起不来。
Condition: start condition failed
ConditionKernelCommandLine=!audit=0 was not met
再往下看,auditctl 直接报错。
Error - audit support not in kernel
Cannot open netlink audit socket
这几行已经把问题说透了,这台机子当前这次启动周期里,Linux 审计是被内核参数硬关掉的。不是服务没启动那么简单,是这一轮开机期间就接不到审计事件。
1.2 我在这台机器上做的复现
为了不动现有账号,我临时建了一个普通账号,把它放进 wheel 组,然后用它通过 sudo 去改系统时间,最后再把时间恢复、把测试账号删掉。
核心动作是这一条。
sudo /usr/bin/date -s '+3 minutes'
改完以后,我重点查了四处。
第一处是 /var/log/secure,这个最有用,因为它直接记录了 sudo 的执行人和命令。
grep -nE 'sudo|date -s' /var/log/secure | tail -n 20
我在现场拿到的关键日志是这一条。
May 14 12:33:01 kylin-16 sudo[11740]: timeaudit : TTY=pts/2 ; PWD=/home/timeaudit ; USER=root ; COMMAND=/usr/bin/date -s +3 minutes
这条日志已经能回答很多问题了。
执行人是 timeaudit,提权目标是 root,登录终端是 pts/2,执行目录是 /home/timeaudit,命令是 /usr/bin/date -s +3 minutes。
第二处是 journalctl,它能把登录、提权、会话关闭这些动作串起来。
journalctl -b --since '30 min ago' -o short-iso |
egrep 'sudo|session opened|session closed|date -s'
我在现场看到的关键片段是这样。
2026-05-14T12:33:00+0800 kylin-16 sshd[11506]: pam_unix(sshd:session): session opened for user timeaudit(uid=1003) by (uid=0)
2026-05-14T12:33:01+0800 kylin-16 sudo[11740]: timeaudit : TTY=pts/2 ; PWD=/home/timeaudit ; USER=root ; COMMAND=/usr/bin/date -s +3 minutes
2026-05-14T12:36:01+0800 kylin-16 sudo[11740]: pam_unix(sudo:session): session closed for user root
第三处是 chronyd 和系统消息日志,因为改时间以后,时间同步组件通常会立刻察觉到时钟跳变。
grep -nE 'chronyd|time jump|System clock' /var/log/messages | tail -n 30
这台机器上我拿到的特征日志包括这些。
May 14 12:00:24 kylin-16 chronyd[900]: Backward time jump detected!
May 14 12:02:35 kylin-16 chronyd[900]: System clock wrong by 10046.347483 seconds, adjustment started
May 14 12:36:01 kylin-16 chronyd[900]: Forward time jump detected!
这类日志不能直接告诉你是谁改的,但它能证明系统时间在那个时段确实发生过异常跳变。
第四处是 last -x,它能把当时从哪个地址登进来的会话列出来。
last -x | head -n 20
这次复现里,能看到测试账号是从 10.0.0.1 连过来的。
timeaudit pts/2 10.0.0.1 Thu May 14 12:33 - 12:36 (00:03)
把这四块拼起来,默认没有开启内核审计的情况下,我依然能得到这样一条证据链。
某个来自 10.0.0.1 的登录会话,以 timeaudit 身份登录到 pts/2,随后执行了 sudo /usr/bin/date -s +3 minutes,紧接着系统里的 chronyd 检测到了时间跳变。
这已经足够定位到这次复现是谁干的了。
但要注意,这个结论成立的前提,是对方用了实名账号加 sudo。如果对方直接共享 root 密码登录,然后手工执行 date -s 或 timedatectl set-time,你未必还能拿到这么完整的归因链。
二、怎么查和怎么处理
2.1 未开启 audit 的排查路线
我建议按下面这个顺序查,不要一上来乱翻日志。
1、先判断这台机器有没有提前开审计
cat /proc/cmdline
systemctl is-active auditd
auditctl -s
如果你看到了 audit=0,或者 auditctl 报 Cannot open netlink audit socket,那就说明这次开机周期里审计不可用,后面就按未开启 audit 的路线来查。
2、查 sudo 这条线
如果像我第一次验证 10.0.0.16 时那样,当前内核参数是 audit=0,那就别在 ausearch 上死磕了。这个时候要老老实实走三条旁证线,sudo、登录会话、时间跳变。
先看 sudo。
grep -nE 'sudo|date -s|timedatectl' /var/log/secure | tail -n 50
再看登录会话。
last -x | head -n 30
journalctl -b --since 'today' | egrep 'session opened|session closed|sshd|sudo'
最后看时间跳变。
grep -nE 'chronyd|time jump|System clock' /var/log/messages | tail -n 50
journalctl -b --since 'today' | egrep 'chronyd|time jump|System clock|timedated'
如果三条线能在同一个时间窗口里对上,通常就能把人锁到八九不离十。
4、别忘了区分人改时间还是 NTP 自己在纠偏
不是所有时间变化都是人手工改的。
如果你看到的是下面这种日志。
chronyd: Selected source ...
chronyd: System clock wrong by ...
chronyd: System clock was stepped by ...
那有可能只是 chronyd 在把漂掉的系统时间纠回来。这个时候要结合 sudo、audit、timedated 的痕迹一起判断,别把自动校时误判成人工篡改。
所以这一节真正要记住的,其实就一句话。
如果 audit 已经开启,优先查 audit,它给的是直接证据。
如果 audit 没开,就查 sudo、last -x、journalctl、/var/log/messages,它们给的是旁证链。
2.2 已开启 audit 的排查路线
如果审计已经提前开好了,这其实是最省心的情况。你不用先去翻 secure 和 messages,先直接查 audit。
1、先直接查时间变更审计记录
ausearch -k time-change -i
ausearch -k timezone-change -i
如果你想把时间范围压小一点,可以这样查。
ausearch -k time-change -ts today -i
ausearch -k time-change -ts recent -i
如果你怀疑对方不是改了时区,而是直接调了系统时钟,还可以补一条 syscall 维度的查询。
ausearch -m SYSCALL -ts recent -i | egrep 'clock_settime|settimeofday|adjtimex'
2、重点看这些字段
我在 10.0.0.16 上把 audit=0 改成了 audit=1,重启后确认了三件事。
cat /proc/cmdline
systemctl is-active auditd
auditctl -s
现场结果是这样的。
BOOT_IMAGE=/vmlinuz-4.19.90-52.22.v2207.ky10.x86_64 ... audit=1
active
enabled 1
pid 879
然后我在机器上加了时间修改审计规则。
cat >/etc/audit/rules.d/time-change.rules <<'EOF'
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S clock_settime -k time-change
-w /etc/localtime -p wa -k timezone-change
EOF
augenrules --load
auditctl -l | egrep 'time-change|timezone-change'
随后我又用实名账号 timeaudit 通过 sudo 执行了一次真实改时。
sudo /usr/bin/date -s '+2 minutes'
这一次,audit.log 里直接留下了完整链路。最关键的是下面这几条。
type=USER_CMD ... cwd="/home/timeaudit" ... exe="/usr/bin/sudo" terminal=pts/0 ... AUID="timeaudit"
type=SYSCALL ... comm="date" exe="/usr/bin/date" key="time-change" ... SYSCALL=clock_settime AUID="timeaudit" UID="root" tty=pts0
这两条已经足够把事情说透了。
AUID="timeaudit"说明最初发起这次操作的人是timeauditUID="root"说明真正执行改时动作时已经提权成了rootexe="/usr/bin/date"和SYSCALL=clock_settime说明确实是date触发了系统时间修改terminal=pts/0说明操作终端就是这次登录会话所在的 TTY
你要重点看这些字段。
auid,原始登录用户,最关键uid,执行时的有效用户,很多时候会是roottty,操作终端addr,来源 IPexe和comm,到底是date、timedatectl还是别的程序msg=audit(...)里的时间戳
真正能定位到人的,通常不是 uid=root,而是 auid=某个实名账号。
3、理解 auid 和 uid 的区别
你可以把它理解成两层身份。
uid=root说明这次动作最终是以 root 权限完成的auid=test01才说明最初登录进来、发起这次操作的人是谁
如果你在 audit 结果里看到类似这种字段组合,基本就已经能锁定操作人了。
auid=test01 uid=root tty=pts/1 addr=10.0.0.1 exe=/usr/bin/date comm=date
这串字段翻成大白话就是,test01 这个人,从 10.0.0.1 登录过来,在 pts/1 终端里,通过提权以 root 身份执行了 date 去改系统时间。
这条路是最完整的。
2.3 想以后稳定查到具体是谁,正确做法是提前加固
这块才是重点。
这次在 10.0.0.16 上,我已经验证了默认日志链路确实能抓到 sudo date -s 这种场景。随后我又把这台机器切换成 audit=1、重启、加规则、再次复现改时间,确认 audit 这条链路也能直接抓到 USERCMD 和 clocksettime。所以真正想把以后每一次时间修改都精确打点,还是得把内核审计打开。
处理步骤我建议这样做。
1、去掉 audit=0,改成 audit=1
grubby --update-kernel=ALL --remove-args="audit=0"
grubby --update-kernel=ALL --args="audit=1"
reboot
重启后确认。
cat /proc/cmdline
只要不再看到 audit=0,并且能看到 audit=1,这一步就算过了。
2、启动并设置 auditd 开机自启
systemctl enable --now auditd
systemctl status auditd --no-pager -l
auditctl -s
3、添加时间修改审计规则
新建规则文件。
cat >/etc/audit/rules.d/time-change.rules <<'EOF'
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S clock_settime -k time-change
-w /etc/localtime -p wa -k timezone-change
EOF
加载规则。
augenrules --load
auditctl -l | egrep 'time-change|timezone-change'
4、用实名账号加 sudo 管理,不要共享 root
这一条听着像管理要求,其实是技术要求。
如果大家都直接拿 root 密码登录,那操作系统最多只能告诉你,root 改了时间。可 root 是账号,不是人。你真想查到具体是谁,必须让管理员先用自己的账号登录,再通过 sudo 提权,这样审计里的 auid 才有意义。
如果条件允许,我建议再做两件事。
- 禁止直接远程登录
root - 保留并集中管理
/var/log/secure、journal、audit日志
5、可选补强,打开进程记账
这台机器上 psacct 包已经装了,但服务没开。
systemctl enable --now psacct
lastcomm date
lastcomm timedatectl
它不能替代审计,但在事后补证的时候有时挺有用。
2.4 以后真出事了,标准查询命令可以直接抄
如果审计已经按上面的方式开好了,出了事先跑这几条。
ausearch -k time-change -ts today -i
ausearch -k timezone-change -ts today -i
ausearch -m SYSCALL -ts recent -i | egrep 'clock_settime|settimeofday|adjtimex'
如果你看到类似下面这种字段组合,基本就能锁人了。
auid=test01 uid=root tty=pts/1 addr=10.0.0.1 exe=/usr/bin/date comm=date
这串字段翻成大白话就是,test01 这个人,从 10.0.0.1 登录过来,在 pts/1 终端里,通过提权以 root 身份执行了 date 去改系统时间。
这才叫能落到人。
如果 audit 没开,那就直接抄这组命令。
grep -nE 'sudo|date -s|timedatectl' /var/log/secure | tail -n 50
last -x | head -n 30
journalctl -b --since 'today' | egrep 'session opened|session closed|sshd|sudo'
grep -nE 'chronyd|time jump|System clock' /var/log/messages | tail -n 50
这组命令查不出 syscall 级别的直接证据,但很适合在没有 audit 的环境里快速拼时间线。
2.5 这次实测最后的结论
回到 10.0.0.16 这台麒麟 V10。
我已经在这台机器上复现并验证了两件事。
第一,在未开启 audit 的默认状态下,虽然 audit 软件包已经安装,但只要内核参数还是 audit=0,这一轮开机周期里审计就不可用,不能指望通过 ausearch 直接查出谁改了时间。
第二,如果时间是通过实名账号加 sudo 改的,那么即使没开 audit,依然可以从 /var/log/secure、journalctl、last -x、/var/log/messages 里把人、终端、来源地址和时间跳变过程拼出来。我第一次复现里,系统明确记录到了 timeaudit 执行了 sudo /usr/bin/date -s +3 minutes。
第三,如果已经开启 audit,并且加好了时间变更规则,那么这件事就会从旁证链升级成直接证据。我第二次复现里,audit.log 明确记录到了 AUID="timeaudit"、UID="root"、exe="/usr/bin/date"、SYSCALL=clock_settime、terminal=pts/0 这些关键字段。
所以这件事真正的答案其实很朴素。
已经发生了,再去问操作系统能不能百分之百告诉你是谁,这要看你之前有没有把证据链准备好。
没准备好,就只能尽量还原。
准备好了,才能精准归因。
顺手补一句,这两轮复现结束后,我已经把测试账号删除,并把 10.0.0.16 的系统时间恢复到了正常值。



暂无评论内容