ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Linux日志体系全解析:从查看、轮转到安全审计实战

2026/9/16 2:09:48 拓冰建站 浏览量
Linux日志体系全解析:从查看、轮转到安全审计实战 1. 先摸清Linux日志体系日志从哪来、往哪去、归谁管搞Linux运维和安全的不管你是刚入行还是干了几年最后都会撞上同一个问题系统出了问题、被人入侵了、服务莫名其妙挂了第一反应都是去翻日志。日志这东西平时没人关心一旦出事它就是唯一的线索来源。我最早接触Linux的时候总觉得日志就是一堆不断增长的文本文件谁不会看啊真到排查问题的时候才发现看不懂日志、找不到关键日志、不知道日志在哪比问题本身还让人头大。先说清楚一个最容易混淆的点Linux日志不是只有一种形态。很多人以为日志就是/var/log/messages其实完整的日志体系至少包含三层。第一层是内核和系统服务的日志由systemd-journald负责采集存放在内存和磁盘的journal目录里用journalctl命令查看。第二层是传统文本日志由rsyslog服务把各类程序产生的日志按规则写入/var/log下的对应文件比如messages、secure、cron这些。第三层是应用自身的日志像Nginx的access.log、应用的debug日志线、数据库的error log这些由应用自己管理路径千奇百怪。这三层并不是互相替代的关系而是同时存在、互相补充的。systemd-journald管得很宽但journal文件是二进制的不能直接拿文本工具去读rsyslog输出的文本日志可读性好很多老运维习惯直接cat和tail看但缺点是程序如果不调用syslog接口rsyslog就接不到它的日志。所以真正排查问题的时候我们往往是两头都看双管齐下。还有一个必须知道的点日志是会丢的。journald默认把日志存在内存里只有配置了持久化选项才会落盘重启之后内存日志就没了。rsyslog这边如果日志量特别大又没配好轮转文件能撑爆磁盘分区。这些坑我后面会逐个展开先记住一个原则日志系统的第一价值不是记录而是在你需要的时候还能找得到、读得动。1.1 /var/log下最重要的几份日志文件传统Linux运维最常打交道的目录就是/var/log。刚接触的时候看到一堆文件很容易懵其实真正常用的就那几个我按用途整理了一个比较全的清单。日志文件记录内容主要用途/var/log/messages系统整体运行信息包括内核日志、服务启停、网络变化等第一排查目标系统异常先看它/var/log/secure认证和安全管理日志包括ssh登录、sudo执行、用户切换安全审计最核心的文件/var/log/croncrontab定时任务的执行记录排查定时任务不执行/var/log/dmesg内核环形缓冲区的消息主要涉及硬件和驱动硬件识别、启动报错排查/var/log/boot.log系统启动过程日志开机过程卡住、引导失败排查/var/log/lastlog所有用户最后一次登录时间二进制格式查看历史登录情况/var/log/btmp失败的登录尝试记录二进制格式暴力破解检测/var/log/wtmp用户登录和退出记录二进制格式配合last命令使用/var/log/audit/audit.logLinux审计框架的审计日志文件监控、系统调用审计/var/log/nginx/access.logNginx访问日志属于应用日志Web服务访问分析这里面有四个二进制日志容易被新手忽略就是lastlog、btmp、wtmp还有utmp。它们不能用cat直接看必须用last、lastb、who这些命令去读取。安全审计的时候lastb的输出简直是指纹级的证据——它会显示所有失败的登录尝试如果某个IP在一小时内尝试了上百次密码登录那就是教科书级的暴力破解行为。1.2 journald和rsyslog两种生态怎么协同工作很多Linux发行版现在默认同时跑着systemd-journald和rsyslog。一开始我也觉得这俩功能重叠后来才明白它们各管一摊是有道理的。journald的优势在于和systemd深度集成所有由systemd管理的服务它们的标准输出和标准错误输出都会被journald捕获。这意味着即使一个程序完全没有写日志文件你也能通过journalctl -u 服务名看到它的输出。这个特性在排查服务启动失败时特别有用很多服务起不来报错信息就打在stdout上不看journalctl根本不知道发生了什么。rsyslog的优势在于灵活的路由和文本格式。它接收系统内各个组件发来的syslog消息然后根据优先级和来源写到不同文件里。最重要的是rsyslog支持把日志转发到远程日志服务器这就解决了日志的集中管理和防篡改问题——如果日志只存在本机攻击者一旦拿到root权限第一件事就是清日志。后面讲安全审计的时候还会细说。两个服务可以同时存在journald采集的信息可以通过一条配置转发给rsyslog处理相当于journald当收集器rsyslog当分发器。实测下来这个组合稳定性和效率都不错。1.3 日志轮转不处理的话磁盘迟早被写爆日志轮转是每个Linux运维迟早要面对的事。日志文件只增不减如果系统跑上几个月不重启messages文件可能膨胀到几个G。一旦/var分区写满轻则服务报错重则系统完全卡死。具体的轮转机制由logrotate负责配置文件在/etc/logrotate.conf和/etc/logrotate.d/目录下。它通过cron定时任务每天触发按照配置对日志进行压缩、循环、删除旧文件。举个最常见的配置\/var\/log\/messages { weekly rotate 4 compress delaycompress missingok notifempty create 0600 root root }这段配置的含义是日志文件每周轮转一次保留4份历史归档老文件用gzip压缩压缩操作延后一周执行文件缺失不报错空文件不轮转轮转后新文件以0600权限由root创建。我刻意加上create这一行是为了强调轮转过程中很容易出现权限问题。如果轮转生成的新日志文件权限不对rsyslog进程可能往里写不了东西这时候系统日志就悄悄断更了。排查这类问题时可以用logrotate -d /etc/logrotate.conf先做一次调试运行看看配置和执行情况。2. 日志查看的基本功命令、参数、管道组合日志文件在那里接下来是怎么看、怎么快速定位的问题。很多新手习惯只用一个tail -f盯着滚动输出真到排查问题时效率极低。我常用的思路是先用全局视图缩小范围再用精准过滤定位具体行最后结合上下文还原场景。2.1 必会的基础命令组合最基础的一批命令tail、head、less、grep、awk、sed这些必须熟练。我举几个在实际排查中几乎每天都会用到的组合。查看某个日志文件的最后50行并且持续跟踪新写入的内容tail -n 50 -f \/var\/log\/messages在日志里搜索关键词并显示匹配行的前后5行上下文。less本身就支持这个操作less \/var\/log\/secure # 进入less后输入 \/Failed 回车然后按 n 跳到下一个匹配 # 按 v 可以直接用vim编辑当前文件如果有权限grep时加上上下文参数这个在查报错时特别有用grep -n -B 5 -A 10 Out of memory \/var\/log\/messages-B和-A分别代表匹配行前5行和后10行还原错误发生的环境。按时间窗口过滤journald日志这是journalctl最实用的功能之一journalctl --since 2024-11-01 09:00:00 --until 2024-11-01 09:30:00只看某个服务的日志带上最近100行journalctl -u nginx.service -n 100 --no-pager我这里特意用了--no-pager因为很多Linux发行版的journalctl默认会调用less分页在脚本里直接执行的话会卡住。2.2 读懂一行日志时间、主机、进程、消息四层结构很多人看日志就是扫一眼消息文本其实一行标准syslog日志是有固定结构的拆开来每个字段都有价值。举个例子Nov 2 14:33:21 web-server-01 sshd[23456]: Failed password for root from 203.0.113.44 port 52310 ssh2从左到右拆解时间是11月2日14:33:21主机名是web-server-01进程是sshdPID是23456后面方括号里的数字是进程ID冒号之后才是真正的消息内容。时间字段可以用来定位异常发生的时间点主机名在集中日志平台里特别重要标注日志来自哪台机器进程名和PID能帮你追到具体是哪个程序在说话消息内容才是真正的有效信息。排查故障的时候如果只看消息内容不看进程名很容易被误导——比如内核打印的网络相关消息和NetworkManager服务打印的网络消息虽然都涉及网络但排查方向完全不同。2.3 从几十万行日志里快速定位问题日志文件大了以后直接搜索效率很低而且很容易被无关消息干扰。我的做法是分三步。第一步先确认出问题的时间范围。用户反馈早上9点服务不可用那就先看9点前后的日志。journalctl支持--since和--until精确指定时间窗口传统日志文件没有这个功能但可以这样配合awk $0 Nov 2 09:00:00 $0 Nov 2 09:30:00 \/var\/log\/messages需要注意awk比较的是字符串日期时间格式必须和日志文件里完全一致包括空格数量。第二步统计错误级别的消息数量看看是不是集中爆发。比如统计messages里各时间段的error数量grep ERROR \/var\/log\/app.log | awk {print $1, $2} | uniq -c第三步针对定位到的时间段查看当时的上下文。用系统日志排查问题最忌讳的是只盯着一行报错看错误的前因后果往往跨度很大可能前面一堆正常的消息恰恰是触发错误的根本原因。3. 故障排查用日志一步步定位系统问题的实战方法日志排查是我工作中最常干的活。踩过的坑多了总结出来一套比较固定的流程遇到问题先按流程走能省不少时间。3.1 系统启动失败先看这两处机器开机后卡在黑屏或者grub界面是最让人头疼的问题。很多人第一反应是反复重启其实日志就在那里关键在于能不能看到。如果开机过程中能看到字符界面可以先按CtrlAltF2切到另一个tty登录后查看日志。最直接的是看dmesg的输出它管内核级别的启动信息dmesg | grep -i error dmesg | grep -i faildmesg里包含内核启动时的驱动加载、设备识别、文件系统挂载等信息。硬件故障、驱动冲突、磁盘错误都能在里面找到蛛丝马迹。如果系统能正常登录但启动过程有异常重点看/var/log/boot.log。这个文件记录的是系统服务在启动阶段的状态哪些服务启动失败、哪些被跳过了一目了然。还有一招我常用systemd把启动过程做成了一条时间线可以用systemd-analyze blame查看哪个服务拖慢了启动速度再用systemd-analyze critical-chain定位启动链的卡点。这个命令本身不读日志文件但底层调用的数据来源和journald是同源的。3.2 服务起不来或频繁崩溃journalctl才是主力传统排查服务问题的方法是看/var/log/messages但journald出现以后我更推荐先看journalctl。定位服务问题最常用的一条命令journalctl -u myservice.service --since today --no-pager这条命令能把myservice这个服务今天所有的输出打印出来。很多服务启动失败的原因就藏在stdout里——比如Java应用报端口被占用、Nginx报配置文件语法错误、数据库报磁盘空间不足。再看selinux拦截的情况这个坑我接过好几次。服务明明配置正确启动就是报Permission denied第一反应以为是文件权限查了半天没问题。后来用下面这条命令看审计日志才发现是selinux策略拦了grep denied \/var\/log\/audit\/audit.log | tail -20如果不想动selinux配置也可以临时用audit2why把审计日志翻译成人话ausearch -m avc -ts recent | audit2why3.3 磁盘被日志或其他文件塞满时的紧急处理日志写爆磁盘是个经典故障。现象是服务频繁报错df -h一看/var或者/分区已用100%。紧急情况下最快速的处理方式是找到大文件并清理du -sh \/var\/log\/* | sort -rh | head -10这条命令列出/var/log下占用空间最大的前10个文件。找到之后先确认日志内容确实不需要了再决定用truncate -s 0清空而不是直接rm。直接rm文件有个隐患如果某个进程还持有这个文件的句柄磁盘空间不会真正释放只会在进程重启后才释放。这在WSL里删文件后空间不释放是个常见现象本质上就是文件被进程占用着。用truncate把文件大小置为0磁盘空间立即释放进程也不会出问题。truncate -s 0 \/var\/log\/messages如果日志文件还在以极快的速度增长说明有程序在疯狂写日志。用lsof找出占用文件的进程然后针对性处理lsof | grep deleted这里顺便提一个排查思路磁盘空间满不一定是日志多也可能是临时文件、docker镜像、core dump。du -h --max-depth1 \/从根往下逐层排查是通用做法。3.4 应用闪退类问题游戏或桌面软件的日志排查思路除了服务器场景Linux桌面用户也会遇到软件闪退的问题很多新手不知道去哪看日志。这里讲一个通用方法溶入windows生态下的事件查看器思维Linux同样有事件记录。如果是通过systemd启动的服务或桌面应用先看journalctljournalctl -u 应用名.service --since today如果是普通图形化程序运行后闪退最简单的方法是在终端里直接前台运行程序崩没崩、报了什么错终端里全都有。很多图形程序在崩溃时会向系统日志写入一条异常记录可以用dmesg或者journalctl查journalctl -k --since today | grep -i segfault dmesg | grep -i segfaultSegmentation fault段错误在dmesg里会留下记录同时还会显示崩溃进程的PID、触发地址等内容这些对开发者排查bug很有用。另外点名一个方式检查core dump是否开启。如果开了程序崩溃时会生成core文件用gdb加载core文件就能看到崩溃时的完整调用栈ulimit -c unlimited gdb \/usr\/bin\/myapp \/var\/core\/core.123454. 安全审计从日志中还原攻击痕迹与异常行为安全审计和故障排查看日志的角度完全不一样。故障排查关心的是哪里坏了安全审计关心的是谁进来过、做了什么、动了什么。日志在这里就是证据链必须看得非常细致。4.1 登录日志里藏着大量攻击痕迹/var/log/secure是安全审计的第一现场。所有通过ssh、su、sudo进行的认证行为都会记录在这里。先看正常登录的记录长什么样Nov 2 14:30:01 web-server-01 sshd[23321]: Accepted password for zhangsan from 192.168.1.100 port 52101 ssh2再看失败的登录尝试Nov 2 14:33:21 web-server-01 sshd[23456]: Failed password for root from 203.0.113.44 port 52310 ssh2对比一下就能发现失败的记录IP和端口都不固定这正是暴力破解的典型特征。用下面这条命令可以把尝试登录次数排名前10的IP统计出来grep Failed password \/var\/log\/secure | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -10这里awk取的是倒数第4个字段也就是IP地址的位置。日志格式稍微不同字段位置会偏移不确定的时候先用head看几行原始记录再写管道。btmp文件专门记录失败的登录流程读取方式是用lastb命令lastb -n 50用last命令查看最近的成功登录记录last -n 20如果发现某个用户账号在凌晨3点有成功登录记录而这个人根本不可能在那个时间操作那就是账号被攻破或内鬼操作的有力证据。4.2 sudo和su的日志提权行为必留痕迹攻击者拿到普通用户权限之后通常会想办法提权到root。sudo和su是他们最常用的两条路而这两条路在日志里都异常清晰。看sudo执行记录journalctl -u sudo -n 50 # 或者 grep sudo \/var\/log\/secure典型记录长这样Nov 2 15:01:22 web-server-01 sudo[24567]: zhangsan : TTYpts\/0 ; PWD\/home\/zhangsan ; USERroot ; COMMAND\/bin\/su -这条日志记录了zhangsan在哪个终端、哪个目录、用什么身份、执行了哪条命令。如果用户的sudo使用频率和业务完全不匹配比如一个前端工程师频繁sudo执行useradd、passwd、修改/etc/sudoers那就要警惕了。Linux提权也是渗透测试里绕不开的话题。日志层面来看除了sudo和su一些漏洞利用行为会在内核日志里留下特征。比如脏牛等提权漏洞利用往往伴随内核崩溃信息或者异常的内存访问记录。虽然系统补丁打了以后这类漏洞少了但从审计角度来说dmesg和messages里的异常内核消息始终值得关注。4.3 auditd审计把关键操作都在眼皮底下如果想要更精细的审计能力光靠secure和messages是不够的。Linux自带的auditd审计框架可以监控文件访问、系统调用、用户行为。它在安全审计中的价值很大尤其是涉及到登录基线、关键文件完整性这些场景。auditd的规则配置在/etc/audit/rules.d/下。举个实际使用中的例子监控/etc/passwd文件被修改的动作auditctl -w \/etc\/passwd -p wa -k passwd_changes这条规则的意思是对/etc/passwd文件监控写w和属性变化a事件标记为passwd_changes。规则生效后查看审计日志ausearch -k passwd_changes -ts recent输出会显示什么时间、哪个用户、用什么命令修改了passwd文件。这个就比secure日志深了一层——secure只记录sudo命令本身auditd能记录到具体的系统调用级别。auditd还有一个高频场景监控某个用户的所有操作。将键盘记录级别的行为审计打开然后查看auditctl -a always,exit -F archb64 -S execve -k user_exec ausearch -k user_exec -ui zhangsan -ts today这样配置之后zhangsan执行的每一条命令都会被记录下来。对应急响应来说这招能极大缩减排查范围不用靠猜来还原攻击者的操作路径。4.4 在一堆正常日志里发现异常的可疑特征安全审计最大的难点不是看日志而是在海量正常日志中定位到那几条异常的。几个常用的思路可以交叉验证。高频失败登录这个前面已经说过核心特征就是短时间内大量失败记录。如果某个IP在某一小时段内尝试了几百次失败登录且之后有一次成功登录基本可以判定为破解成功。这时候要立刻追溯到那条成功的记录看它登的是哪个账号、来源IP是哪。非法时间点的操作。每个人都有固定作息凌晨时段的登录无论成功还是失败都值得标记。正常业务无关的操作。一个web服务器突然出现了大量yum install、curl到外部域名的记录说明可能被种植了恶意脚本或者下载了攻击工具。异常文件的创建和调用。日志里频繁出现/tmp/目录下的可执行文件被运行这也是web服务器上常见的webshell特征。可以用auditd监控/tmp目录的写和执行权限。5. 渗透复盘视角攻击者如何清理日志我们如何对抗和还原这个部分从一个更专业的角度来讲假设你的系统已经被入侵了攻击者在离开之前会做什么答案是——清理日志。所以安全审计不能只懂得看日志还必须懂得日志如何被破坏以及如何对抗这种破坏。5.1 两类常见的日志清理手法第一类是直接删除或清空日志文件。最简单粗暴的rm -rf \/var\/log\/*或者cat \/dev\/null \/var\/log\/secure把文件内容清空。这种方式门槛低但也容易暴露——文件历史痕迹可以通过inode和文件系统层面部分恢复而且清空所有日志本身就是一个巨大的告警信号。第二类是精确删改和混淆。攻击者并不总是把整个日志删掉而是精准地删除和自己相关的条目。比如用sed删除secure里包含自己IP的行或者修改时间戳让日志顺序错乱。这种手法很难被察觉尤其是日志量非常大、人工不可能逐条核对的情况下。防御端的对应策略也很清晰日志不能只存在本机也不能只保留一份。远程日志服务器和日志备份是底线中的底线。rsyslog可以配置将日志实时转发到远程服务器*.* 192.168.1.200:514这一行配置放在/etc/rsyslog.conf末尾或者/etc/rsyslog.d/remote.conf里系统内所有syslog日志都会通过UDP 514端口发送到远程服务器。远程服务器上配置好接收规则和存储目录这样即使本机日志被删远程服务器上仍然保留着完整记录。5.2 从残留日志还原攻击路径假设攻击者清了本机日志但远程日志服务器上保存了完整记录。那怎么利用这些记录还原攻击链条。我复盘过一个真实的入侵案例大致还原流程是这样。第一步看登录记录。从secure日志里找到攻击者的第一次成功登录时间、使用的账号和来源IP。通常攻击者会先尝试暴力破解从大量Failed password记录时间线就能看出来从哪个IP开始扫描、多久爆破成功。第二步看命令执行记录。secure日志里能找到sudo执行的每一条命令配合auditd或bash history的记录能还原攻击者提权和留后门的整个过程。比如执行useradd添加了隐藏账号、修改了/etc/shadow、在/tmp下放了shell脚本、通过crontab做了持久化。第三步看文件变动。auditd能记录关键文件的访问和修改情况通过时间点串联能知道攻击者改了哪些配置、上传了哪些文件。这些文件就是webshell、后门程序、挖矿程序找到之后还要做样本留存。第四步看网络连接。防火墙日志、系统当前连接、历史连接痕迹可以还原攻击者与C2服务器的通信情况。ss -tunap查看当前连接lsof -i列出所有网络相关进程netstat更传统一些。入侵后门往往就是主动外连的进程。5.3 保证日志只能追加删除和篡改都困难Linux文件系统本身提供了防止日志被篡改的机制。最基础的是immutable属性通过chattr命令设置。设置之后即使是root用户也无法修改或删除文件要清除属性得先取消immutable标记。chattr a \/var\/log\/securea参数是append-only文件只能追加内容不能修改已有内容、不能删除、不能重命名。还有更强的i参数完全锁定文件。但这里要说明chattr只是一层防护不是绝对安全。攻击者拿到root权限后可以先执行chattr -a取消属性再清理。所以更可靠的方式还是日志异地实时同步。我自己的处理方式是双保险本机日志加上append-only属性同时rsyslog实时转发一份到远程日志收集服务器。即使本机日志被动过远程那份还是完整的。还有一个容易被忽略的点:日志的时间同步。服务器时间不准的话日志里的时间戳就是废的对不上实际攻击时间线。部署一套NTP时间同步是所有日志审计工作的前提。这个事一般配系统环境的时候顺手就做了但确实见过不少生产服务器时间偏移严重的。另外日志轮转也会影响安全审计。日志轮转后旧文件被压缩改名如果审计工具只看固定文件名就可能漏掉历史数据的分析。所以做日志审计的时候要考虑把/var/log/messages.*等归档文件纳入检查范围不只是看最新那个。6. 日志运维的几个实用心得最后分享几个基于实际经验总结的做法。不按严格的技术章节走都是一些散点建议但每条都是踩过坑之后才想明白的。日志集中管理要趁早。一开始日志都在各台服务器本地排查问题的时候到处跳转、逐个tail效率非常低。后来搭了一套集中日志平台用Filebeat采集、Kafka缓冲、Elasticsearch存储、Kibana展示虽然前期搭的时候费了不少功夫但后面所有排查和审计工作都能在一个界面里完成。如果觉得自己搭ELK太重至少也要把rsyslog集中转发做起来。日志字段的规范统一很关键。很多程序自带日志的格式千奇百怪有的连时间戳都没有用起来非常痛苦。尽量让开发在写应用日志的时候遵循同样的标准比如统一使用ISO8601时间格式、包含请求ID、包含用户ID。日志数据量大的时候这些标准化字段能大幅提升检索效率。定期做日志演练。平时不看日志等出安全事件才去看那必然手忙脚乱。我建议每个月找一个业务低峰时段模拟几个常见场景来练习日志排查比如假设某台服务器被暴力破解了用日志还原整个过程。练过几次之后真遇上应急响应心里就会有底。还要留心应用日志和系统日志的关联。纯看系统日志有时候查不出问题的根因。举个例子Nginx返回500系统日志里什么都没有但应用日志里记录的是一条数据库连接超时的异常。真正要修的是数据库连接池配置不是Nginx。排查问题的时候把系统日志、应用日志、数据库日志三者结合起来看定位速度和准确率都能明显提升。日志压缩保留的周期也要提前规划。服务器磁盘就这么大日志保留多久、多长时间归档一次、归档后放哪都要有明确策略。行业里常见的是系统日志保留90天安全类日志至少保留180天合规要求高的行业甚至要求一年以上。我的做法是安全日志单独存一份密集归档其他日志正常轮转这样既控制存储成本又保证了应急时有关键数据可用。还有一个很多人忽略的小细节日志文件权限的问题。/var/log/secure、/var/log/btmp这些日志里包含大量敏感信息权限必须严格控制。默认是600权限owner是root不要为了图方便改成644或者把目录权限放开。曾经就有过因为日志文件权限过大导致普通用户能读到root账号的登录时间和来源信息给安全审计带来了隐患。排查故障和高危操作的时候顺手记录一份时间线笔记。把什么时间、看了哪个日志文件、发现了什么异常、做了什么操作逐条记下来。这个习惯在长时间的应急响应中尤其管用——精力消耗大的阶段最容易忘记前面看过什么、改过什么有了时间线笔记复核和交接都方便很多。这个建议听起来朴素但在实际工作中它帮我避免过很多次重复排查和误操作。最后再说一条日志是系统运行的黑匣子但它不会自己开口说话。只有当你遇到问题时懂得去哪找、找到了能读懂、读懂了能串联起来它才会真正发挥作用。与其等故障发生了再急急忙忙学命令不如现在就打开你的Linux系统把/var/log下每个文件翻一遍感受一下它们各自的性格。这个十分钟的小动作比背一百条命令都管用。