Spring Boot配置Logstash remote_host读取X-Forward-For获取真实客户端IP
实现方案(按改造成本从低到高排序)
方案1:Logstash管道层直接替换字段(优先推荐,零应用侧改动)
不需要调整任何应用端日志配置,仅修改Logstash规则即可直接覆盖remote_host字段,改造成本最低。
- 如果Logstash直接作为HTTP接收端部署在负载均衡后端,直接修改input段配置即可自动完成替换,不需要额外写过滤规则:
input { http { port => 8080 # 开启X-Forwarded-For头自动解析 use_forwarded_for => true # 将解析得到的真实客户端IP直接写入remote_host字段 remote_host_target_field => "remote_host" } }
- 如果日志是由应用侧上报、X-Forwarded-For值已经包含在日志字段中(字段名通常为
x_forwarded_for或X-Forwarded-For),在filter段添加如下规则即可。多层代理场景下X-Forwarded-For为逗号分隔的IP列表,最左侧第一个为真实客户端IP:
filter { if [x_forwarded_for] { mutate { split => ["x_forwarded_for", ","] add_field => { "tmp_real_ip" => "%{[x_forwarded_for][0]}" } } mutate { strip => ["tmp_real_ip"] # 直接覆盖原有remote_host字段 replace => { "remote_host" => "%{tmp_real_ip}" } # 清理临时字段,可按需保留原始X-Forwarded-For值 remove_field => ["tmp_real_ip"] } } }
注意:如果存在多层内网代理,建议额外添加可信IP段校验逻辑,过滤掉客户端伪造的X-Forwarded-For头值,避免拿到虚假IP。
方案2:应用侧日志编码器局部覆盖(无Logstash配置权限时可选)
重定义全量日志字段的方案确实冗余,使用AccessEventCompositeJsonEncoder时不需要重写所有默认字段,只需要单独覆盖remote_host的取值规则即可,原有默认日志字段会全部保留,配置量极小:
<encoder class="net.logstash.logback.composite.accessevent.AccessEventCompositeJsonEncoder"> <providers> <!-- 加载所有默认日志字段,无需逐个手动定义 --> <defaultProviders> <fieldNames> <remoteHost>remote_host</remoteHost> </fieldNames> </defaultProviders> <!-- 单独覆写remote_host取值,优先提取X-Forwarded-For第一个IP --> <accessEventPattern> <pattern> { "remote_host": "%replace(%requestHeader{X-Forwarded-For}){^([^,]+).*$,$1}" } </pattern> </accessEventPattern> </providers> </encoder>
如果X-Forwarded-For头不存在,上述配置会自动回退使用TCP连接的对端IP(即当前记录的负载均衡IP),不会出现字段空值问题。
内容的提问来源于stack exchange,提问作者Webbo
相关产品推荐
相关产品推荐

