您好,我目前正在将探测器的 suricata 日志发送到 Syslog-ng 服务器(172.16.238.15):
@version: 3.25
options {
keep-timestamp (no);
chain_hostnames (off);
keep_hostname (no);
};
source s_eve {
wildcard-file(
base-dir("/var/log/suricata/")
filename-pattern("*.json")
flags(no-parse)
keep-timestamp(no)
keep-hostname(no)
);
};
destination d_eve {
network(
"172.16.238.15" transport("tls") port(6514)
tls( ca_dir("/etc/syslog-ng/ca.d"))
template("$MSG\n")
);
};
log {
source(s_eve);
destination(d_eve);
};
一切运行正常,问题出在我尝试旋转探测器中的日志时。我使用的是 logrotate,suricata 生成的主要日志文件是 eve.json,旋转后会创建 eve.1.json、eve.2.json,最多 5 个。
因此,问题在于我在 Syslog-ng 服务器中收到重复的日志,因为 eve.1.json 或 eve.2.json 中的所有内容在轮换之前已经存在于 eve.json 中一段时间,并且已经发送到服务器,但由于它是一个新文件,它会再次发送它们。但是,如果我仅将 Syslog-ng 设置为仅发送原始 eve.json,那么如果在连接到服务器之前轮换了某些日志,我可能会不发送它们。
是否有任何配置可以让 Syslog-ng 将旋转的文件理解为一个,或者解决这个问题的方法是什么?
答案1
您可以配置 Suricata 在轮换时创建新的“eve.json”日志文件。这可确保将文件发送到 syslog-ng 时日志事件不会重复。
这里的主要思想是在 logrotate 配置中运行 postrotate 脚本,该脚本将 USR2 信号发送到 Suricata。Suricata 对此信号做出反应,关闭并重新打开日志文件。
以下是 logrotate 配置的示例:
/etc/logrotate.d/suricata
/var/log/suricata/*.json {
daily
rotate 5
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/bin/kill -USR2 `cat /var/run/suricata.pid 2> /dev/null` 2> /dev/null || true
endscript
}
postrotate 脚本向 Suricata 发送 USR2 信号,使其关闭当前日志文件并启动一个新文件。使用delaycompress
指令将确保最后一个日志文件不会被压缩,因此可以毫无问题地写入。
/var/run/suricata.pid
记得用 Suricata PID 文件的实际位置替换。
syslog-ng 配置将保持当前状态,因为它将始终读取当前的“eve.json”文件。写入上一个“eve.json”(已轮换)的任何事件都将在轮换之前发送到 syslog-ng。
syslog-ng 可以识别新文件,但不会跟踪轮换后重命名的文件。此配置非常适合此行为,因为每次轮换后都会创建一个新的“eve.json”。
编辑:
USR2 和 HUP 是可以发送给进程的不同类型的信号。它们都是用户定义的,没有特定的预定义功能 - 它们的行为由接收信号的程序定义。
对于 Suricata,发送 HUP 信号告诉它关闭并重新打开其日志文件,这在这些日志正在轮换时非常方便。另一方面,USR2 信号告诉 Suricata 重新加载其配置。
关于连接不稳定的问题,如果由于网络问题,日志条目写入日志的速度比 syslog-ng 发送日志的速度快,那么您确实会遇到丢失日志条目的问题。可以通过增加保留的轮换日志文件数量以及检查 syslog-ng 配置中的压缩日志文件(如果您的 syslog-ng 版本支持读取压缩文件)来缓解此问题。
请记住,解决此问题的任何方法都需要在确保发送所有日志条目和管理磁盘空间使用之间取得平衡。
您可能还想研究可靠的日志传输协议(如 RELP)或在 syslog-ng 中使用基于磁盘的存储的队列/缓冲区,当远程服务器不接受消息时,它可以将日志消息缓冲到磁盘。