Linux日志分析详解(附带实例)
Linux日志会记录许多有价值的信息,其中除了常规的系统登录事件外,还包括 Web 日志、定时任务、Samba 日志、内核日志、启动日志以及各用户的命令执行记录,这些信息可以为我们了解系统运行状态、在安全事件发生后进行分析提供很大的帮助。
在 Linux 系统中,绝大多数日志默认存储在“/var/log”目录下。同时,我们可以注意到,由于配置了日志转储机制,我们可以在该目录下看到不少同名但有不同扩展名的日志。
/var/log/ 目录下的日志非常丰富,不同的日志有不同的内容。这里先简单介绍其中的一些常见日志及它们的内容,如下表所示,便于读者理解。
从上表可以看出,Linux 日志非常丰富。在实际分析时,我们可以依据日志的类型对这些日志先进行分类,再进行分析。
对 Linux 日志进行严格区分是比较困难的,这里我们依据日志内容的特点和归属,简单将 Linux 日志分为以下几类,便于后面对其进行讨论。
1) rsyslog日志。这类日志由 Linux 下的 rsyslogd 服务统一管理。虽然不同的 Linux 发行版中 /var/log 下的日志类型及内容存在差异,但大致上,/var/log 目录下的 messages、auth、cron、debug、kern、maillog 等日志均由 rsyslogd 服务管理,并且这些日志采用一种相对固定的日志格式。
2) utmp 日志。这类日志以一种特殊结构记录系统中当前登录用户的相关信息,具体日志包括 /var/log 目录下的 wtmp、btmp、lastlog 以及 /var/run/ 下的 utmp。
3) 其他日志。诸如启动日志、Web 日志、包管理器运行维护日志、系统首次安装时生成的安装日志、数据库日志等。这些日志的内容与格式取决于自身定义,没有完全固定的内容与格式。
4) 命令执行历史记录日志。这类日志一般存储于用户家目录下,比较典型的有 .bash_history、.zsh_history、.python_history、.rediscli_history、.lesshst、 .sqlite_history 等。这些日志以文件形式存储时普遍会在文件名前面加“.”进行隐藏,正常使用过程中用户不会对这些日志有所感知。
接下来我们选取一些典型的日志进行分析。

图 1 多次针对不同用户名的登录尝试
rsyslog 是一个被 rsyslogd 服务统一管理的典型日志,从格式上说,每个日志均可分为 4 部分:日志记录时间、主机名、服务的守护进程和服务的日志内容。
如图 1 所示,该 messages 日志记录了 sshd 服务建立的会话信息,实际上我们可以据此判断系统在某段时间是否遭受 SSH 爆破,以及是否有用户登录成功。
这里需要说明的是,不同 Linux 发行版记录 sshd 服务历史的位置是有差异的,日志记录时间的格式也可能存在差别。在利用 Linux 上的字符串过滤工具进行处理时,我们需要额外关注不同 Linux 发行版上记录 sshd 服务历史的日志关键词字段的格式。
utmp 日志不是一个文本文件,而是一个二进制文件,需要由专门的编辑程序进行编辑。该日志中的实现和字段因系统或 libc 版本而异,并且这些内容会在 utmp.h 头文件中定义。
此外,utmpdump 命令可以将以上日志的信息转化为可读类型后供分析人员查看,使用该命令的前提是他们对 utmp 日志的结构非常熟悉。
下表所示为一些常见的命令及其对应的命令执行历史记录日志:
需要注意的是,这些命令执行的历史记录日志可能包含用户的敏感信息,例如通过命令行输入的密码、SQL 语句中的敏感数据等,故应妥善保护这些日志的访问权限,以防其他用户或者恶意程序获取其中的信息。
在实际场景下,不仅排查人员会关注这些日志,攻击者也常通过日志收集服务器的敏感信息。
下表列出了一些常用的命令。限于篇幅,相关命令的用法不再展开讨论,读者可以自行搜索并学习。
基于以上命令配合 Linux 下灵活的管道符(“|”)、重定向符(“>”“<”)、模糊匹配符(“*”“?”)可以快速匹配到我们需要的日志并提取出我们需要的数据。
接下来我们将使用以上命令结合一些实际场景向读者展示如何对日志进行快速 分析。
【示例 1】内容预览。
我们可以使用 head 命令查看日志的前 n 行内容,例如查看日志的前 10 行内容:
【示例 2】可疑IP地址排查。
确认某可疑 IP 地址是否成功登录过本设备,使用的方式是什么。
这里使用以下命令对某台 CentOS 6.4 设备下的 /var/log/messages 进行分析:

