ARTICLE DETAIL

资讯详情

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

Linux日志体系全解析:从故障排查到安全审计的实战指南

Linux日志体系全解析:从故障排查到安全审计的实战指南 做运维的朋友应该都有这种经历半夜被电话叫醒说服务器出问题了第一反应是什么不是急着重启而是先跑到/var/log目录下捞日志。我干了十几年Linux运维和安全应急越来越觉得一个系统的稳定与安全一半靠代码和架构另一半就靠这些平时不起眼的日志文件。日志这东西平时没人看一旦出故障、被入侵它就是你唯一的目击证人。这篇内容不聊虚的从故障排查、安全审计、渗透复盘三个角度把Linux系统里那些关键日志掰开揉碎讲一遍包括日志文件都在哪、每条日志怎么读、怎么定位问题、怎么从日志里还原一次攻击路径。适合运维工程师、SRE、安全防护人员也适合准备Linux面试的同学——面试官最喜欢问日志相关的问题因为这是实践经验的最好试金石。1. Linux日志体系全景这些文件和命令到底管什么1.1 从内核到用户态的日志流转Linux系统里的日志不是只有一种它是一套从内核到应用层层传递的体系。最早的日志服务是 syslog后来逐渐被 rsyslog 和 syslog-ng 取代再后来 systemd 出现systemd-journald 又成为很多发行版的默认日志组件。但无论怎么变内核都会通过 printk 输出内核日志应用可以通过标准 syslog 协议把日志交给日志服务再由日志服务写到文件或转发到远端。内核日志是系统最早、最底层的“老大哥”。你用dmesg或journalctl -k看的就是它。它记录了硬件识别、驱动加载、磁盘I/O错误、内存不足OOM、文件系统异常等信息。故障排查时如果系统起不来或者运行中硬件报错内核日志往往是第一步要看的。用户态日志则更丰富认证日志、网络服务日志、定时任务日志、应用自己的日志文件等等。rsyslog 负责接收内核和各类守护进程发送的日志消息根据规则写到不同文件。比如/var/log/messages是一般性地系统消息/var/log/secure记录认证和权限相关日志/var/log/cron记录计划任务。同时 systemd-journald 也会捕获几乎所有进程的 stdout/stderr 输出用二进制格式集中存储通过journalctl查询。1.2 常用日志文件与对应场景这里把常见的日志文件列成一个表方便对照使用。不同发行版文件名可能略有差异但大部分 CentOS/RHEL 系和 Ubuntu 系的路径基本一致。日志文件记录内容典型排查场景/var/log/messages系统整体运行信息、服务启停、网络变化、用户态应用日志定位随机性故障、程序报错/var/log/kern.logUbuntu或 dmesg 输出内核日志、硬件错误、驱动信息硬件故障、启动失败、内核模块加载/var/log/secure或/var/log/auth.logSSH登录、sudo提权、用户认证失败/成功暴力破解分析、认证审计/var/log/boot.log开机启动过程信息启动卡住、服务启动失败/var/log/croncron 定时任务执行记录排查定时任务为什么没执行/var/log/maillog或/var/log/mail.log邮件发送接收记录Postfix 等邮件服务故障/var/log/httpd/access_log、error_log或/var/log/nginx/access.logWeb访问日志和错误日志网站中文乱码、404风暴、攻击特征/var/log/dmesg内核环形缓冲区信息与 dmesg 命令输出一致查看开机后的硬件日志/var/log/wtmp所有用户成功登录和注销记录通过 last 命令查看/var/log/btmp登录失败的记录通过 lastb 查看暴力破解情况/var/log/lastlog每个用户最近一次登录时间通过 lastlog 排查账号使用情况1.3 journald 与 rsyslog 的配合与取舍说到 systemd-journald很多新手会懵日志文件是二进制的不能直接 cat 怎么办用journalctl。它最大的优势是自带索引查询效率高而且默认捕获所有进程的错误输出比 rsyslog 更全面。但 journald 也有短板默认日志只存在内存里的/run/log/journal重启后就没了一部分就算持久化配置了/var/log/journal日志文件依然是二进制普通文本处理工具用不上。所以生产环境通常的做法是journald 负责接收和临时存储rsyslog 负责把日志转发到明文文件或远端日志服务器。两条腿走路既保证了查询效率又保证了可保留、可审计。需要注意journald 的配置在/etc/systemd/journald.conf比如把Storageauto改成Storagepersistent就能开启持久化。改完要重启 systemd-journald 服务。rsyslog 的主配置在/etc/rsyslog.conf规则文件在/etc/rsyslog.d/没事别乱动主配置文件在/etc/rsyslog.d/下新建.conf文件写规则更规范。2. 故障排查从报错到根因的日志实战2.1 定位故障的基本思路时间和关键字是第一生产力故障排查的本质就是缩小范围。日志那么多你不可能一行行读完。先用时间定位故障发生的前后半小时是黄金窗口。再用关键字定位报错信息里的关键词比如error、fail、timeout、I/O error、Out of memory。具体怎么做比如收到告警说某台机器磁盘快满了你第一件事是df -h和df -i确认是空间满还是 inode 满然后去/var/log/messages里搜No space left on device可能还要看/var/log/kern.log里同时间段的 ext4 报错。如果日志里出现blocked for more than 120 seconds大概率是存储链路I/O卡死这时候该查磁盘阵列或云盘状态了。经验之谈排查问题的时候别只盯着报错那一行。上下文很重要。用grep -C 5 错误关键词看到前后五行往往真正的根因藏在上文里。比如php-fpm报Segmentation fault前面可能就有数据库连接断开的提示问题出在依赖服务而不是PHP进程本身。2.2 磁盘和文件系统问题的排查案例拿一台真实服务器举例。有一天用户反馈网站生成缓存失败df -h一看根分区分区满了但du查了一圈没有特别大的文件。用lsof | grep deleted一查发现一个被删除但仍被进程占用的日志文件占了50G。这种经典问题日志里未必直接报错但/var/log/messages里会有ext4_fsblk或者No space left on device的记录。再讲一个 inode 耗尽的案例。df -h显示还有几十G却总报cannot create temp file马上查df -i结果 /tmp 所在的文件系统 inode 用完了。为什么会这样多半是某个程序疯狂创建小文件。这时去日志里看可能有audit: file system的审计信息或者有程序不断写failed to open的报错跟着进程 PID 就能揪出元凶。处理这类问题操作顺序很重要先释放空间恢复服务再查根因。释放空间可以删旧日志、清临时文件最不济用du -x -h --max-depth1 / | sort -hr | head -20找出大目录。千万不要一上来就重启机器起不来可能更麻烦。2.3 服务启动失败与进程崩溃排查服务起不来第一反应看服务状态systemctl status httpd但这段输出可能只显示最后几条日志不够全。更靠谱的是journalctl -u httpd --since 10 minutes ago把该服务的全部日志拉出来。如果服务压根没写日志那就得看sudo systemctl start httpd时的终端输出或者strace跟踪进程了。进程崩溃里最典型的是 OOM Killer。当内存耗尽内核会杀掉进程来保住系统。日志里会出现Out of memory: Kill process 12345 (java) score 256 or sacrifice child这样的记录。你按照记录里的进程名和 PID去对应业务日志里找内存申请失败的线索。同时要看同一时间段的top或监控数据判断是内存泄漏还是真的配额不够。还有一种情况是核心服务被 systemd 反复拉起日志里全是start request repeated too quickly。这类问题往往是服务启动脚本的前置条件没满足比如配置文件写错、端口被占用、依赖服务没起来。用journalctl -u xxx -e看最近的报错就行。2.4 日志查询命令的进阶用法既然要排查故障命令就得用得溜。tail 和 less 是基本功但对于大量日志还得会过滤和统计# 查看系统日志的最新100行并持续跟踪 tail -f /var/log/messages # 在日志中定位关键词显示前后5行 grep -C 5 nf_conntrack: table full /var/log/messages # 统计某个时间段内error出现次数最多的前10个服务 sed -n /2025-01-15 08:00/,/2025-01-15 09:00/p /var/log/messages | \ awk {for(i5;iNF;i) if($i ~ /kernel|httpd|sshd/) print $i} | \ sort | uniq -c | sort -nr | head # journalctl 按时间过滤 journalctl --since 2025-01-15 08:00 --until 2025-01-15 09:30 -p err # 查看某个服务所有日志 journalctl -u nginx.service -f # 查看内核日志 journalctl -k -f注意一点journalctl -p err表示只打印错误及以上级别但有些故障不是 error 级别而是warning或notice排查时别把级别卡得太死先看全部再逐步过滤。3. 安全审计日志里的“异常行为”长什么样3.1 认证与登录日志的解读安全审计最基础的是认证日志。RHEL/CentOS 系在/var/log/secureUbuntu/Debian 系在/var/log/auth.log。这里记录着每次 SSH 登录、sudo 提权、su 切换用户的成败。一个典型的暴力破解特征是这样的大量Failed password for invalid user记录时间间隔很均匀来源 IP 分散或固定有时还伴随Invalid user提示说明扫描者在猜用户名。更明显的是PAM service(sshd) ignoring max retries这种消息说明已经因为重试次数过多被 PAM 限流了。怎么快速统计攻击来源我用的是这条命令# 统计每个IP尝试登录失败的次数secure日志 grep Failed password /var/log/secure | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -20但注意一点日志格式会随发行版变化安全做法是先tail -20 /var/log/secure看一下行格式再写 awk否则容易取错列。成功登录日志同样重要。last -20会显示最近的登录用户、来源IP和登录时长。last -f /var/log/wtmp可以翻历史。如果发现某个账号在凌晨3点从非办公IP登录这通常就是需要重点排查的异常。此时配合lastb查看失败登录记录如果同一个IP也出现在成功登录列表里基本可以判定被攻破了。3.2 用户操作审计与 auditd 的强大威力很多人觉得认证日志够用了但认证日志只记录谁登录了不记录登录后干了什么。要想审计用户的具体操作得用 Linux 的审计子系统 auditd。auditd 可以监控文件访问、系统调用、用户行为并写入/var/log/audit/audit.log。配置规则用auditctl或者写/etc/audit/rules.d/audit.rules。例如监控/etc/passwd被修改auditctl -w /etc/passwd -p wa -k passwd-change # -w 监控文件, -p wa 监听写和属性变更, -k 给规则起个名字方便搜索想查是谁改的 passwd用ausearch -k passwd-change -ts recent输出结果里能看到操作的 UID、进程 PID、命令名。配合auid可以追溯到登录者因为 auid 是登录时分配且不会随su改变的逻辑 ID这就是审计系统最核心的设计。auditd 还能监控特定目录的递归访问比如网站目录上传了可疑文件auditctl -w /var/www/html/ -p x -k web-upload这会记录访问这个目录并在其中执行文件的进程。做安全审计时非常有用。3.3 定时任务与提权行为的日志痕迹攻击者经常通过定时任务做持久化所以 cron 日志也是安全审计的重点。/var/log/cron会记录每次 cron 任务的执行用户和命令。定期检查新增的 crontab 任务非常重要。比如某天机器被入侵攻击者创建了一个反向 shell 的定时任务日志里就会出现CMD (/bin/bash -i /dev/tcp/...)这样的记录。这种可以直接实锤。提权行为主要体现在 sudo 日志。CentOS 7 之后 sudo 日志默认发给 journald可以通过journalctl -u sudo查看有些系统也写在/var/log/sudo或/var/log/auth.log里。用grep sudo /var/log/auth.log或者journalctl -t sudo就能看到某用户执行了哪些命令。3.4 让日志自动“开口”集中收集与异常感知单靠一台机器查日志效率低且容易被攻击者清除。建议生产环境做日志集中转发。最简单的方案是 rsyslog 远程转发把每台主机的/var/log/messages、/var/log/secure等发送到一台日志服务器。服务端在/etc/rsyslog.conf里打开模块并允许接收module(loadimudp) input(typeimudp port514) # 如果走tcp module(loadimtcp) input(typeimtcp port514)客户端则在/etc/rsyslog.d/remote.conf里写*.* 192.168.1.100:514 # 或者采用tcp: 192.168.1.100:514重启 rsyslog 后在服务端tail -f /var/log/messages就能看到远端主机的日志。这样即使本地日志被删远端也有一份。有条件可以直接上 ELK、Loki 这样的日志平台但小环境用 rsyslog grep 也够。4. 渗透复盘视角从防守方视角还原攻击路径4.1 渗透测试之后日志复盘到底看什么先说明一下这里说的“渗透复盘”是防守方蓝队视角的事后分析或者是在获得授权的前提下对一次渗透测试过程做复盘。目的不是教你怎么攻击而是让你知道当系统被攻破以后日志会留下哪些痕迹以及怎么顺着痕迹还原攻击者的动作。攻击链条拆开来看一般有这么几个环节信息探测、漏洞利用、获得权限、权限提升、安装后门、横向移动、痕迹清理。每个环节都会在日志里留下或多或少的影子。复盘的核心就是把日志按时间线串起来问几个问题对方是怎么进来的进来之后干了什么有没有拿到最高权限是否已经横向移动这决定了你接下来的应急响应措施。4.2 Web访问日志里的攻击特征大多数服务器的入口是 Web 服务所以 Web 日志是复盘的第一站。Apache 的/var/log/httpd/access_log和 Nginx 的/var/log/nginx/access.log记录了每个请求的源IP、时间、请求方法、路径、UA、状态码。攻击前的探测行为在日志里非常显眼短时间内大量 404、大量GET /?id1、GET /etc/passwd、GET /admin这类路径扫描。比如# 查看访问量最高的IP awk {print $1} /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10 # 查看某个IP具体请求了哪些路径 grep 192.168.10.66 /var/log/nginx/access.log | awk {print $6,$7} | head -50如果日志里出现POST /upload/xxx.php后面跟着 200同时响应时间异常很可能已经上传了 WebShell。再配合error_log里的POST content length和 PHP 错误信息能判断解析是否成功。访问日志还有一个重要意义记录攻击参数。比如 SQL 注入会留下%27、union select这类特征扫描器UA比如sqlmap、Nmap Scripting Engine也会暴露。所以复盘时用grep -i -E sqlmap|nmap|nikto|curl过滤一波会有惊喜。4.3 主机层面的入侵痕迹还原拿到 Web 权限后攻击者通常会尝试获取一个 shell随后进行提权。这一阶段SSH 认证日志、history 历史命令、新增用户、进程历史都是关键证据。查看当前所有登录用户和进程用w和ps -ef然后去看异常主机的 shell 历史。但要注意history只会缓存当前用户的攻击者如果换了一个用户比如创建的 postgres 用户那就要去/home/postgres/.bash_history里看。下面几个地方是必须检查的/etc/passwd和/etc/shadow是否出现新用户尤其是 UID 0 的用户/root/.bash_history和/home/*/.bash_history是否存在 wget、curl、chmod、useradd 等敏感命令/etc/rc.local或者 systemd 服务目录/etc/systemd/system/是否存在新增的可疑服务SSH authorized_keys 文件是否被写入攻击者的公钥这是最常见的后门方式/etc/crontab和/var/spool/cron/下是否有异常任务在日志复盘里这些痕迹不一定直接有“日志文件”但用户登录记录和 audit 日志可以佐证。比如 audit 日志记录了useradd的调用时间/var/log/secure里记录了攻击者试图用su切换到 root 或者 sudo 成功的记录这些时间点能和.bash_history里的命令对上攻击路径就完整了。4.4 如果日志被清理了怎么办防删改的底线思路经验丰富的攻击者都会尝试清理日志删 secure、messages、清空 history。但很多情况下清理并不干净core dump 文件、进程残留、临时目录文件、应用日志都可能留下线索。最重要的是如果之前配置了日志远程转发攻击者只能清本地清不了远端。为了加大复盘的胜算建议提前做几件事开启 journald 持久化并定期备份/var/log/journal目录配置 rsyslog 远程日志转发把认证和系统日志实时送走对关键日志文件设置不可删除属性chattr a /var/log/messages但注意这个属性会让日志轮转出问题要提前测试好轮转前用chattr -a解除有条件上文件完整性监控比如 AIDE一旦日志被改动会触发告警如果日志确实被删了也别慌。检查last -f备份、shell 历史、临时目录、内存中残留的进程信息用ps auxww、以及入侵后连带产生的业务日志中间件、数据库日志。这些往往会留下蛛丝马迹。5. 常见问题与排查技巧实录5.1 日志不输出、时间不对、轮转异常日志排查中最常见的坑第一个是日志文件没有内容。导致这个问题的原因很多最常见的是 rsyslog 服务没起来或重启之后没有重新读取规则。用systemctl status rsyslog看一下再logger test手动写一条日志观察文件是否有变化这个办法很直接。第二个坑是日志时间不对。虚拟机、云主机重启后时间漂移很常见而日志分析最讲究时间线。解决办法是配置 NTP 服务或 chrony 同步时间同时保证/var/log下文件的时间戳准确。分析跨多台服务器日志时建议统一使用 UTC 或同一时区避免因为时区不同把时间线搞乱。第三个坑是日志轮转异常。日志文件越写越大最后把磁盘塞满。默认的 logrotate 配置一般每周轮转一次但有些应用自己写日志不走 syslog也不会自动轮转比如 Nginx 的 access.log。这时需要自己写一个 logrotate 配置例如# /etc/logrotate.d/nginx /var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 640 nginx adm sharedscripts postrotate if [ -f /var/run/nginx.pid ]; then kill -USR1 $(cat /var/run/nginx.pid) fi endscript }注意postrotate里要优雅通知程序重新打开日志句柄否则程序会一直往已删除的文件写数据。5.2 journald 日志查看和导出journald 日志是二进制的有人习惯用 cat 看结果满屏乱码。用journalctl就对了。有时需要把 journald 日志导成文本给同事或交给安全团队用以下方式journalctl -u sshd.service --since 2025-01-01 --until 2025-01-02 sshd_log.txt如果 journald 日志由于磁盘限制被丢弃可以查看systemd-journald的启动日志确认或者检查/var/log/journal目录的剩余空间。生产环境建议给/var/log单独分区并且配额打足否则日志写满根分区的后果比丢日志更严重。5.3 常用日志分析命令速查表最后把压箱底的一些命令整理成表格都是日常高频使用的顺手保存一份排查的时候不用翻书。目标命令实时监控系统消息tail -f /var/log/messages查看内核和硬件日志dmesg -T | tail -50查询某服务最近的日志journalctl -u nginx.service -n 100查看登录成功记录last -20查看登录失败记录lastb -20统计暴力破解来源IPgrep Failed password /var/log/secure | awk {print $(NF-3)} | sort | uniq -c | sort -nr查看某时间段的sudo操作journalctl --since today -t sudo跟踪Web访问日志中的扫描awk {print $1} /var/log/nginx/access.log | sort | uniq -c | sort -nr | head检查用户登录历史lastlog查找文件变更审计记录ausearch -m FILE_WATCH -ts recent验证时间同步timedatectl status测试syslog转发logger test log from client我个人的习惯是每接手一台新服务器第一件事就是检查/var/log下有哪些关键日志、rsyslog 和 journald 是否正常运行、时间是否同步、日志轮转是否配置好。这些平时看起来不紧迫的事真到出问题的时候能帮你节省几个小时甚至一整晚的排查时间。日志系统就像家里的水电管道平时感觉不到它的存在一旦坏了你才发现它有多重要。希望这篇内容能让你把 Linux 日志这几个关键环节理顺下次遇到故障或安全事件能第一时间从日志里找到答案。
返回列表