ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux last命令全解:从登录历史到服务器安全审计

Linux last命令全解:从登录历史到服务器安全审计 1. 先弄清楚 last 在看什么那些看不见的登录记录我做了很多年服务器运维平时巡检有一件事雷打不动看登录历史。你翻任何一份 Linux 常用命令大全last都会被归到“登录记录”这一类但它到底在读什么、记录是怎么产生的很多刚入行的人其实没搞清楚。last的核心数据源是/var/log/wtmp这个文件记录了系统上每一次成功登录的开始时间、结束时间、来源 IP或主机名、使用的终端以及重启和关机事件。注意它不是普通文本文件直接用cat打开只会看到乱码。你可以先执行file /var/log/wtmp看一下大概率会输出类似“data”的结果这就是 wtmp 的原本形态。所以想查看里面的内容正规姿势就是交给last这类专用工具来解析。登录历史这件事看起来简单但背后有一套完整的日志体系。用户通过 SSH 登录、本地 tty 登录甚至某些图形界面登录时系统的登录程序会在/var/run/utmp里记录“当前正在登录”的会话同时将完整的会话记录追加到/var/log/wtmp。等用户退出会话的“结束时间”会被补全。如果会话因为断电、系统崩溃而异常终止last会显示 crash 之类的标记而不是一个正常的下线时间。这些细节恰恰是排查问题时最关键的线索。1.1 /var/log/wtmp一个二进制文件里的完整时间线可以这么理解wtmp是系统自己维护的“签到簿”。每次有人成功登录系统就往里面写一条记录每次退出再补一条记录。这个文件从系统创建最初开始累积直到 logrotate 把它轮转走。因为它面向的是后台审计所以设计上就是只追加、不轻易覆盖。这跟/var/log/auth.log这类文本日志不一样文本日志可以被人随手改两行而 wtmp 虽然理论上也能被篡改但门槛明显更高。这一点在做安全排查时特别重要。攻击者就算清空了自己的 shell historylast这条命令依然能告诉我某人什么时候从哪个 IP 登上来过。因为 wtmp 的写入并不由 shell 控制而是由 sshd、login、PAM 这些底层机制负责。只要修改登录行为就会留下会话痕迹。当然有 root 权限的人刻意清理另说这点后面我会聊到。还需要强调一个关键区别last看的是“成功登录”。那些失败的、被拒绝的登录尝试记录在/var/log/btmp里对应命令是lastb。很多人一开始把两个文件搞混结果排查暴力破解的时候发现last里干干净净就以为服务器安全无忧其实真正的爆破流量全藏在btmp里。1.2 last 输出里每个字段是什么意思直接敲一句last屏幕上出来的内容长这样root pts/0 192.168.1.55 Thu Dec 12 09:22 still logged in reboot system boot 5.15.0-91-generic Thu Dec 12 08:59 still running alice pts/1 10.0.0.8 Wed Dec 11 22:31 - 23:02 (00:31) wtmp begins Wed Dec 11 18:00:01 2024看着挺简单但每个字段都有讲究字段含义实战价值用户名谁登录了排查是否有异常账号、是否 root 直接登录终端pts/0、tty1 等pts 一般是远程 SSHtty 多为本地控制台来源 IP/主机名从哪连过来的判断是否来自陌生 IP、内网还是公网登录开始时间会话建立时刻和业务异常时间点对齐登录结束时间会话关闭时刻正常退出有时间异常中断会显示 crash持续时间会话保持时长异常长连接值得关注still logged in会话还没退出配合who查看当前在线用户system boot系统启动记录查看重启时间判断是否有人动过机器有了这张表你再回看上面的输出一条完整时间线就出来了12 月 12 日早上 8 点 59 分系统启动9 点 22 分 root 从内网 IP 登录目前还没退出。如果这不是你自己的操作那问题就大了。1.3 为什么登录历史这么重要很多人觉得登录历史“不起眼”但我在实际处理过的故障和攻击事件里最后定位问题的抓手往往就是last的输出。服务器被人种了后门、业务数据在凌晨被导出、某台机器出现异常流量追来追去最终都要回到一个问题那个时间点谁登录了这台机器。last的另一个价值在于它能关联到审计和合规要求。等保检查、客户审计、内部安全扫描几乎都会问到“系统登录日志是否留存”“是否有人定期检查登录历史”。在这个场景下last不是可有可无的小命令而是整个登录审计体系的门面。后文我会把last、lastb、lastlog、who串成一套组合拳来用这才是运维巡检的完整打法。2. last 参数从只会敲 last 到随手定制输出last的参数看起来不多但组合起来能覆盖大部分场景。我见过很多同事翻来覆去只会敲一个last遇到几百行输出只能肉眼找信息效率很低。其实只要掌握几条参数组合就能把输出裁剪成真正需要的内容。2.1 最常用的参数组合先看几条我日常使用频率最高的命令# 只看最近 20 条记录 last -n 20 # 只看某用户的登录记录 last root # 用完整时间格式展示方便看具体秒级时间 last -F -n 10 # 显示 IP 而不是主机名并且把主机名放到最后一列 last -i -a -n 15 # 包含系统关机、重启和运行级别变化记录 last -x -n 20 # 指定读取某个日志文件常用于查看轮转后的历史日志 last -f /var/log/wtmp.1这里最容易被忽略的是-i。默认情况下last会尝试把登录来源 IP 反解析成主机名。如果网络环境里 DNS 配置不规范反解析会很慢一条命令卡半天输出还全是内网 hostname根本看不出真实 IP。我习惯直接加上-i让它保持原始 IP 格式输出既快又清晰。-F是我排查问题时必用的参数。普通输出只精确到分钟但安全事件往往需要精确到秒。比如业务日志显示 3 点 15 分 30 秒左右数据库被删了last默认输出只有 03:15你没法判断登录发生在删库之前还是之后加上-F就能把时间卡到秒级。-x也值得一提。默认last也会显示 reboot但不够完整。加上-x之后系统开机、关机、运行级别变化都会被列出排查“这台机器到底什么时候重启过”就非常方便。常用参数我再整理成一张速查表方便你贴在笔记本里参数作用典型场景-n 数字只显示最后 N 条快速看最近登录避免刷屏-f 文件从指定文件读取记录查 logrotate 轮转后的历史 wtmp-i使用 IP 替代主机名显示公网服务器快速定位来源-d把 IP 反解析为主机名对内部域名环境友好-a把主机名显示在最后一列脚本解析时方便按列处理-F完整时间格式精确到秒的审计排查-x显示系统关机、运行级别记录排查重启和异常关机-R不显示主机名看本地登录时减少噪音-s 时间从指定时间之后的记录配合-t做时间窗口查询-t 时间到指定时间之前的记录按天、按月筛选登录历史-s和-t是很多人没注意到的宝藏参数。假设你要查 2024 年 1 月份root 的登录情况可以这样last -s 2024-01-01 -t 2024-01-31 root不同发行版对时间格式的容忍度略有差异有的支持20240101000000这种格式有的支持2024-01-01。实际使用前先man last确认一下别在脚本里写死格式不然换个环境就翻车。2.2 按用户、终端和时间窗口过滤last的位置参数可以直接接用户名比如last alice它会自动筛选出 alice 的登录记录。这点和grep相比有个好处它对字段是结构化匹配不会因为某个日志文本里恰好出现了用户名就误匹配。同理last pts/0可以筛选某个终端的所有记录last reboot可以直接看重启记录。但有一点要留意如果你想把来源 IP 当作过滤条件直接last 192.168.1.55在部分版本的last上不一定生效。更稳妥的做法是先last -i把主机名换成 IP再用 grep 筛选last -i | grep 192.168.1.55如果是想查某个时间段内的所有登录推荐配合-s和-t使用而不是输出全部日志后手动翻。比如查今天早上 8 点到 10 点之间所有人的登录last -s today -t tomorrow # 或者精确时间 last -s 2024-12-12 08:00:00 -t 2024-12-12 10:00:00这样输出干净利落不会把无关记录带进来。2.3 把 last 和其他常用命令串起来用last本身只是输出一张表真正产生价值的是把它的输出喂给其他文本处理工具。我在统计爆破源 IP 时最常用的一条命令是sudo lastb | awk {print $3} | sort | uniq -c | sort -nrlastb输出的是失败登录记录每行第三列是来源 IP。通过awk取出第三列排完序后统计去重最后按出现次数从高到低排列就能一眼看出谁在暴力破解我的服务器。同理如果想知道哪些账号被爆破得最凶就把第一列换成用户名sudo lastb | awk {print $1} | sort | uniq -c | sort -nr还有一个小技巧把last的登录历史输出交给wc -l统计总数配合grep计算某个特定 IP 的成功登录次数就能评估这个地址的可信度。比如last -i | grep 10.0.0.8 | wc -l这里的核心思路是last负责解析二进制 wtmpawk、sort、grep负责把解析结果变成可决策的数据。单看一条日志没什么用加上统计才有安全判断可言。3. 登录审计全家桶last、lastb、lastlog 和 who前面说了last只是成功登录记录的查看器。想做完整的登录审计必须把lastb、lastlog、who、w这几个命令放在一起理解。它们分别对应了登录历史的不同侧面组合起来才能还原完整画面。3.1 lastb失败登录的账本lastb和last从名字看像亲兄弟实际上也确实是同一个家族的lastb读取/var/log/btmp而这个文件专门记录失败的登录尝试。注意读取btmp一般需要 root 权限普通用户会看到权限不足的报错。实际使用就是加sudosudo lastb -n 20输出字段和last类似但含义完全不同。lastb里出现的一行几乎可以断定是一次认证失败的尝试。如果尝试次数很多那不是用户输错密码就是有人在爆破。我经常在新接入的服务器上跑一遍sudo lastb | wc -l看看上线前已经积累了多少失败记录。有一次一台刚交付的机器btmp 里居然有上万条记录一时间我们都以为是被攻击了后来才发现是部署脚本里反复用错密码重试造成的。所以看到失败记录先别慌要结合来源 IP 和账号去判断是机器行为还是人的行为。3.2 lastlog每个用户的最后登录时间lastlog读取的是/var/log/lastlog它和wtmp的角度不同wtmp是“按时间排的事件流”lastlog是“按用户排的状态表”。执行一下就能看到每个系统账号的最近一次登录lastlog输出通常包含用户名、登录终端、来源 IP、最后登录时间。lastlog -u alice可以直接查看指定用户非常适合快速判断某个账号是否还在被使用。比如运维发现一个一年没登录的账号那这个账号就应该被禁用或删除因为它往往是入侵者最喜欢的“僵尸账号”。有一点要注意lastlog对服务账号也会显示记录比如 sshd、mysql 这类系统用户它们正常情况下没有登录记录会显示“Never logged in”。如果某个服务账号显示有登录历史反而值得警惕。3.3 who/w看当前正在发生的登录who读取的是/var/run/utmp记录的是当前在线会话它的意义和last正好互补。last告诉你历史上有谁来过who告诉你现在有谁在。当last显示某条记录是 still logged in 时用who能立刻确认这个会话是否依然存在。who # 输出alice pts/0 2024-12-12 09:30 (192.168.1.55)w命令比who更强大它除了显示登录用户、终端、来源之外还会显示当前正在执行的命令和系统负载。我排查“服务器明明没人操作CPU 却跑满”的问题时第一反应就是敲w看看那个 still logged in 的会话到底在跑什么。这三条命令的配合逻辑是last看成功历史lastb看失败尝试lastlog看账号维度who看当下状态。四者并用才算把登录审计吃透了。3.4 多文件交叉排查思路只盯一个文件容易产生盲区。攻击者成功登录后会在wtmp留下成功记录他之前反复猜密码会在btmp留下失败记录如果他创建了新账号并成功登录lastlog会显示这个新账号的存在。把三个文件拼起来就能基本还原攻击者的完整行为链。我一般会按这样的顺序排查先用sudo lastb -n 50确认是否存在爆破迹象。再用last -i -n 30找最近的成功登录记录重点看有没有意外 IP。然后用lastlog检查每个账号的最后登录时间特别关注异常账号。最后用who和w确认当前有没有可疑会话在线上。这条链路看起来简单但在快节奏的故障处理中非常实用。省去了在多个日志文件里来回翻找的混乱。4. 实战从登录历史里揪出异常登录理论说了一堆不如直接还原一个排查场景。有一年我接手一台被“疑似入侵”的业务服务器业务方描述是“凌晨数据库数据异常怀疑有人动过服务器”。我到现场没急着查数据库日志第一个动作就是看登录历史。4.1 第一步看有没有不该出现的成功登录先执行last -i -n 30输出里正常应该只有运维人员的办公 IP。结果我看到一条凌晨 2 点 47 分从公网 IP 登录的 root 记录登录时间持续了 40 多分钟然后退出。这个时间点、这个来源、这个账号每一条都踩在危险线上。业务方确认该 IP 不是公司出口 IP那基本可以判定为异常登录。这里有个细节光看last默认输出还不够因为它把来源 IP 反解析成了主机名我看到的可能是内网某台机器名误导判断。加了-i之后原始公网 IP 直接暴露出来问题一目了然。这也是我反复强调-i参数的原因。4.2 第二步通过失败登录确认爆破点既然有异常成功登录那大概率之前有过大量失败尝试。执行sudo lastb -n 50结果里面确实有不少凌晨时段的失败记录来源 IP 和刚才异常的 IP 完全一致。随后我用统计命令看看这个 IP 到底尝试了多少次sudo lastb | grep 1.2.3.4 | wc -l几分钟内几百次尝试典型的密码爆破特征。此时基本可以确认攻击者先对 root 账号做了高频爆破中间某一次试中了弱口令成功登录。4.3 第三步还原时间线登录历史只能还原“什么时候登的、什么时候退的”具体登录后在服务器上做了什么还要靠鉴权日志来补。Debian/Ubuntu 上查看/var/log/auth.logCentOS/RHEL 上查看/var/log/securesudo grep Accepted password /var/log/auth.log | grep 1.2.3.4查出来发现 2 点 47 分确实有一次 Accepted之后攻击者切换到了另一个账号继续操作。结合 shell history 和其他应用日志最终定位到数据库异常操作发生在 2 点 58 分恰好在这段会话期间。时间线闭环问题才算真正定位。4.4 第四步处理并加固定位到这里的下一步不是急着删数据而是先止血立即踢掉可疑会话pkill -u 可疑账号或手动终止 SSH 进程。临时封锁攻击 IP可以先iptables -A INPUT -s 1.2.3.4 -j DROP挡住。修改受影响的所有账号密码包括 root、数据库账号、应用账号。禁用 root 直接 SSH 登录修改 sshd 配置PermitRootLogin no PasswordAuthentication no如果业务允许直接切换到密钥登录彻底关闭密码登录通道。检查是否留下后门包括定时任务、启动脚本、ssh authorized_keys 文件。这套流程之后我会反复用核心就是先看登录历史确定时间范围再查失败记录判断爆破事实再结合文本日志还原操作行为最后做加固。顺序不能乱否则很容易被局部日志带偏方向。5. last 命令常见问题与排查技巧last看着简单实际用起来还是会碰到各种情况。这一节我把自己踩过的坑和常见问题的解决方法整理出来算是避坑实录。5.1 wtmp 文件不存在或无法打开有些精简版系统、容器镜像或者刚部署好的机器可能根本没有/var/log/wtmp文件。执行last会提示类似last: /var/log/wtmp: No such file or directory解决方法很简单手动创建这个文件并设置好权限sudo touch /var/log/wtmp sudo chown root:utmp /var/log/wtmp sudo chmod 664 /var/log/wtmp创建之后last就能正常工作了但过去的记录肯定是补不回来的。另外如果看到权限不足的报错先ls -l /var/log/wtmp检查文件属主和权限通常属主是 root、属组是 utmp普通用户只读没问题。容器环境里如果挂载卷没有包含 wtmp也会出现查不到记录的情况这时候不是命令的问题而是挂载配置的问题。5.2 刚登录却查不到记录如果你明明刚通过 SSH 登录执行last却没有看到自己的记录先别怀疑人生按下面几步检查确认登录过程是否走了 PAM 认证。系统如果配置了某些激进的 PAM 模块可能跳过 wtmp 写入。确认/var/log/wtmp是否被 logrotate 轮转后重新创建权限是否正确。确认当前环境是不是容器。很多容器默认不写 wtmpSSH 到容器里确实可能没有记录。确认有没有人手动执行过清空命令比如 /var/log/wtmp。这里我最想提醒的是容器虽然常用但登录审计体系在容器里往往不全别把容器的last输出当成宿主机安全依据。真要审计容器登录得依赖宿主机日志或统一日志平台。5.3 时间对不上last输出的时间看起来不对多半是时区问题。服务器默认时区如果是 UTC而你习惯用东八区北京时间那输出就会差 8 个小时。解决方式有两种直接改系统时区sudo timedatectl set-timezone Asia/Shanghai。临时按自己的时区查看TZAsia/Shanghai last -F -n 10。另外硬件时间不准也会影响登录记录。如果服务器经常断电CMOS 电池没电系统每次启动时间都对不上last记录的时间自然也是乱的。先用date看系统时间再用timedatectl检查 NTP 同步状态能从根上避免很多诡异日志。5.4 日志轮转后想查历史记录/var/log/wtmp会像其他日志一样被 logrotate 轮转。日志轮转后历史文件会在同目录下生成类似wtmp.1、wtmp.2.gz的文件。last默认只读当前的wtmp想查历史就要用-f指定文件last -f /var/log/wtmp.1如果历史文件被压缩成了.gz或.xzlast没法直接读。我的做法是先解压到临时目录再让last去读zcat /var/log/wtmp.1.gz /tmp/wtmp.1 last -f /tmp/wtmp.1部分版本的last支持-f -从标准输入读取理论上可以zcat ... | last -f -但我见过老版本对这种方式支持不稳定所以更推荐先解压成临时文件路径虽然笨但胜在稳。5.5 文件太大导致 last 很慢服务器运行时间很长、登录量很大时wtmp会膨胀到几百 MB这时候直接敲last确实可能卡顿。不过别慌这属于正常现象解决办法有两个用last -n 50限制只输出最近的记录多数版本的last会停止继续扫描速度明显更快。配合 logrotate 把 wtmp 轮转周期缩短比如从每月一次改为每周一次防止文件无限膨胀。顺便说一句如果看到 wtmp 文件异常巨大也要留个心眼。攻击者有时候会故意不做清除但在里面反复写无效记录让日志变得难以分析。文件大小和登录量明显不匹配时果断翻轮转日志和鉴权日志。5.6 快速排查速查表我把上面这些常见问题整理成一张表方便你在实际工作中对照现象大概率原因优先处理方案提示 wtmp 不存在系统精简或容器未挂载手动创建并设置权限查不到刚发生的登录容器环境、PAM 配置异常、手动清空核对登录机制与日志轮转配置登录时间差 8 小时系统时区不是本地时区timedatectl修改时区或 TZ 临时指定查不到历史记录logrotate 已轮转默认只读当前文件last -f /var/log/wtmp.1压缩文件读不了last 不支持直接读 gz/xz先解压到临时文件再指定读取last 输出很慢wtmp 文件过大用-n限制条数并调短轮转周期lastb 显示权限不足普通用户读取 btmp 受限加 sudo 执行6. 登录历史背后的一些深水区经验到了这个章节last的基本用法你已经掌握了但我想多说几句关于“登录日志不可全信”的经验。last依赖/var/log/wtmp这个文件的位置、权限、轮转策略都直接影响记录完整性。但要清楚一点凡是登录到服务器的人一旦拿到 root 权限就有能力修改甚至清空本机上的日志文件。攻击者完全可以删掉自己的会话记录让last里看起来干干净净。所以对公网业务机这种高价值目标只靠本地 wtmp 远远不够。我的习惯是把登录审计做成“本地 远端”双重保险。远端方案不复杂比如配置 rsyslog 把/var/log/auth.log、/var/log/secure实时转发到集中日志服务器或者至少把日志定期同步到独立存储。这样一来攻击者清理了本机日志我们还能从远端把记录捞回来。单独依赖last的本地输出在对抗有经验的黑客时是很脆弱的。还有一点值得提chattr 加不可变属性这类操作要慎用。网上很多教程让人对/var/log/wtmp执行chattr a以为这样能防篡改。听起来很美但实际生产环境里加了 append-only 后可能会和 logrotate 产生冲突导致日志轮转失败反而搞出一堆运维事故。安全性不是靠单个文件的“奇技淫巧”堆出来的而是靠权限收敛、集中审计、定期检查互相配合。我个人现在每天早晚各看一次服务器状态其中一定会包含last -i -n 10和sudo lastb -n 10。别小看这几条输出很多问题在最早期都是通过登录历史暴露的。服务器上没有陌生人登录比装了再多安全软件都让人安心。如果你也打算把last写进巡检脚本建议脚本里同时输出成功和失败两类记录并且用-F把时间精确到秒。脚本不用做得太花哨关键是它能坚持每天跑。日志这件事坚持比对习惯本身比命令参数值钱得多。
返回列表