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

如何记录HAProxy代理的TCP连接内容?

需求:在HAProxy日志中完整记录TCP连接的传输内容

环境信息

  • 系统:Ubuntu Server 18.04
  • Docker版本:19.03.12
  • HAProxy镜像版本:2.7.3
  • Docker Compose版本:1.27.1
  • Docker Compose配置:
services:
  ftt_tcp_proxy_dev:
    container_name: ftt_tcp_proxy_dev
    image: haproxy:2.7.3
    ports:
      - "50000:50000"
    volumes:
      - /home/user1/git/ftt_tcp_proxy/dev/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    restart: unless-stopped

初始HAProxy配置

global
    log stdout format raw daemon

defaults
    mode tcp
    log global
    log-format "[%t] Connection on port %fp from ip %ci forwarded to %si:%sp with data x"
    timeout client 60s
    timeout client-fin 60s
    timeout connect 60s
    timeout server 60s
    timeout server-fin 60s
    timeout tunnel 60s

frontend server1
    bind :50000
    default_backend server2

backend server2
    server server2 10.10.150.82:50000

测试场景与问题

  • 在server2执行监听命令:nc -nvlkp 50000
  • 在server1通过HAProxy连接server2:nc haproxy01 50000(haproxy01为HAProxy容器所在服务器的DNS记录)
  • 连接可正常建立并转发内容,但日志仅显示占位符x

尝试过的配置及问题

  1. 首次调整frontend配置:

    tcp-request inspect-delay 5s
    tcp-request content capture req.payload(0,100) len 100
    

    同时将log-format中的x替换为%[capture.req.hdr(0)],但日志仅显示破折号-

  2. 二次调整配置:

    tcp-request content capture req.payload(0,5) len 5
    

    此时能成功记录“hello”,但存在局限:

    • 内容短于5字符时显示破折号
    • 内容长于5字符时仅记录前5个字符

当前临时方案

使用tcpdump记录内容:sudo tcpdump -i any -nn -A port 50000,但希望通过HAProxy配置实现需求


解决方案

HAProxy的TCP内容捕获机制无法自动适配任意长度的payload,因为req.payload(start,end)的结束位置是固定值,且len参数限制了最大捕获长度。可通过以下两种方式优化:

方式1:增大捕获长度并处理空内容

设置足够大的捕获长度(根据业务场景调整,比如1024字节),同时优化日志格式处理空值:

修改frontend配置:

frontend server1
    bind :50000
    tcp-request inspect-delay 10s  # 延长检查延迟,确保捕获完整初始payload
    tcp-request content capture req.payload(0,1024) len 1024
    default_backend server2

修改log-format:

log-format "[%t] Connection on port %fp from ip %ci forwarded to %si:%sp with data %[capture.req.hdr(0),field(-1,'-')]"
  • %[capture.req.hdr(0),field(-1,'-')]的作用是:若捕获内容为空(显示-),则替换为空字符串,避免日志出现多余破折号
  • 注意:若payload长度超过1024字节,仍只会记录前1024字节,这是HAProxy TCP捕获的固有限制

方式2:开启trace功能(仅适合调试)

如果是临时调试需求,可开启HAProxy的trace功能,详细记录TCP流内容:

在global段添加:

global
    log stdout format raw daemon
    trace level verbosity full output stdout

在frontend段添加:

frontend server1
    bind :50000
    trace tcp-request content capture all
    default_backend server2
  • 该方式会输出极详细的流数据,包括每个数据包内容,适合调试,不建议生产环境长期开启(会产生大量日志)

额外说明

TCP是流式协议,HAProxy无法自动识别“完整消息”边界,只能捕获初始段数据。如果你的业务协议有明确消息边界(比如固定长度、换行符分隔),可使用req.payload(0,1024,CRLF)这类规则,捕获到第一个换行符为止,自动截断到完整消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:02:22