图 2 排查与可疑 IP 地址相关的日志
【示例 3】账户失陷排查。
使用以下命令统计通过 SSH 成功登录 root 的所有 IP 地址并进行降序排序,如下图所示:

图 3 统计登录成功的IP地址并排序
【示例 4】爆破排查。
1) 如下图所示,统计尝试对本服务器的 SSH 服务进行爆破的次数最多的 10 个 IP 地址:

图 4 统计尝试爆破的次数最多的10个IP地址
2) 定位 IP 地址在爆破主机的 root 账号数量:
3) 攻击者尝试使用了哪些用户名登录系统:
尝试的用户名属于系统内已存在的用户:
尝试的用户名属于系统内不存在的用户:
当然,部分读者可能面临一些比较特殊的情况,比如相关日志因保留现场的需要无法在现场进行分析、有线索表明系统中可能存在rootkit病毒等。这时我们可以依据实际情况使用如下多种思路推进分析:
在 Linux 系统中,绝大多数日志默认存储在“/var/log”目录下。同时,我们可以注意到,由于配置了日志转储机制,我们可以在该目录下看到不少同名但有不同扩展名的日志。
/var/log/ 目录下的日志非常丰富,不同的日志有不同的内容。这里先简单介绍其中的一些常见日志及它们的内容,如下表所示,便于读者理解。
日志 | 内容说明 |
---|---|
/var/log/cron | 记录与系统定时任务相关的信息 |
/var/log/cups | 记录输出信息 |
/var/log/dmesg | 记录系统在开机时产生的内核自检信息,也可以使用 dmesg 命令直接查看内核自检信息 |
/var/log/maillog | 记录邮件信息 |
/var/log/messages | 记录系统重要信息。这个日志中会记录 Linux 系统的绝大多数重要信息,如果系统出现问题,首先要检查的就应该是这个日志 |
/var/log/btmp | 记录错误登录信息,这个日志是二进制文件,不能直接使用 vi 命令查看,而要使用 lastb 命令查看 |
/var/log/lastlog | 记录系统中所有用户的最后一次登录时间信息,这个日志是二进制文件,不能直接使用 vi 命令查看,而要使用 lastlog 命令查看 |
/var/log/wtmp | 永久记录所有用户的登录、注销信息,同时记录系统的启动、重启、关机时间信息。同样,这个日志也是二进制文件,不能直接使用 vi 命令查看,而要使用 last 命令查看 |
/var/log/utmp | 只记录当前登录用户的信息,这个日志记录的信息会随着用户的登录和注销不断变化。同样这个文件不能直接使用 vi 命令查看,而要使用 w、who、users 等命令查看 |
/var/log/secure | 记录验证和授权方面的信息,涉及账号和密码的程序的相关信息都会被记录,比如 SSH 登录、su 切换用户、sudo 授权等,甚至添加用户和修改用户密码的相关信息都会被记录在这个日志中 |
从上表可以看出,Linux 日志非常丰富。在实际分析时,我们可以依据日志的类型对这些日志先进行分类,再进行分析。
对 Linux 日志进行严格区分是比较困难的,这里我们依据日志内容的特点和归属,简单将 Linux 日志分为以下几类,便于后面对其进行讨论。
1) rsyslog日志。这类日志由 Linux 下的 rsyslogd 服务统一管理。虽然不同的 Linux 发行版中 /var/log 下的日志类型及内容存在差异,但大致上,/var/log 目录下的 messages、auth、cron、debug、kern、maillog 等日志均由 rsyslogd 服务管理,并且这些日志采用一种相对固定的日志格式。
2) utmp 日志。这类日志以一种特殊结构记录系统中当前登录用户的相关信息,具体日志包括 /var/log 目录下的 wtmp、btmp、lastlog 以及 /var/run/ 下的 utmp。
3) 其他日志。诸如启动日志、Web 日志、包管理器运行维护日志、系统首次安装时生成的安装日志、数据库日志等。这些日志的内容与格式取决于自身定义,没有完全固定的内容与格式。
4) 命令执行历史记录日志。这类日志一般存储于用户家目录下,比较典型的有 .bash_history、.zsh_history、.python_history、.rediscli_history、.lesshst、 .sqlite_history 等。这些日志以文件形式存储时普遍会在文件名前面加“.”进行隐藏,正常使用过程中用户不会对这些日志有所感知。
接下来我们选取一些典型的日志进行分析。
Linux rsyslog日志分析
下图所示为某 CentOS 7.6 服务器上 /var/log/messages 日志的一部分内容:
图 1 多次针对不同用户名的登录尝试
rsyslog 是一个被 rsyslogd 服务统一管理的典型日志,从格式上说,每个日志均可分为 4 部分:日志记录时间、主机名、服务的守护进程和服务的日志内容。
如图 1 所示,该 messages 日志记录了 sshd 服务建立的会话信息,实际上我们可以据此判断系统在某段时间是否遭受 SSH 爆破,以及是否有用户登录成功。
这里需要说明的是,不同 Linux 发行版记录 sshd 服务历史的位置是有差异的,日志记录时间的格式也可能存在差别。在利用 Linux 上的字符串过滤工具进行处理时,我们需要额外关注不同 Linux 发行版上记录 sshd 服务历史的日志关键词字段的格式。
Linux utmp日志分析
前文提到,utmp 日志涉及 /var/log 目录下的 btmp、wtmp、lastlog 以及 /var/run/ 下的 utmp 日志,这些日志都是二进制文件,无法直接进行查看、分析,但可以基于系统命令进行解析,具体如下:- /var/run/utmp 将系统的当前状态、系统启动时间、登录的用户及终端会话、用户注销事件等进行了全面的记录。使用常见的 w、who 命令可在执行时解析该日志内容。
- wtmp 可以视为系统历史上 utmp 内容的集合。使用 last 命令默认解析本日志。
- btmp 专门记录用户登录失败的事件。使用 Linux 系统上的 lastb 命令可对此日志进行解析。
- lastlog 记录某个用户的最近一次登录信息。使用 Linux 系统上的 lastlog 命令可对此日志进行解析。
utmp 日志不是一个文本文件,而是一个二进制文件,需要由专门的编辑程序进行编辑。该日志中的实现和字段因系统或 libc 版本而异,并且这些内容会在 utmp.h 头文件中定义。
此外,utmpdump 命令可以将以上日志的信息转化为可读类型后供分析人员查看,使用该命令的前提是他们对 utmp 日志的结构非常熟悉。
Linux命令执行历史记录日志分析
命令执行历史记录日志,顾名思义,记录的是命令执行的历史。在未经额外配置的条件下,过去执行的命令均放置于当前用户的家目录下且可以被当前用户读取和写入。下表所示为一些常见的命令及其对应的命令执行历史记录日志:
命令 | 命令执行历史记录日志 | 说明 |
---|---|---|
bash | $HOME/.bash_history | Bash Shell 下的命令执行历史记录 |
zsh | $HOME/.zsh_history | zsh Shell 下的命令执行历史记录 |
sh | $HOME/.sh_history | sh Shell 下的命令执行历史记录 |
python2/python3 | $HOME/.python_history | Python 交互模式下输入的命令 |
redis-cli | $HOME/.rediscli_history | Redis 交互模式下输入的命令 |
mysql | $HOME/.mysql_history | MySQL 交互模式下输入的命令 |
sqlite/sqlite3 | $HOME/.sqlite_history | SQLite 交互模式下输入的命令 |
wget | $HOME/.wget-hsts | 用于记录先前通过 wget 命令下载的 HTTPS 网站的安全令牌(Security Token)。可以通过本日志知道是否访问过某 HTTPS 网站 |
ssh | $HOME/.ssh/known_hosts | 用于记录先前连接的远程主机的主机密钥(Host Key)信息。如果未经安全配置,其中将含有被连接主机的主机名及 IP 地址 |
less | $HOME/.lesshst | 使用 less 命令交互式查看某文件内容时的历史记录 |
需要注意的是,这些命令执行的历史记录日志可能包含用户的敏感信息,例如通过命令行输入的密码、SQL 语句中的敏感数据等,故应妥善保护这些日志的访问权限,以防其他用户或者恶意程序获取其中的信息。
在实际场景下,不仅排查人员会关注这些日志,攻击者也常通过日志收集服务器的敏感信息。
Linux日志分析技巧
Linux 具有丰富的文本编辑及筛选命令,实际场景下,排查人员时常利用系统自带的命令对日志进行分析。下表列出了一些常用的命令。限于篇幅,相关命令的用法不再展开讨论,读者可以自行搜索并学习。
用途 | 命令 |
---|---|
查看日志 | cat、less、more、head、tail、nano、vim |
内容筛选 |
• grep、zgrep、egrep 等 *grep 族命令 • awk(条件筛选及按列筛选) • sed(条件筛选及按行筛选) |
日志编辑 | sed |
数据编码 | base64、gunzip |
数据排序 | sort |
数据去重 | uniq |
日志查找 | find |
参数切分 | xargs |
基于以上命令配合 Linux 下灵活的管道符(“|”)、重定向符(“>”“<”)、模糊匹配符(“*”“?”)可以快速匹配到我们需要的日志并提取出我们需要的数据。
接下来我们将使用以上命令结合一些实际场景向读者展示如何对日志进行快速 分析。
【示例 1】内容预览。
我们可以使用 head 命令查看日志的前 n 行内容,例如查看日志的前 10 行内容:
head -n 10 filename还可以使用 tail 命令查看日志的后 n 行内容,例如查看日志的后 10 行内容:
tail -n 10 filename
【示例 2】可疑IP地址排查。
确认某可疑 IP 地址是否成功登录过本设备,使用的方式是什么。
这里使用以下命令对某台 CentOS 6.4 设备下的 /var/log/messages 进行分析:
grep -rn "Accepted" messages|grep "117.61.31.25"发现 2 月 17 日某可疑 IP 地址成功通过交互式输入口令的方式登录了本设备,如下图所示:

