journalctl 的 _uid 字段仅能查询已落盘日志中明确标记该 uid 的条目,如 pam 登录、systemd 用户服务等,不覆盖 shell 命令、ssh 后续操作、sudo 行为或 cron 任务。

journalctl 的 _UID 字段本身不支持“一秒内全盘点”这种实时快照式操作,它只能按时间范围过滤已有日志条目;且 _UID 是 systemd-journald 的内部匹配字段,需配合用户 ID(数字)而非用户名使用,也不能直接用于检测横向移动行为——它只记录该 UID 启动的 systemd 服务或 PAM 登录会话,不覆盖所有进程、SSH 命令、shell 操作或非 systemd 进程行为。
明确 _UID 能查什么、不能查什么
_UID 只匹配 journal 日志中明确设置了该字段的条目,典型来源包括:
- PAM 登录成功/失败(如 sshd、gdm、lightdm 记录的 session start/end)
- systemd 用户级服务(
systemctl --user start xxx触发的日志) - 某些 setuid 程序显式写入 journal 时携带的 UID
它不会记录:
- 普通 shell 中执行的命令(如
ls、curl、nc) - SSH 登录后执行的任意命令(除非该命令自身调用
sd_journal_print()) - sudo 切换后的操作(sudo 日志走 auth.log 或 journald 的
_GID/_UID不一定准确反映原始行为者) - crontab、at、screen/tmux 会话内的活动
正确获取目标账号的 UID 并做精准时间过滤
先查 UID(别用用户名硬编码):
id -u suspicious_user
假设输出为 1005,再用 journalctl 查该 UID 在最近 1 秒内的相关日志(注意:journalctl 无法“未来等待 1 秒”,只能查已落盘日志,而日志写入有毫秒级延迟):
journalctl "_UID=1005" --since "1 second ago" --output=short-iso-us
更实用的是缩小到最近 5 秒并加字段增强可读性:
journalctl "_UID=1005" --since "5 seconds ago" -o json | jq 'select(.MESSAGE and (.SYSLOG_IDENTIFIER=="sshd" or .UNIT or .MESSAGE | contains("session")))'
横向移动真正需要联动的关键日志源
单靠 _UID 远不足以判断横向移动。必须交叉验证以下日志:
- auth.log / secure:SSH 登录源 IP、密钥指纹、failed login 频次、sudo 提权行为
- bash_history(谨慎!易伪造):仅当用户未禁用且 history 时间戳开启才具参考价值
- auditd 日志(/var/log/audit/audit.log):可审计 execve、setuid、network connect,需提前配置规则
-
systemd-logind:查
journalctl _COMM=systemd-logind获取登录/登出、session 创建详情
实战建议:构建最小响应命令链
发现可疑账号(如 devtest)后,立即运行(一行,5 秒内完成):
U=$(id -u devtest 2>/dev/null); [ "$U" ] && { journalctl "_UID=$U" --since "10 seconds ago" -n 50 --no-pager | grep -E "(sshd|session|Started|ExecStart)"; journalctl _COMM=sshd --since "10 seconds ago" | grep -F " $U "; } | head -30
说明:
- 优先查该 UID 最近 10 秒内与登录、服务启动强相关的日志
- 同步查 sshd 日志中是否出现该 UID 字符串(部分 sshd 版本会在日志中记 UID)
-
head -30防止滚动过长,聚焦最新线索











