tcp-check 期望连续第二个数据包中的二进制响应
tcp-check expect binary response in second packet in a row
我正在尝试使用 HAProxy 版本 1.5.8 在我的后端服务器上构建 TCP 检查。
行为应该如下:
- 发送二进制数据到服务器
- 收到 ACK 作为第一个数据包
- 在第二个数据包中收到确认数据
所以我需要检查在发送二进制数据后我收到了 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
- Receive ACK as first packet
HA 代理不在原始数据包级别工作,而是在 TCP 级别工作。在此级别,不存在作为单个数据包的 ACK 之类的东西。在这个级别甚至没有数据包的概念。相反,只有由接收到的字节组成的数据流的概念。
Every time I received back from server ACK, connection is terminated by HAProxy with the result that the backend server is down.
鉴于 HA 代理首先不关心负载为零的数据包,您的 "ACK as first packet" 可能实际上是一些包含 ACK 的数据包(几乎所有 TCP 数据包都这样做)但也包含一些有效负载,但不是您期望的 "next packet"。由于有效载荷与您指定的预期载荷不匹配,因此检查失败。
请注意,这只是基于您 "ACK as first packet" 的不完整信息做出的假设。为了证明这一假设,实际上需要查看线路上到底发生了什么,例如通过数据包捕获。
EDIT#1:
在 OP 提供了一些(未记录的)数据包转储和一些找出这些数据包中实际 IP header 开始的位置(偏移量 14,即前缀使用第 2 层以太网 header) 很明显,第一个数据包没有有效负载,这意味着它会被检查完全忽略。然后第二个数据包具有以下 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 之后,可以看到 client/haproxy 和服务器的行为差异:
没有 haproxy:
- 客户端向服务器发送 2 个字节
\x00\x11
,然后是 17 个字节 \x30\x30....
- 服务器立即回复 17 个字节
\x00\x0f\x30\x30....
使用 haproxy:
- haproxy 发送 17 个字节
\x30\x30...
到服务器。
它不像原始服务器那样发送最初的 2 个字节 \x00\x11
!
- 服务器不回复(除了没有负载的 ACK)。在 6 秒不活动后,haproxy 关闭与服务器的连接并可能认为检查失败。
总结:我认为 haproxy 检查无法向服务器发送正确的请求,即前 2 个字节丢失。这就是为什么服务器根本不会响应并且在超时后检查会失败的原因。
我正在尝试使用 HAProxy 版本 1.5.8 在我的后端服务器上构建 TCP 检查。
行为应该如下:
- 发送二进制数据到服务器
- 收到 ACK 作为第一个数据包
- 在第二个数据包中收到确认数据
所以我需要检查在发送二进制数据后我收到了 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
- Receive ACK as first packet
HA 代理不在原始数据包级别工作,而是在 TCP 级别工作。在此级别,不存在作为单个数据包的 ACK 之类的东西。在这个级别甚至没有数据包的概念。相反,只有由接收到的字节组成的数据流的概念。
Every time I received back from server ACK, connection is terminated by HAProxy with the result that the backend server is down.
鉴于 HA 代理首先不关心负载为零的数据包,您的 "ACK as first packet" 可能实际上是一些包含 ACK 的数据包(几乎所有 TCP 数据包都这样做)但也包含一些有效负载,但不是您期望的 "next packet"。由于有效载荷与您指定的预期载荷不匹配,因此检查失败。
请注意,这只是基于您 "ACK as first packet" 的不完整信息做出的假设。为了证明这一假设,实际上需要查看线路上到底发生了什么,例如通过数据包捕获。
EDIT#1:
在 OP 提供了一些(未记录的)数据包转储和一些找出这些数据包中实际 IP header 开始的位置(偏移量 14,即前缀使用第 2 层以太网 header) 很明显,第一个数据包没有有效负载,这意味着它会被检查完全忽略。然后第二个数据包具有以下 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 之后,可以看到 client/haproxy 和服务器的行为差异:
没有 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 发送 17 个字节
总结:我认为 haproxy 检查无法向服务器发送正确的请求,即前 2 个字节丢失。这就是为什么服务器根本不会响应并且在超时后检查会失败的原因。