告警规则分别写在 rsyslog 的 /etc/rsyslog.d/ 和 syslog-ng 的 /etc/syslog-ng/conf.d/;rsyslog 用 if $msg contains 或 re_match() 匹配,需加 $programname 等上下文过滤;输出链路需检查权限、防火墙和本地落地验证;必须配置 rate-limit 防止洪峰告警。

告警规则写在哪儿?rsyslog 和 syslog-ng 路径不同
Linux 系统日志告警不是靠“加个插件”就能生效,得先确认你用的是哪个日志守护进程。大多数 CentOS/RHEL 7+ 默认用 rsyslog,而 Debian/Ubuntu 22.04+ 开始默认切到 syslog-ng——两者的规则语法、配置位置、加载机制完全不同,混用必失效。
-
rsyslog规则写在/etc/rsyslog.d/下的.conf文件里,比如/etc/rsyslog.d/99-alert.conf;必须以$ActionFileDefaultTemplate或template定义输出格式,再用if $msg contains 'Failed password' then ...这类条件触发 -
syslog-ng规则写在/etc/syslog-ng/conf.d/(或主配置里的filter+destination+log三段式),匹配靠正则:filter f_ssh_fail { message(".*Failed password.*"); }; - 改完配置后,
rsyslog要sudo systemctl reload rsyslog,syslog-ng必须用sudo syslog-ng-ctl reload(systemctl reload在某些版本不生效)
if $msg contains 为什么总漏报?匹配逻辑太粗糙
rsyslog 的 contains 是纯子串匹配,不支持正则,也不区分大小写(除非显式加 ignorecase),更不会跨行。实际日志里,“authentication failure” 可能出现在第二行,或者被缩写成 auth fail,又或者带时间戳前缀干扰匹配。
- 优先换
re_match($msg, "Failed password for invalid user|Connection closed by"),它支持 PCRE 正则,且可一次写多个模式 - 避免只匹配关键词,比如
"error"——内核日志、cron、journal 都会刷这个,告警爆炸是常态 - 加上下文过滤:用
$programname == 'sshd'或$syslogfacility-text == 'auth'限定来源,比单靠消息体可靠得多
告警发出去了,但收不到?action 输出链路常断在三处
写好规则只是第一步,真正卡住的地方往往在“怎么送出去”。常见的是本地命令执行失败、网络请求超时、或权限不足导致写入临时文件失败。
- 用
omprog调外部脚本时,脚本必须有可执行权限(chmod +x),且第一行#!/usr/bin/env bash路径要真实存在;rsyslog默认以syslog用户运行,不能直接curl写入需认证的 Webhook - 用
omfwd发 TCP/UDP 到告警平台时,务必检查防火墙:sudo ss -tuln | grep :514看端口是否监听,sudo tcpdump -i lo port 514确认包发出没 - 测试阶段别省事:在规则末尾加一行
*.* /var/log/debug_alert.log,把所有匹配日志落地,比盲等邮件/钉钉强十倍
为什么凌晨三点批量告警?rate limit 不设等于自扰
一条 SSH 暴力破解日志每秒刷几十条,没限流规则的话,一分钟能触发上千次告警。不是规则没写对,是压根没防住洪峰。
-
rsyslog用$SystemLogRateLimitInterval 60和$SystemLogRateLimitBurst 5控制全局速率(单位:秒 + 条数),但这是针对整个rsyslog进程,不够精细 - 更稳妥的是在规则里嵌套限流:用
call rate_limit定义模板,再配合if $msg re_match ... and not (rate_limit()) then ... -
syslog-ng原生支持rate-limit(5)参数,直接写在log块里,比rsyslog清晰不少
真正的麻烦不在语法,而在日志格式本身——不同服务输出结构不一,同一服务升级后字段可能变动,靠固定字符串匹配迟早翻车。留个心眼:关键告警规则上线前,先用 journalctl -u sshd -n 100 --no-pager 抽样看原始日志长什么样,别光盯着文档抄示例。










