You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rsyslog经反向隧道转发日志时属性被替换如何保留原始值

Rsyslog反向隧道转发日志属性嵌套/丢失解决方案

问题现象

  • 发送端host-A输出的原始JSON格式日志,经SSH反向隧道传输到接收端后,外层元属性被替换为localhost、127.0.0.1等本地回环值
  • 完整原始日志被整体嵌套封装到外层日志的message字段中,无法直接识别原始主机名、程序名等属性
  • 发送端原始日志示例:
{"@timestamp":"xxxxxxx","@version":"1","sysloghost":"host-A","severity":"xxxxxxx","facility":"xxxxxxx","programname":"host-A-app","procid":"xxxxxxx","relayhost":"host-A","relayip":"host-A","message": "xxxxxxx"}
  • 隧道接收端异常日志示例:
{"@timestamp":"yyyyyyy","@version":"1","sysloghost":"localhost","severity":"notice","facility":"user","programname":"","procid":"-","relayhost":"localhost","relayip":"127.0.0.1","message":{"@timestamp":"xxxxxxx","@version":"1","sysloghost":"host-A","severity":"xxxxxxx","facility":"xxxxxxx","programname":"host-A-app","procid":"xxxxxxx","relayhost":"host-A","relayip":"host-A","message": "xxxxxxx"}}

根因说明

反向隧道本质是将发送端的日志流映射到接收端本地的127.0.0.1回环端口,接收端rsyslog默认对从该端口收到的所有流量做全新syslog报文解析:自动提取TCP/IP层的源地址(127.0.0.1)、源主机名(localhost)生成外层元数据,由于收到的载荷本身是完整JSON格式日志,没有符合标准syslog的报文头,rsyslog就会把整个JSON载荷直接当做普通消息文本写入message字段,最终形成嵌套结构。

可行解决方案

方案1:接收端配置JSON解析规则,直接提取嵌套原始日志属性(推荐,无侵入)

不需要修改发送端配置,在接收端rsyslog加载mmjsonparse模块,匹配从回环端口收到的日志,直接解析message字段内的原始JSON,将原始属性提升为日志顶层属性,覆盖外层错误的本地元数据即可。
配置写入接收端rsyslog配置文件,通常路径为/etc/rsyslog.conf或/etc/rsyslog.d/下的自定义conf文件:

# 加载JSON解析模块
module(load="mmjsonparse")

# 定义规则集:专门处理反向隧道端口进来的日志
ruleset(name="process_tunnel_log") {
    # 解析当前报文的message字段(即嵌套的原始JSON日志)
    action(type="mmjsonparse")
    # 校验是否解析成功(即message字段确实是合法JSON)
    if $parsesuccess == "OK" then {
        # 把解析出来的原始属性赋值给顶层元数据字段
        set $!sysloghost = $!message!sysloghost;
        set $!programname = $!message!programname;
        set $!severity = $!message!severity;
        set $!facility = $!message!facility;
        set $!relayhost = $!message!relayhost;
        set $!relayip = $!message!relayip;
        set $!message = $!message!message;
        # 后续可接转发、本地存储等动作,此时操作的日志已经是还原后的原始属性
        *.* /var/log/tunnel_collect.log
        stop
    }
    # 解析失败的非JSON日志走默认处理逻辑
    *.* /var/log/messages
}

# 绑定监听端口到上述规则集,端口替换为实际反向隧道映射的本地端口,比如10514
input(type="imtcp" port="10514" ruleset="process_tunnel_log" address="127.0.0.1")

配置完成后执行systemctl restart rsyslog即可生效,该方案解析性能远高于正则匹配、文本检索方式。

方案2:发送端配置标准syslog头封装,避免接收端重复解析

如果可以修改发送端配置,在发送端输出JSON日志时,提前加上标准syslog报文头,接收端就不会把整个JSON当做普通消息体封装。发送端转发配置参考:

# 发送端配置转发时使用标准syslog格式封装JSON内容
*.* action(type="omfwd" target="127.0.0.1" port="20514" protocol="tcp"
           template="RSYSLOG_SyslogProtocol23Format"
           TCP_Framing="octet-counted")

该方案下接收端不需要做特殊JSON解析,rsyslog会自动识别报文头后的JSON载荷,不会出现localhost属性替换问题,长期稳定性最好,符合syslog标准规范。

方案3:调整隧道转发模式,避免源地址被替换为回环地址

如果使用SSH反向隧道,可在隧道参数中添加-g参数允许远程主机绑定到非回环地址,同时配合rsyslog的preservefqdn参数开启主机名保留,直接读取日志内携带的主机名字段,不做反向解析替换:

# 接收端全局配置添加
global(preservefqdn="on")

注意:该方案需要确保隧道两端网络连通性正常,避免非回环绑定出现端口暴露风险,仅建议测试环境使用。

内容的提问来源于stack exchange,提问作者Orisson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:48:19