syslog 随笔

概述

Syslog 是一种消息日志记录的标准,用于在网络设备和应用程序之间发送和接收日志消息。它允许将生成消息的软件、存储消息的系统以及报告和分析消息的软件进行分离。每条消息都标有一个设备代码,指示生成该消息的系统类型,并分配一个严重性级别。

简单来说,它是一个用于集中记录和管理系统日志的标准方法。Syslog 消息具有预定义的结构,包括优先级、时间戳、主机名、应用程序名称和消息文本等元素。可以通过UDP 或TCP 协议发送。UDP 通常用于快速、无连接的传输,而TCP 提供更可靠的连接。

syslog 基本概念

Syslog 消息的发起者提供的信息包括设备代码和严重性级别。Syslog 软件会在将条目传递给 Syslog 接收器之前将信息添加到信息头中。这些组件包括发起者进程 ID、 时间戳以及设备的主机名或 IP 地址。

常用端口:

  • UDP:514 端口。

  • TCP:由于 UDP 缺乏拥塞控制机制,因此建议使用 TCP 的 6514 端口。

设施层级 (Facility)

表示日志消息的来源系统组件,用 0-23 的数字或预定义关键字表示:

Facility code Keyword Description
0 kern 内核消息,例如内核错误、驱动问题
1 user 用户级消息,普通应用程序日志
2 mail 邮件系统
3 daemon 守护进程,例如sshd/crond 等后台服务
4 auth 安全/身份验证消息,例如登录、sudo 操作
5 syslog syslog 自身消息,syslog 服务内部日志
6 lpr Line printer subsystem
7 news Network news subsystem
8 uucp UUCP subsystem
9 cron 定时任务,cron 作业日志
10 authpriv Security and authentication messages
11 ftp FTP 守护进程
12 ntp NTP 子系统
13 security Log audit
14 console Log alert
15 solaris-cron Scheduling daemon
16–23 local0 – local7 本地使用的设施,0:预留自定义用途,7:通常用于引导日志 (boot.log)

特点

  • 设施层级用于日志分类过滤(如:auth.* 表示所有认证日志)
  • local0-local7 专供用户自定义应用使用

在不同的操作系统和 syslog 实现中,设施代码和关键字之间的映射并不统一。

严重性级别 (Severity Level)

表示日志的紧急程度,从 0(最高)到 7(最低):

数值 关键字 说明 典型场景
0 emerg 系统不可用 硬件故障、核心服务崩溃
1 alert 需立即处理 磁盘满、关键安全事件
2 crit 严重错误 服务启动失败、配置错误
3 err 普通错误 连接超时、文件访问失败
4 warning 警告 资源使用率高、非关键异常
5 notice 正常但重要事件 服务启动/停止、配置重载
6 info 信息性消息 操作记录、状态变更
7 debug 调试消息 开发/排错详细输出

特点

  • 决定日志的处理优先级(如 alert 级日志可能触发告警)
  • 日志过滤语法:facility.severity(如 mail.err 表示邮件服务的错误及以上级别日志)

优先级 (Priority)

设施 + 严重性 组合计算得出:

1
优先级(PRI) = Facility * 8 + Severity

示例

  • auth.info(设施=4,严重性=6) → 优先级 = 4*8 + 6 = 38
  • 在日志中显示为 <38>(消息头部尖括号内)

特点

  • 优先级是 syslog 消息的第一个字段
  • 接收端通过优先级反向解析出设施和严重性

Syslog 消息格式

RFC 3164 (旧格式)

RFC3164相对来说格式较为简单,消息长度不超过 1024,能适应大部分使用场景,但是已废弃。

在 RFC 3164 中,消息组件(称为 MSG)被指定为具有以下字段: TAG ,它应该是生成消息的程序或进程的名称,以及 CONTENT ,其中包含消息的详细信息。

RFC 5424 (新格式):

RFC5424已作为Syslog的业界规范。RFC 5424 中 MSG 就是 RFC 3164 中所说的 CONTENT。TAG 现在是报头的一部分,但不再是一个单独的字段。TAG 被拆分成了 APP-NAME、PROCID 和 MSGID。这与 TAG 的用法并不完全一样,但在大多数情况下提供了相同的功能。

Rsyslog

Rsyslog 是一款开源软件实用程序,用于在 UNIX 和类 Unix 计算机系统上通过IP网络转发日志消息。它实现了基本的 syslog 协议,并对其进行了扩展,包括基于内容的过滤、丰富的过滤功能、用于处理离线输出的队列操作、支持不同的模块输出、灵活的配置选项,以及使用 TCP 进行传输等功能。

启动 Rsyslog

ubuntu 默认安装了 rsyslog,我们可以直接修改配置文件进行安装,参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vi /etc/rsyslog.conf 

#################
#### MODULES ####
#################

module(load="imudp")
input(type="imudp" port="514")



###########################
#### GLOBAL DIRECTIVES ####
###########################

