【问题标题】:tcp-check expect binary response in second packet in a rowtcp-check 期望连续第二个数据包中的二进制响应
【发布时间】:2019-01-02 15:46:09
【问题描述】:

我正在尝试使用 HAProxy 1.5.8 版在我的后端服务器上构建 TCP 检查。

行为应该如下:

  1. 向服务器发送二进制数据
  2. 接收 ACK 作为第一个数据包
  3. 在第二个数据包中接收确认数据

所以我需要检查在发送二进制数据后我收到了 ACK,然后在第二个数据包中连续收到其他二进制数据。

是否可以使用 HAProxy 来做到这一点。

我试图在文档中找到它并尝试创建不同的配置,但未成功:

option tcp-check
tcp-check connect
tcp-check send-binary 303030303030
tcp-check expect binary 303030303030

每次我收到来自服务器的 ACK 时,HAProxy 都会终止连接,结果后端服务器已关闭。

编辑:

我将收到以下信息:

发送数据后的第一个数据包

0000   a0 66 10 09 2e 46 9c af ca bb aa 47 08 00 45 00    f...F.¯Ê»ªG..E.
0010   00 28 40 58 40 00 3e 06 d7 04 0a 1e 0b 34 0a 02   .(@X@.>.×....4..
0020   06 20 25 1c d5 80 91 0a f8 87 db 03 25 8f 50 10   . %.Õ...ø.Û.%.P.
0030   01 c9 03 d6 00 00 00 00 00 00 00 00               .É.Ö........

紧接在上面的第二个数据包

0000   a0 66 10 09 2e 46 9c af ca bb aa 47 08 00 45 00    f...F.¯Ê»ªG..E.
0010   00 39 40 59 40 00 3e 06 d6 f2 0a 1e 0b 34 0a 02   .9@Y@.>.Öò...4..
0020   06 20 25 1c d5 80 91 0a f8 87 db 03 25 8f 50 18   . %.Õ...ø.Û.%.P.
0030   01 c9 2d 2e 00 00 00 0f 30 30 30 30 30 30 42 33   .É-.....000000B3
0040   30 30 43 48 45 43 4b                              00CHECK

第一个没有任何数据,我需要检查第二个是否包含 000000。

EDIT2:

提供 PCAP:

通信直接从客户端到服务器时的正常行为,没有 HAProxy: Normal behavior - client to server

使用HAProxy作为负载均衡器,连接到同一个服务器,用同样的命令检查,检查失败: failing check - HAProxy to server

后端配置:

backend nodes
        mode tcp
        balance roundrobin
        default-server inter 10s fall 3 rise 2
        option tcp-check
        tcp-check connect
        tcp-check send-binary 303030303030423230303035434845434b
        tcp-check expect binary 000f30303030303042333030434845434b
        server server1 10.30.11.52:9500 check
        server server2 10.30.11.52:9501 check
        server server3 10.30.11.52:9502 check

【问题讨论】:

    标签: tcp binary haproxy health-monitoring


    【解决方案1】:
    1. 接收 ACK 作为第一个数据包

    HA 代理不在原始数据包级别工作,而是在 TCP 级别工作。在这个级别,没有像单个数据包这样的 ACK。在这个级别甚至没有数据包的概念。相反,只有由接收到的字节组成的数据流的概念。

    每次我收到来自服务器的 ACK 时,HAProxy 都会终止连接,结果后端服务器已关闭。

    鉴于 HA 代理首先不关心有效负载为零的数据包,因此您的“ACK 作为第一个数据包”实际上可能是一些包含 ACK 的数据包(就像几乎所有 TCP 数据包一样)但也包含一些有效载荷,但不是您期望的“下一个数据包”。由于负载与您指定的负载不匹配,因此检查失败。

    请注意,这只是基于您的“ACK 作为第一个数据包”的不完整信息做出的假设。为了证明这一假设,我们实际上需要查看网络上的实际情况,例如通过数据包捕获。

    EDIT#1:
    在 OP 提供了一些(未记录的)数据包转储并确定这些数据包中的实际 IP 标头从哪里开始(偏移量 14,即以第 2 层以太网标头为前缀)之后,它是明确第一个数据包没有有效负载,这意味着它被检查完全忽略。然后第二个数据包具有以下 17 个字节的有效负载:

    0030                     00 0f 30 30 30 30 30 30 42 33         ..000000B3
    0040   30 30 43 48 45 43 4b                              00CHECK
    

    鉴于 OP 检查 binary 303030303030 但实际有效负载是 00 0f 30 30 30 30 30 30 ....,给定的 tcp-check expect ... 与实际有效负载不匹配,因此检查失败。

    编辑#2:
    在 OP 提供了没有和有 haproxy 的连接的 pcap 之后,可以看到客户端/haproxy 和服务器的行为差异:

    1. 没有 haproxy:

      • 客户端发送2个字节\x00\x11到服务器后跟17个字节\x30\x30....
      • 服务器立即回复 17 个字节 \x00\x0f\x30\x30....
    2. 使用 haproxy:

      • haproxy 发送 17 字节 \x30\x30... 到服务器。
        它不会像原始服务器那样发送最初的 2 字节 \x00\x11 !!!
      • 服务器不回复(没有负载的 ACK 除外)。在 6 秒不活动后,haproxy 将关闭与服务器的连接,并可能认为检查失败。

    总结:我认为 haproxy 检查未能向服务器发送正确的请求,即前 2 个字节丢失。这就是为什么服务器根本不会响应,并且在超时后检查会失败的原因。

    【讨论】:

    • 请看我的编辑,它应该提供更多关于收到什么和应该检查什么的说明。
    • @user1563721:查看我的答案的编辑。但实际上,连接的整个 TCP 捕获而不是所选数据的十六进制转储会更有用。
    • 当我根据您的回答将以下内容放入配置中时:tcp-check expect binary 000f30303030303042333030434845434b 检查仍然失败。要检查的二进制数据与第二个数据包的有效负载中的数据完全相同。但是连接在第一个数据包之后被 HAProxy 终止,因此 HAProxy 将不会收到带有有效负载的第二个数据包。这就是问题所在。
    • @user1563721:您能否提供完整连接的数据包捕获作为 pcap(文件,而不是十六进制转储),而不仅仅是选定数据包?
    • @user1563721:感谢 pcap 提供了很大帮助。我认为您未能向服务器发送正确的请求,这导致服务器根本没有响应,并且超时后检查失败 - 请参阅我的第二次编辑。
    猜你喜欢
    • 2021-05-08
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多