日志排查

操作系统运行过程中,各种程序、服务以及用户登录尝试都会产生海量的运行数据。为了便于日后排错或追溯攻击行为,系统会把这些信息持续记录进日志文件中。

常见系统日志路径

Linux 的日志默认集中存放于 /var/log 目录及其子目录下。常见的核心日志文件有:

  • /var/log/syslog:最基础的全局系统日志。记录了大部分系统级事件、服务启动和报错信息。
  • /var/log/kern.log:记录来自 Linux 内核的硬件驱动异常、系统崩溃和内存分配警告。
  • /var/log/auth.log:身份认证与安全审计日志,通常会记录用户登录尝试(包括成功与失败的 SSH 访问)以及利用 sudo 提升权限执行命令的事件;具体内容取决于发行版和日志配置。
  • /var/log/nginx//var/log/apache2/:应用程序级日志。其中按配置启用的 access.log 通常记录网站收到的 HTTP 请求细节(如 IP、时间、请求路径、状态码等),error.log 则记录服务器运行时的错误信息。

注意

为了防止长期运行的服务产生海量日志撑爆磁盘,系统常通过 logrotate 执行日志轮转。例如,当 access.log 达到设定的大小或时间后,旧日志会按配置改名、压缩归档,并创建新的 access.log 文件。

解析典型日志行的结构

我们在分析系统日志时,需要能够拆解每一行日志所代表的含义。以下是一行典型的 SSH 认证失败日志行:

Feb 28 15:04:22 opsbox sshd[3010]: Failed password for crow from 10.14.15.2 port 50223 ssh2

我们将其分为五个部分拆解:

  1. 时间戳Feb 28 15:04:22):该事件发生的确切日期与时间。
  2. 主机名opsbox):产生该日志事件的系统主机名。
  3. 服务名称sshd):生成此日志记录的具体应用程序或守护进程名称。
  4. PID[3010]):处理该会话或请求的进程 PID。
  5. 事件详情Failed password for...):该事件的具体细节描述。此处记录了用户认证尝试失败的信息以及请求源 IP。

在分析 Web 访问日志时也是如此。例如,以下是一行典型的 Apache 访问日志记录:

127.0.0.1 - - [28/Feb/2023:15:06:43 +0000] "GET /index.html HTTP/1.1" 200 13484

其中,127.0.0.1 是请求的客户端 IP,最后的 200 代表请求成功返回的状态码,13484 代表返回的数据字节数。

现代 systemd 服务日志查询:journalctl

现代 Linux 系统除了使用 /var/log 目录下的文本日志外,许多由 systemd 管理的服务还会把日志写入二进制的 systemd journal;具体取决于服务与日志系统的配置。

如果某个服务意外崩溃,而你在文本日志中找不到原因,应该使用 journalctl 命令行工具来查询。

  • 查看特定服务的全部日志:加上 -u 参数指定服务单元名称。
    crow@opsbox:~$ journalctl -u ssh.service
    
  • 非分页直接输出:默认情况下 journalctl 会使用分页器打开以供滚动翻看。如果你想将其直接作为标准输出打印以便配合 grep 等命令检索,需要添加 --no-pager 参数:
    crow@opsbox:~$ journalctl -u ssh.service --no-pager
    

正常访问状态码

练习

当客户端成功请求网页,且 Web 服务器端正常处理并成功返回内容时,系统在日志(如 access.log)中记录的代表正常成功的 HTTP 状态码是多少?请提交对应的 3 位阿拉伯数字。

提交答案

题解 Hint

练习四:从海量 Web 日志中检索线索

在此实操练习中,我们需要在一份包含大量失败噪声的 Web 服务器请求日志中,过滤筛选出唯一一条成功获取敏感密钥的请求记录。

  1. 我们的目标日志文件位于 /var/log/opsbox/access.log。我们首先读取该日志文件:
    crow@opsbox:~$ cat /var/log/opsbox/access.log
    127.0.0.1 - - [16/Jul/2026:01:00:00 +0000] "GET /index.html HTTP/1.1" 404 125
    127.0.0.1 - - [16/Jul/2026:01:00:02 +0000] "GET /favicon.ico HTTP/1.1" 404 125
    # ... (此处略去数百条 404 错误日志)
    
    你会发现终端屏幕被数百条状态码为 404(请求资源不存在)的访问请求瞬间刷屏。由于日志数量巨大,单靠肉眼极难定位。
  2. 结合之前学到的过滤知识,在标准的 Web 访问日志中,代表正常响应成功的状态码是 200。我们可以使用 grep 工具在日志文件中进行精确过滤,前后加上空格以防匹配到其他部位的数字:
    crow@opsbox:~$ grep ' 200 ' /var/log/opsbox/access.log
    10.0.3.9 - - [11/Jul/2026:03:17:00 +0000] "GET /internal/report?key=COIN{……} HTTP/1.1" 200 512
    
  3. 管道和过滤工具成功截获了唯一的一行符合条件的正常访问日志。
  4. 提取其中包含的 Token 令牌值并进行提交以完成本次挑战。

从访问日志里捞出那一行

Lab

opsbox 的访问日志 /var/log/opsbox/access.log 有几百行,几乎全是失败请求(404),只有一次成功请求(状态码 200)带着一个 key。

在网页终端(TARGET 终端(启动 Lab 后显示))里用 grep 配合管道把那一行捞出来,提交请求里的 key。

提交格式:COIN{........}

加载会话状态…

提交 coin

题解 Hint