服务器是不是被人登录过、什么时候登录的、从哪个 IP 来的,这些问题在出事后排查或者日常安全巡检时都会被问到。Linux 其实记录得相当详细:谁在什么时候登录、从哪来、登录了多久、失败了几次,都散落在几个不同的命令和日志文件里。问题在于,这些信息分布在多个位置,格式各异,很多人不知道该去哪里找,或者只会用 last 看一个大概,遇到"到底有没有陌生 IP 进来过"这种具体问题就抓瞎了。
这篇文章把 Linux 上查看登录记录的几套工具讲清楚:last/lastb/lastlog/w/who 这组命令各看什么,/var/log/secure(RHEL 系)或 /var/log/auth.log(Debian 系)里有什么,怎么用 grep+awk+sort+uniq 统计失败登录的 Top IP,怎么从这些记录里识别异常行为,以及如何把关键信号做成告警。读完你应该能做到:一分钟内回答"这台机器最近谁登过、有没有异常"。
命令区分 RHEL/CentOS/Rocky 与 Debian/Ubuntu 两套。本文只做日志查询与分析,不涉及任何登录尝试的技术手段。
一、记录都存在哪里:先搞清数据源
在动手敲命令之前,先搞清楚"登录信息到底记在哪"。这决定了你排查时该去哪个文件找。
第一类是二进制登录记录文件,主要是 /var/log/wtmp 和 /var/log/btmp,还有 /var/log/lastlog。它们不是纯文本,需要用专门的命令去读:last 读 wtmp(成功登录的历史),lastb 读 btmp(失败登录的历史),lastlog 读 lastlog(每个用户最后一次登录的信息)。这些文件是登录记录的"权威账本",比日志更结构化,但也更容易被有 root 权限的人清掉——这一点后面会讲。
第二类是文本日志,也就是认证日志。RHEL/CentOS/Rocky 系默认在 /var/log/secure,Debian/Ubuntu 系默认在 /var/log/auth.log。里面记的东西更细:谁尝试登录、用什么方式、成功还是失败、失败原因、有没有执行 sudo 等。文本日志的好处是能用 grep 随意过滤。
第三类是 systemd 统一日志。现代系统都可以用 journalctl 查询,它会把包括认证服务在内的日志聚合起来,而且默认持久化和轮转做得较好,不容易被随手清掉。当文本日志被轮转或删除时,journalctl 往往还能查到。
# 确认本机的认证日志到底在哪个文件
ls -l /var/log/secure /var/log/auth.log 2>/dev/null
# 用 journalctl 看 sshd 服务的日志(注意服务名可能是 sshd 或 ssh)
sudo journalctl -u sshd --since "1 day ago" | tail -30
sudo journalctl -u ssh --since "1 day ago" | tail -30 # Debian/Ubuntu
搞清数据源之后再看一个前提:这些命令大多需要 root 或 sudo 才能读到完整信息,普通用户执行可能只能看到自己的记录。排查时一律用 sudo。
二、几个命令各看什么:last、lastb、lastlog、w、who
这五个命令经常被混着用,其实分工很明确。用一张表把它们摆清楚。
| 命令 | 数据来源 | 看什么 | 典型用途 |
|---|---|---|---|
last |
/var/log/wtmp | 成功登录的历史列表 | 看谁登过、从哪来、登了多久 |
lastb |
/var/log/btmp | 失败的登录历史 | 看被尝试登录的 IP 与账号 |
lastlog |
/var/log/lastlog | 每个用户最后登录时间 | 找长期未登录的账号 |
w |
/proc + wtmp | 当前在线用户及正在做什么 | 看此刻谁连接着 |
who |
/var/log/wtmp | 当前登录的用户简要信息 | 快速确认在线会话 |
# 看最近的成功登录记录(默认倒序,最新的在最上)
last -n 20
# 只看某个用户
last admin -n 10
# 看最近的失败登录记录(IP、时间、尝试的账号)
sudo lastb -n 20
# 看所有用户最后一次登录时间,从未登录过的会显示 "**Never logged in**"
sudo lastlog
# 只统计从未登录过的账号(潜在的可疑/闲置账号)
sudo lastlog | grep -i "Never logged in"
# 看当前在线用户及其正在执行的命令
w
# 更简洁的在线用户列表
who -a
last 的输出结构值得熟悉一下:第一列是用户名,第二列是登录终端(pts/0 之类的伪终端,或 tty1 本机终端),第三列是来源(IP 或主机名,本机登录显示为空),接着是登录时间与登出时间,最后一列是会话时长。still logged in 表示还在线,down 表示系统关机导致的会话结束,crash 表示异常中断。看懂这几列,扫一眼就知道有没有异常。
lastb 默认只对 root 可见,因为失败登录记录里包含大量尝试的账号名,属于敏感信息。它的输出和 last 类似,但它记录的是失败尝试——这正是识别扫描和爆破的关键。如果 lastb 输出为空,可能是 btmp 文件不存在或权限问题,可以先创建它。
# 如果 lastb 报 "btmp: No such file",创建该文件
sudo touch /var/log/btmp
sudo chown root:utmp /var/log/btmp
sudo chmod 660 /var/log/btmp
w 的输出还带一列 WHAT,显示用户当前在跑什么命令或程序。这一列在排查"有没有人在线做不该做的事"时很有用。who -a 除了普通登录,还会显示开机时间、运行级别、以及"有记录但已关机"的会话,视野更全。
三、读认证日志:文本日志里的细节
二进制记录给了概览,认证日志给了细节。文本日志可以精确到某一次尝试用什么认证方式、失败的具体原因。
# 看今天的认证日志(RHEL 系)
sudo tail -f /var/log/secure
# Debian/Ubuntu
sudo tail -f /var/log/auth.log
# 只看 SSH 成功的登录(Accepted)
sudo grep "Accepted" /var/log/secure
# 只看 SSH 失败的登录(Failed)
sudo grep "Failed password" /var/log/secure
# Debian/Ubuntu 把 secure 换成 auth.log
sudo grep -E "Accepted|Failed password" /var/log/auth.log | tail -30
# 看 sudo 的使用记录(谁在什么时候提权做了什么)
sudo grep "sudo:" /var/log/secure | tail -20
# 用 journalctl 按时间过滤,查某段时间的登录情况
sudo journalctl -u sshd --since "2026-10-01" --until "2026-10-02"
几个关键字符串要记住。Accepted password 是密码登录成功,Accepted publickey 是密钥登录成功(更常见于加固后的服务器),Failed password 是密码失败,Invalid user 是尝试了系统中不存在的用户名(扫描器常用手法),Connection closed by ... [preauth] 是连接在认证前就被关闭。把这几类串起来看,就能还原"谁在什么时间尝试了什么"。
值得注意的是,日志里的时间戳用的是服务器本地时区。排查时先确认服务器时间是否准确同步,否则时间线会对不上。用 timedatectl 看时区和同步状态。
# 确认服务器时间与时区是否正常
timedatectl
# 查看 NTP 同步状态
timedatectl show-timesync --all
四、统计失败登录的 Top IP 与 Top 账号
单条日志看不出全貌,需要聚合。这是登录分析里最实用的一组命令,用 grep 加 awk 加 sort 加 uniq 就能把海量日志压成一张 Top 榜。
# 失败登录来源 IP 的 Top 10
# 日志行形如:Failed password for root from 203.0.113.5 port 51234 ssh2
# 倒数第 4 个字段就是来源 IP
sudo grep "Failed password" /var/log/secure \
| awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# Debian/Ubuntu:把 /var/log/secure 换成 /var/log/auth.log
# 被尝试最多的用户名 Top 10
sudo grep "Failed password" /var/log/secure \
| awk '{for(i=1;i<=NF;i++) if($i=="for") print $(i+1)}' \
| sort | uniq -c | sort -rn | head -10
# 同时包含无效用户名的记录(扫描器特征)
sudo grep "Invalid user" /var/log/secure | awk '{print $(NF-3)}' \
| sort | uniq -c | sort -rn | head -10
# 成功登录的来源 IP 统计(这个更值得警惕,是真实进过的)
sudo grep "Accepted" /var/log/secure | awk '{print $(NF-3)}' \
| sort | uniq -c | sort -rn | head -10
# 用 journalctl 做同样的统计(当日)
sudo journalctl -u sshd --since today \
| grep "Failed password" | awk '{print $(NF-3)}' \
| sort | uniq -c | sort -rn | head -10
关于 awk '{print $(NF-3)}' 这个写法:NF 是当前行的字段总数,$(NF-3) 表示倒数第四个字段。在标准的 SSH 失败日志格式里,倒数第四个恰好是来源 IP。如果日志格式不同(比如加了其他信息),这个位置会偏,建议先 grep 出一行看着确认字段位置,再调整 NF 的偏移量。这是排查时最容易被忽略的细节——照抄命令但没核对字段,结果统计出来一堆乱码。
还有一类统计很有价值:按小时统计失败次数,能看出攻击的时间分布。如果集中在某个时段突然暴涨,那通常是新的一轮扫描或爆破开始了。
# 按小时统计失败登录次数(RHEL 系)
sudo grep "Failed password" /var/log/secure \
| awk '{print $1" "$2}' | sort | uniq -c | sort -rn | head -20
# Debian/Ubuntu 日志时间戳格式略有不同,可能需要调整字段
# 若时间戳是 "Oct 12 03:15:22",$1 是月份、$2 是日期、$3 是时间
sudo grep "Failed password" /var/log/auth.log \
| awk '{print $1" "$2" "$3}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
如果服务器日志很大,纯 grep 会慢,可以配合 journalctl 的时间过滤缩小范围,或者用 zgrep 去查已经被压缩轮转的历史日志(/var/log/secure-20261001.gz 这类)。
# 查询已轮转压缩的历史日志
sudo zgrep "Failed password" /var/log/secure-*.gz | tail -20
五、怎么识别异常行为
有了数据,判读就是关键。下面这些模式,出现任意一条都应该进一步追查。
第一,来自陌生地域或陌生 IP 的成功登录。这是最需要警惕的。把你和团队常用的 IP、办公网段、跳板机 IP 列一个白名单,凡是"Accepted"里出现白名单之外的成功登录,逐个核对。如果确认不是自己人,立即按"疑似已被入侵"处理。
第二,异常的登录时段。如果你的团队只在北京时间白天工作,日志里却出现凌晨三点从陌生 IP 的成功登录,这很可疑。失败尝试在凌晨集中出现则相对正常,那是扫描器在跑。
第三,异常频繁的失败尝试且集中在同一 IP。lastb 或统计里某个 IP 出现上百次,说明它认准了你,应该封禁。分布在一大堆不同 IP 上的、每次只试一两次的,则是泛扫,不必逐个封。
第四,尝试的账号名很奇怪。像 admin、test、oracle、postgres、ubuntu 这类通用名或者明显不存在的名字(Invalid user),几乎都是扫描器,因为它们在碰运气找存在的账号。反过来,如果有人精准尝试你系统里真实存在的账号名,说明对方做过侦察,风险更高。
第五,登录后立刻执行了提权或敏感命令。这要在 sudo 记录和 shell 历史里交叉看。正常运维的 sudo 使用是有规律的,突然出现的陌生 sudo 命令值得关注。
第六,登录记录出现"缺口"或时间倒挂。如果 last 的输出里,中间某段时间的记录莫名其妙消失了,或者时间顺序错乱,要警惕日志被清理或篡改的可能。有 root 权限的人可以修改 wtmp,所以不要把它当绝对权威,要和 journalctl、外部日志系统交叉验证。
# 快速拉出"当前在线用户 + 最近登录 + 最近失败"三件套做初判
echo "=== 当前在线 ==="; w
echo "=== 最近成功登录 ==="; last -n 15
echo "=== 最近失败登录 ==="; sudo lastb -n 15
# 查看某个用户的登录历史(确认其登录规律是否正常)
last admin | head -20
# 查看某用户最后登录时间
sudo lastlog -u admin
六、把关键信号做成告警
靠人定期翻日志,难免有遗漏。更好的做法是把几个关键信号做成自动告警:出现白名单之外的成功登录、单位时间内失败登录次数超过阈值、某个 IP 失败次数异常集中。
最简单的方式是用日志监控工具(如 Fail2ban 的邮件通知能力)或者监控系统(如 Zabbix、Prometheus 配合日志采集)来触发。如果不想上工具,一个定时脚本也能实现最基本的检查:每天统计一次失败登录 Top IP,超过阈值就发通知。
# 一个最简单的巡检脚本示例:统计当日失败登录次数并输出 Top IP
# 放到 cron 里每天执行一次,结果发到自己邮箱
#!/bin/bash
LOG=/var/log/secure # Debian/Ubuntu 改成 /var/log/auth.log
TODAY=$(date +%b\ %e)
COUNT=$(grep "Failed password" "$LOG" | wc -l)
echo "今日失败登录总数: $COUNT"
echo "Top 来源 IP:"
grep "Failed password" "$LOG" | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -5
# 若总数超过阈值(如 1000)可以在此触发邮件/告警
风险提示:把这类脚本放进 cron 时,注意脚本本身的权限和输出位置,不要把日志内容写到公网可访问的地方。另外,长时间运行的服务器上 /var/log/secure 可能已经轮转,脚本应同时兼顾当前日志和 secure-*.gz,否则统计会偏小。
七、几个容易踩的坑
第一,lastb 需要 btmp 文件存在,新装系统上这个文件可能没有,导致你以为"没有失败登录"。先确认文件存在。
第二,日志轮转会让"看起来只有今天的记录"。用 ls /var/log/secure* 看有哪些历史文件,配合 zgrep 查压缩归档,才能看到完整的过去。
第三,时间戳的时区和格式会因发行版而异,写统计命令前一定要先看一行真实日志确认字段,别照抄。Debian 系的时间戳格式和 RHEL 系不完全一样,字段位置会变。
第四,last 显示的主机名可能被反向解析成域名,看着不直观,加 -n 或配合 -i 显示 IP 更清晰(部分版本支持 --ip 或 -i)。
# 如果 last 显示的是主机名,尝试显示 IP
last -i -n 20
常见问题
Q:last 和 lastb 的结果能作为入侵证据吗?
可以作为线索,但不能单独作为定论。这两个文件都是普通文件,有 root 权限的人可以修改或删除。真正可靠的排查应该把 wtmp/btmp、认证日志、journalctl、以及如果有条件的外部日志服务器交叉验证。如果发现记录被清理,本身就是可疑信号。
Q:为什么 lastb 输出是空的,但我明明被大量尝试登录?
很可能是 btmp 文件不存在或权限不对。按本文的方法创建 /var/log/btmp 并设好属主和权限,之后新的失败登录就会开始记录(历史记录不会补回来)。
Q:日志里 Invalid user 特别多,是不是被针对了?
不完全是。扫描器默认会尝试一堆常见的用户名碰运气,Invalid user 多恰恰说明在做宽泛尝试,而不是针对你。真正要警惕的是针对你系统真实存在用户名的高频失败尝试。
Q:w 显示有我不认识的用户在线,怎么办?
先确认是不是某个服务账号或系统会话(比如某些监控代理会有会话)。如果确实是陌生的人类会话,且来源 IP 不在白名单,按"疑似已被入侵"处理:先隔离网络、保留现场、改所有凭据、检查是否有后门(新增公钥、定时任务、异常进程)。
Q:日志文件太大,grep 很慢怎么办?
用 journalctl 的时间过滤缩小范围,或用 zgrep 直接查压缩的历史日志。生产环境建议上日志采集系统(如集中式日志平台),把日志实时收集走,既方便查询,也避免本地日志被清除后丢失证据。
总结
Linux 的登录记录分散在几处:last/lastb 看成功和失败的登录历史,lastlog 看每个用户最后登录时间,w/who 看当前在线,认证日志看细节,journalctl 做统一查询和持久化。搞清数据源,是排查的第一步。
统计失败登录的 Top IP 和 Top 账号,是识别扫描与爆破最直接的手段。用 grep+awk+sort+uniq 那几组命令,先核对真实日志的字段位置再套用,避免因格式差异统计出错。
判读异常的关键模式是:白名单外的成功登录、异常时段的成功登录、集中在单一 IP 的高频失败、针对真实账号的精准尝试、以及登录记录的缺口。其中"白名单外的成功登录"最需要立即处理。
别只靠人工翻日志。把关键信号(异常成功登录、失败次数超阈值、异常来源)做成告警,让巡检自动化,才能在第一时间发现真正的问题。
最后要记住:本地日志可被有权者修改,重要的服务器应把日志外送到独立系统留存。这样即使本机日志被动过手脚,你依然有可信的时间线来做判断。
企业QQ咨询




