基于TLS的Syslog-ng跨服务器日志转发问题:目标服务器未将日志写入磁盘
结合你描述的情况——证书、TLS连接都正常,端口有数据包但日志不落地,已经排除权限、SELinux问题,咱们一步步拆解可能的原因:
1. 先排查路径宏变量的有效性
你的目标路径用了$LOGHOST、$HOST_FROM、$HOST这些宏变量,很可能是这些变量未被正确解析,导致生成的路径不存在或者无效。
测试方法:
先把destination简化成最基础的路径,比如:
destination d_test { file("/tmp/test_encrypted.log" owner("syslogng") group("syslogng")); };
然后修改log配置指向这个测试destination,重启syslog-ng后发送测试日志。如果/tmp/test_encrypted.log能正常写入,说明问题出在原路径的宏变量上。
你可以用syslog-ng -Fevd启动服务(前台调试模式),搜索调试日志里的destination相关条目,查看实际生成的路径是什么,就能定位哪个宏变量出了问题。比如RHEL7上的旧版syslog-ng,部分宏变量名称可能和新版不同,比如$HOST_FROM可能需要换成$SOURCEIP。
2. 检查Syslog格式解析是否匹配
你的接收端source用的是syslog(),它默认强制解析RFC3164格式的日志。如果发送端发送的是RFC5424或者自定义格式的日志,接收端可能无法正确解析,导致宏变量为空,最终无法生成有效路径。
测试方法:
把source改成network()类型(原始流接收,不强制解析syslog格式),加上flags(no-parse)参数:
source s_encrypted_syslog { network(ip(0.0.0.0) port(1470) transport("tls") tls(key-file("/etc/syslog-ng/key.d/privkey.pem") cert-file("/etc/syslog-ng/cert.d/servercert.pem") peer-verify(optional-untrusted)) flags(no-parse)); };
再配合刚才的d_test destination测试,如果能写入,说明是格式解析不匹配的问题。你需要要么调整发送端的日志格式,要么在接收端的source里指定正确的格式(比如format(rfc5424))。
3. 核对配置语法的细节问题
你提到配置可能有笔误,虽然服务能启动,但部分参数可能未生效。比如:
- 你写的
certfile应该是cert-file(下划线分隔,旧版syslog-ng对参数名的大小写/分隔符敏感) - 检查source的括号是否闭合:你给出的source最后是
peer-verify(optional-untrusted)) },多了一个闭合括号,正确的应该是peer-verify(optional-untrusted)); };
可以先执行syslog-ng -s检查配置语法,看有没有隐藏的警告信息,这些警告可能不会导致服务启动失败,但会让部分配置失效。
4. 确认调试日志中的关键节点
用syslog-ng -Fevd启动后,重点关注这些日志条目:
Listening on TCP socket:确认1470端口是否正常监听New connection from:确认发送端的连接被成功接受Message received:确认接收端确实收到了日志消息Writing message to file:确认服务尝试写入文件,以及实际使用的路径是什么
如果没有Message received,说明TLS连接虽然建立,但没有实际的日志数据传输;如果有这个条目但没有写入日志,大概率是路径或权限问题(虽然你排除了权限,但测试路径可以再确认)。
内容的提问来源于stack exchange,提问作者ropo101