$template RemoteLogs,"/var/log/%HOSTNAME%/%PROGRAMNAME%.log" *
*.* ?RemoteLogs
& ~

参数说明:

  1. imudp: Input Module for UDP,用于接收通过 UDP 协议发送的日志消息,加载该模块后,Rsyslog 才能通过 UDP 网络协议接收日志。

  2. $template:用来定义模板,模板名称叫做 RemoteLogs,模板的作用是定义日志文件的存储路径格式。其中:

    • %HOSTNAME% 是一个动态变量,表示发送日志的主机名。

    • %PROGRAMNAME% 是另一个动态变量,表示生成日志的程序名称。

    • 日志文件的路径格式为 /var/log/{主机名}/{程序名}.log

  3. *.*:表示匹配所有设施(facility)和所有优先级(priority)的日志。

  4. ?RemoteLogs :表示将匹配到的日志按照 RemoteLogs 模板定义的路径存储。

  5. & ~:这是一个特殊的语法,表示在处理完当前规则后,停止进一步处理该日志消息。可以防止日志消息被重复处理或写入到其他地方。

接着重启 rsyslog

1
systemctl restart rsyslog

验证是否接收到日志

方法一:

找另一台 Ubuntu 主机,配置如下:

1
2
3
vi /etc/rsyslog.conf 

*.* @192.168.2.65:514
1
systemctl restart rsyslog

这个配置会发送所有的的日志到 Server 端。

接着在 Server 端的 /var/log/{主机名}/{程序名}.log 路径查看日志是否接收到。

方法二:

使用 logger 发送日志进行测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## 基于 udp (-d 指定 udp,默认是 udp,也可以不写这个参数)
logger -n 192.168.2.65 -P 514 -d "Test from logger client"

## 基于 tcp
logger -n 192.168.2.65 -P 514 -T "Test from logger client"

# ,发送给自己(使用默认设施 user 和严重性 notice)
logger "Default log"

# 指定设施和严重性
logger -p local0.err "Custom facility error"

# 指定标签(替代默认进程名)
logger -t MY_APP "Starting MY_APP service"

# 发送 RFC 5424 格式消息
logger --rfc5424 -t WEB_APP "This is RFC 5424"

# 发送 RFC 3164 格式消息
logger -n 127.0.0.1 -P 5140 --rfc3164 "This is RFC 3164"

Fluentd 接收 syslog

除了 rsyslog,Fuentd 内置了输入插件 in_syslog, 使 Fluentd 能够通过 UDP 或 TCP 上的 syslog 协议检索日志。

启动 Fluentd

首先新建一个目录,然后在创建一个 fluentd.conf 文件,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
cat fluentd.conf 
<source>
@type syslog
port 5140
bind 0.0.0.0
tag system
</source>

<match system.**>
@type stdout
@id stdout_output
</match>

可以使用 docker 来启动 Fluentd:

1
docker run -itd -p 5140:5140/udp --name fluentd-test -v $(PWD)/fluentd.conf:/fluentd/etc/fluent.conf fluent/fluentd:latest

验证是否接收到日志

输入

1
logger -n 127.0.0.1 -P 5140 --rfc3164  "Hello Fluentd Demo" 

输出

1
2024-11-01 01:45:01.000000000 +0000 system.user.notice: {"host":"node51","ident":"root","message":"Hello Fluentd Demo"}

输入

1
logger -n 127.0.0.1 -P 5140 --rfc3164 -t my_app  "Hello Fluentd Demo" 

输出

1
2024-11-01 01:47:18.000000000 +0000 system.user.notice: {"host":"node51","ident":"my_app","message":"Hello Fluentd Demo"}

输入

1
logger -n 192.168.2.51 -P 5140 -p local0.notice -t myapp -d --rfc3164 "test"

输出

1
2024-11-01 01:48:27.000000000 +0000 system.local0.notice: {"host":"u65","ident":"myapp","message":"test"}

Fluentd 对接 NeuVector

NeuVector 支持通过 syslog 将相关的安全事件和CVE 数据(可以针对每个 CVE 单独发送,也可以包含分层扫描结果)发送到 syslog 服务器,例如 Fluentd。

这里配置稍微有些不同,参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<source>
@type syslog
port 5140
bind 0.0.0.0
tag system
<parse>
@type syslog
message_format rfc5424 # 明确指定RFC 5424格式
with_priority true # 包含优先级字段
</parse>
</source>

<match system.**>
@type stdout
@id stdout_output
</match>

接着在 NeuVector 的 Settings -> Configuration 页面,配置 syslog 对应的参数即可。

其他

相关参考链接:

https://datatracker.ietf.org/doc/html/rfc5424

https://en.wikipedia.org/wiki/Syslog

https://en.wikipedia.org/wiki/Rsyslog

https://docs.redhat.com/zh-cn/documentation/red_hat_enterprise_linux/7/html/system_administrators_guide/s1-basic_configuration_of_rsyslog

https://www.rsyslog.com/doc/configuration/conf_formats.html

https://www.cnblogs.com/shu-sheng/p/13275474.html