syslog PRI值是否允许为负值?Cisco ASA日志转发场景出现负值如何解决?
该问题的核心诱因是TCP传输场景下的syslog报文粘包/断连残留半包拼接错误,和超时时间长度无直接关联,调整超时仅能降低断连概率,无法根治问题:
TCP断连残留报文拼接
当前架构中所有节点的TCP syslog传输默认采用换行符作为帧边界,当客户端连接超时中断时,haproxy或syslog-ng的接收缓冲区会残留最后一条未读取完整、缺少尾部换行符的半截日志。新连接建立后,新发送的首条日志会直接拼在残留半截日志的尾部,导致syslog-ng解析PRI值时读取到错误的偏移位置,最终解析出负数PRI。
你提供的异常日志就是典型的拼接现象:前半条残留日志的尾部和新日志的头部拼接后,原本应该为<165>这类合法PRI的位置被覆盖为<-1>。
2. ## Cisco ASA TCP syslog默认无长度标识
Cisco ASA默认发送TCP syslog时未开启RFC6587规定的字节计数帧前缀,仅依赖换行符分割报文,一旦传输中断就会出现帧边界识别失效的问题。
按优先级从高到低排列,建议逐层配置验证:
1. 开启Cisco ASA TCP syslog字节计数帧
直接从源端解决帧边界识别问题,在ASA全局配置模式下执行命令:
logging syslog-tcp framing octet-counted
该配置会在每条TCP syslog报文前添加报文长度标识,接收端不需要依赖换行符即可准确分割报文,彻底避免粘包和拼接问题。
2. 调整haproxy断连缓冲区清理规则
在haproxy对应syslog转发的listen/backend配置段添加如下参数,断连后立刻清理残留缓冲区数据,避免残留报文和新连接报文拼接:
listen syslog-tcp bind 0.0.0.0:1470 mode tcp timeout client 12h timeout server 12h # 新增以下配置 timeout client-fin 1s timeout server-fin 1s option tcp-smart-accept option tcp-smart-connect
3. syslog-ng端添加校验和帧分割规则
修改syslog-ng的TCP源配置,开启严格帧校验,过滤异常PRI报文:
source s_syslog_tcp { syslog( transport("tcp") port(1470) flags(octet-counted) # 支持字节计数帧分割 keep-alive(yes) ); }; # 新增合法PRI过滤规则 filter f_valid_pri { pri(0..191); # 合法syslog PRI值范围为0~191 }; # 日志路由仅转发合法报文 log { source(s_syslog_tcp); filter(f_valid_pri); destination(d_kafka); }; # 可选:异常报文单独存入本地文件用于排查 filter f_invalid_pri { not pri(0..191); }; destination d_invalid_log { file("/var/log/syslog-ng/invalid.log"); }; log { source(s_syslog_tcp); filter(f_invalid_pri); destination(d_invalid_log); };
你反馈的异常日志就是典型的拼接后错误报文:
<-1>May 24 2021 17:40:28: %ASA--1-6414004: TCP Syslog Server private:xx.xx.xx.xx/1470 - Connection restored CAL\\John Mike/xxxxxxxxxxxxxxxxxx) to private:xx.xx.xx.xx/xx duration 0:00:00 bytes 142 (John Mike/xxxxxxxxxxxxxxxxxx) xxxxxxx) 4 2021 17:40:28: %ASA-6-302016: Teardown UDP connection 1733810491
内容的提问来源于stack exchange,提问作者aniketpant