图 2 排查与可疑 IP 地址相关的日志
【示例 3】账户失陷排查。
使用以下命令统计通过 SSH 成功登录 root 的所有 IP 地址并进行降序排序,如下图所示:

图 3 统计登录成功的IP地址并排序
【示例 4】爆破排查。
1) 如下图所示,统计尝试对本服务器的 SSH 服务进行爆破的次数最多的 10 个 IP 地址:
grep "Failed password" /var/log/messages* | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -n 10

图 4 统计尝试爆破的次数最多的10个IP地址
2) 定位 IP 地址在爆破主机的 root 账号数量:
grep "Failed password " /var/log/messages* |grep "root"| awk '{print $11}' | sort | uniq -c | sort -nr |wc -l
3) 攻击者尝试使用了哪些用户名登录系统:
尝试的用户名属于系统内已存在的用户:
grep -rn "ssh"|grep "password for"|grep -v "invalid user"|awk '{print $9}'|sort|uniq
尝试的用户名属于系统内不存在的用户:
grep -rn "ssh"|grep "password for"|grep "invalid user"|awk '{print $11}'|sort|uniq
当然,部分读者可能面临一些比较特殊的情况,比如相关日志因保留现场的需要无法在现场进行分析、有线索表明系统中可能存在rootkit病毒等。这时我们可以依据实际情况使用如下多种思路推进分析:
- 在 Linux 环境上使用 BusyBox 提供的命令对日志进行分析;
- 在 Windows 系统下安装 Git 工具或 MinGW,利用提供的 Linux 环境下的相关工具对日志进行分析和处理;
- 将相关日志导入 Splunk、ELK(Elasticsearch、Logstash、Kibana)进行筛选、分析。