Linux 远程日志收集:rsyslog 从原理到实战

发布时间:2026/7/31 3:26:07
Linux 远程日志收集:rsyslog 从原理到实战 一、rsyslog 是什么它解决了什么问题1. 核心作用rsyslog Rocket-fast System for Log Processing是一个高性能的日志处理守护进程。它的职责是按照规则采集系统中产生的日志并根据配置把日志写到指定的位置文件、远程服务器、数据库等通俗地说操作系统内核、各种服务SSH、HTTP、邮件、定时任务都在不停地输出日志。rsyslog 像一个日志快递分拣中心——它接收所有日志然后根据你制定的规则把不同种类的日志投递到不同的目标。2. 为什么需要远程日志场景问题远程日志解决服务器宕机日志存在本地机器挂了日志也读不了日志实时发到远程服务器挂了也能查入侵溯源攻击者登录后会清理本地日志远程日志无法被攻击者篡改多机审计几十台机器一台台查太慢一台日志服务器集中查看所有日志合规要求等保/SOX 要求日志集中归档统一存储、统一备份二、Linux 系统日志分类详解在 Linux 中日志并不是杂乱无章地堆在一起。rsyslog 默认按照程序功能把日志写入不同的文件。日志文件存放内容典型场景/var/log/messages通用系统消息和服务启动/报错信息应用程序崩溃、网络服务异常/var/log/secure认证相关的安全日志SSH 登录成功/失败、sudo 操作/var/log/maillog邮件服务器日志sendmail/postfix 收发记录/var/log/cron定时任务执行日志crontab 执行结果、报错/var/log/boot.log系统启动过程的日志内核加载、服务自启状态记忆技巧文件名就暗示了用途——secure管安全、maillog管邮件、cron管定时任务一眼就能看出是干什么的。三、rsyslog 日志采集规则类型 × 级别rsyslog 的规则核心只有两件事什么类型什么级别。1. 日志类型Facility—— 谁产生的日志类型含义说明auth用户认证用户登录/登出验证authpriv服务认证SSH、sudo 等服务的认证信息cron定时任务crond 相关的日志kern内核日志内核输出的信息优先级高mail邮件系统邮件服务产生的日志news新闻组/更新信息一般较少用到user用户级别日志普通用户程序产生的日志2. 日志级别Severity—— 日志有多严重级别从低到高排列级别含义严重程度debug调试信息 最低info普通信息notice重要信息warning警告err错误crit严重错误alert必须立即处理 紧急emerg系统濒临崩溃 最高none不采集—原理一句话级别是向下包含的。如果你指定了err那么errcritalertemerg都会被记录下来。级别越低包含的范围越大。3. 规则语法类型.级别*.* → 所有类型的所有级别最全的日志 authpriv.err → authpriv 类型的 err 及以上级别 *.*;auth.none → 所有类型所有级别但排除 auth 类型 kern.debug → 内核的 debug 及以上级别语法结构类型.级别 动作逗号;分隔多条规则.前面是类型、后面是级别。none特殊级别表示不采集这个类型。四、本地日志规则配置4.1 采集所有日志到一个自定义文件操作命令vim/etc/rsyslog.conf在文件末尾追加一行*.* action(typeomfile file/var/log/qwe)然后重启服务systemctl restart rsyslog逐行解释配置/命令解释*.*第一个* 所有日志类型第二个* 所有日志级别。含义不管什么类型的日志、不管多严重的级别全部采集action(typeomfile file/var/log/qwe)action是 rsyslog 的动作声明typeomfile表示输出模块是写文件output module filefile/var/log/qwe指定输出的目标文件路径。注意没有写绝对路径的开头/实际应写/var/log/qwe这里原笔记略有省略但 rsyslog 默认相对路径基于/systemctl restart rsyslog重启 rsyslog 服务使配置生效。每次修改rsyslog.conf必须重启测试验证cat/var/log/qwe你会看到系统中所有类型的日志都被写入了这个文件——包括内核、服务、认证等。这说明规则生效了。4.2 排除某个类型的日志场景我们希望采集除了服务认证authpriv之外的所有日志。因为secure文件已经记录了认证信息重复采集浪费空间。配置*.*;authpriv.none action(typeomfile file/var/log/qwe)原理这条规则拆开理解*.*— 所有类型所有级别authpriv.none— 但类型为 authpriv 的日志不采集none是排除指令分号;表示同时满足——先包含全部再排除指定类型效果除了 SSH 登录、sudo 等认证日志之外其他所有日志都写入/var/log/qwe。测试方法# 在另一台机器上尝试 SSH 登录ssh-lroot192.168.17.138# 查看 qwe 文件应该没有 SSH 相关的日志cat/var/log/qwe同时可以对比/var/log/secure的内容——认证日志只出现在了secure中说明我们的排除规则生效了。⚠️注意排除规则必须写在包含规则前面以;连接。rsyslog 按顺序匹配规则先遇到谁就执行谁。4.3 清空日志文件/var/log/qwe这个命令用重定向符清空文件内容相当于: /var/log/qwe或truncate -s 0 /var/log/qwe。测试前清空文件方便对比观察新的日志是否被正确写入。五、自定义日志格式5.1 为什么需要自定义格式默认的日志格式包含的信息比较有限。在生产环境中我们往往需要知道日志是什么时候产生的不是写入时间而是事件发生时间是哪台机器产生的多机集中管理时尤为重要是哪个程序输出的具体内容是什么5.2 自定义模板配置vim/etc/rsyslog.conf加入以下内容$template LEE, %timegenerated% %FROMHOST-IP% %syslogtag%: %msg%\n *.*;authpriv.none action(typeomfile templateLEE file/var/log/lee)模板参数详解参数含义示例值%timegenerated%日志生成的时间戳Jul 30 10:52:44%FROMHOST-IP%产生日志的主机 IP 地址192.168.17.131%syslogtag%产生日志的程序名称sshd,crond,root%msg%实际的日志内容session opened for user root\n换行符每条日志占一行—整条配置的含义第一行$template LEE, ...— 定义一个名为LEE的日志格式模板第二行*.*;authpriv.none action(... templateLEE ...)— 在写入动作中引用这个模板最终写入文件的日志格式就是时间 IP 程序名: 内容重启服务systemctl restart rsyslog.service5.3 测试自定义格式# 清空之前的日志/var/log/qwe# 使用 logger 命令手动生成一条日志loggertest# 查看自定义格式的日志文件cat/var/log/leelogger是 Linux 内置的向 syslog 发送日志的命令行工具。运行logger test会生成一条内容为test的日志经由 rsyslog 处理后写入/var/log/lee。输出示例Jul 30 23:39:22 192.168.17.131 root: test对比如果不用自定义模板默认格式可能缺少 IP 和时间信息。在远程日志场景中%FROMHOST-IP%是最关键的字段——它让你知道日志来自哪台机器。六、远程日志同步这是本文的核心——搭建一台日志服务器让网络中所有 Linux 机器把日志实时发送过来。6.1 架构原理┌──────────────────────┐ UDP 514 ┌──────────────────────┐ │ 发送方Client │ ────────────────────── │ 接收方Server │ │ 192.168.17.131 │ │ 192.168.17.138 │ │ │ syslog 协议 │ │ │ rsyslog 收集本机日志 │ (基于 UDP) │ 按来源 IP 程序名 │ │ 然后转发到远程 │ │ 自动分类存储 │ └──────────────────────┘ └──────────────────────┘通信原理rsyslog 支持通过UDP 514 端口传输日志也支持 TCPUDP 传输速度快、开销小但不保证送达——日志丢失一两行是可以容忍的因为日志是持续产生的接收方通过imudp模块Input Module UDP监听 UDP 514 端口发送方使用符号指定远程目标一个是 UDP两个是 TCP6.2 接收方配置日志服务器接收方就是我们的日志服务器负责接收所有其他机器发来的日志。步骤 1编辑配置文件vim/etc/rsyslog.conf在文件末尾或合适位置加入以下内容# 定义日志存储路径模板按来源 IP 和程序名分目录存放$templateRemoteByIP,/var/log/remote/%FROMHOST-IP%/%PROGRAMNAME%.log# 定义日志格式模板时间 来源IP 程序名 内容$templateRemoteFormat,%timegenerated% %FROMHOST-IP% %syslogtag%: %msg%\n# 非本机产生的日志按 RemoteByIP 模板、RemoteFormat 格式写入:source,!isequal,localhost-?RemoteByIP;RemoteFormat# 非本机日志处理完后不再继续往下匹配丢弃:source,!isequal,localhost~# 加载 UDP 输入模块只需加载一次module(loadimudp)# 在 514 端口启动 UDP 监听input(typeimudpport514)每行解释配置解释$template RemoteByIP, /var/log/remote/%FROMHOST-IP%/%PROGRAMNAME%.log定义了一个名为RemoteByIP的路径模板。日志会按来源IP/程序名.log的结构存放。例如来自192.168.17.131的 SSH 日志存在/var/log/remote/192.168.17.131/sshd.log$template RemoteFormat, %timegenerated% %FROMHOST-IP% %syslogtag%: %msg%\n定义日志内容格式模板包含时间、来源 IP、程序标签、消息内容:source, !isequal, localhost -?RemoteByIP;RemoteFormat条件判断如果日志来源source不等于!isequal本机localhost则按照RemoteByIP路径和RemoteFormat格式写入。-?中的-表示异步写入先写缓冲区再落盘提高性能?后面跟模板名:source, !isequal, localhost ~上一条把非本机日志写入了文件这一条用~波浪号表示丢弃告诉 rsyslog非本机日志处理完了不要再往下匹配了。防止日志被重复处理module(loadimudp)加载imudp输入模块Input Module for UDP。这是 rsyslog 的插件化架构——模块按需加载不用不加载input(typeimudp port514)在 UDP 514 端口上启动监听。514 是 syslog 的标准端口低于 1024 的端口需要 root 权限核心原理$template定义怎么写:source, !isequal定义哪些写module(loadimudp)定义怎么收。三条各司其职。步骤 2重启服务并验证端口systemctl restart rsyslog# 查看 UDP 514 端口是否在监听netstat-antlupe|greprsyslogudp 0 0 0.0.0.0:514 0.0.0.0:* 0 148148 37733/rsyslogd udp6 0 0 :::514 :::* 0 148149 37733/rsyslogd输出字段含义udp协议是 UDP0.0.0.0:514监听所有网卡的 514 端口0.0.0.0:*接受来自任何 IP 的连接37733/rsyslogd进程 PID 和进程名说明确实是 rsyslog 在监听udp6 :::514IPv6 版本的同端口监听6.3 发送方配置被收集的机器操作命令vim/etc/rsyslog.conf在文件末尾添加一行*.* 192.168.17.138重启服务systemctl restart rsyslog逐行解释配置解释*.*所有类型、所有级别的日志。发送方一般把全部日志都发出去接收方来筛选和归类192.168.17.138一个表示使用 UDP 协议发送到目标 IP 的 514 端口默认端口可省略。如果是192.168.17.138则使用 TCP 协议vs UDP速度快无连接可能丢包→ 适合局域网内部日志收集 TCP可靠性高开销大→ 适合跨公网、重要日志传输6.4 测试远程日志同步步骤 1发送方生成测试日志# 在发送方192.168.17.131执行loggertestlogger test会生成一条内容为test的日志logger命令的默认程序标签是当前用户名这里是root。步骤 2接收方查看远程日志# 在接收方192.168.17.138执行cat/var/log/remote/192.168.17.131/root.log结果分析字段值说明时间Jul 30 10:52:44日志在发送方产生的时间%timegenerated%来源 IP192.168.17.131发送方的 IP 地址%FROMHOST-IP%程序名root产生日志的程序这里是logger命令标签为当前用户名内容test实际的日志消息至此远程日志同步搭建成功发送方的任何日志都会实时传输到接收方并按来源IP/程序名.log的目录结构自动归档。