本文主要记录了一些在特殊网络下使用 HAProxy 的一些进阶使用技巧,如网络上层应用 Health Check 的精准检测(HA)和负载均衡。本期主要介绍 Health Check 在 proxy 中的使用细节。

Health Check

我们使用 HAProxy 作为大局域网内的多 VPS 聚合和 HA 是想尽可能提高科学服务的稳定性的,进程异常退出和 TCP 端口连接超时这些问题都是比较容易检测出来的,但是还有一些时候通往国外的 TCP 端口连接正常,可科学服务就是有问题。这种场景下,我们就需要利用 HAProxy 高级一点的 TCP 或者 HTTP 检活机制了,让其更接近上层应用的真实需求。

在了解 HAProxy Health Check 的进阶技巧之前,推荐去看看 HAProxy 官网文档Performing Health Checks 官网文档有利于了解 HAProxy 的全貌,而后文则对你了解 HAProxy 的 Health Check 机制更有帮助。对于我们的科学网络服务,更贴近上层应用的检活机制恐怕非 Google 的 generate_204 服务莫属了,我们只需要请求 http://client3.google.com/generate_204 即可判断网络是否连通。由于是一个 HTTP 请求,我们可以利用 HAProxy 的 tcp-checkhttp-check 分别检测 socks5http proxy.

tcp-check

tcp-check 机制相对麻烦一些,毕竟是处于应用层之下的协议,tcp-check 中,我们需要发送的内容是 TCP payload, 这部分可以通过 tcpdump 或者更为直观一点的 wireshark 抓包得到。以 socks5 为例,HAProxy 中的配置如下:

listen ha-socks5
    bind 127.0.0.1:xxxx
    option tcp-check
    tcp-check connect
    tcp-check send-binary 05020001
    tcp-check expect binary 0500
    tcp-check send-binary 0501000312636c69656e74332e676f6f676c652e636f6d0050
    tcp-check expect binary 050000010000000006b5
    #tcp-check send-binary 474554202f67656e65726174655f32303420485454502f312e310d0a486f73743a20636c69656e74332e676f6f676c652e636f6d0d0a557365722d4167656e743a206375726c2f372e35342e300d0a4163636570743a202a2f2a0d0a0d0a
    tcp-check send GET\ /generate_204\ HTTP/1.1\r\n
    tcp-check send Host:\ client3.google.com\r\n
    tcp-check send User-Agent:\ curl/7.54.0\r\n
    tcp-check send Accept:\ */*\r\n
    tcp-check send \r\n
    tcp-check expect rstring ^HTTP/1.1\ 204
    balance     source
    hash-type consistent # optional
    server xxx1 127.0.0.1:11110 check
    server xxx2 127.0.0.1:11111 check backup

从以上配置可以看出我们利用 HAProxy 模拟了 socks5 请求的全过程:

  1. 建 TCP 连接
  2. 协商认证方式
  3. 协商访问目标主机
  4. 发送真正代理请求

其中第2步和第3步与 socks server 的实现有关系,需要自己抓包进行分析,着重分析 TCP payload(data) 部分就好了。多行 send 请求会合并为一行,当然你也可以选择发送对应的二进制内容。

socks5 协议细节可参考 https://www.ietf.org/rfc/rfc1928.txt

http-check

http-check 的配置相对简单一些,HAProxy 的配置如下:

listen ha-http
    bind :::xxxx
    option httpchk GET http://client3.google.com/generate_204 HTTP/1.1\r\nHost:\ client3.google.com\r\nProxy-Authorization:\ Basic\ xxxx\r\nProxy-Connection:\ Keep-Alive
    balance     source
    hash-type consistent # optional
    server xxx1 127.0.0.1:11120 check
    server xxx2 127.0.0.1:11121 check backup

需要注意的是其中 \r\n\ 空格的发送,由于我的 http proxy 配置了 Basic 认证,因此在这里也需要一并加上,Basic 的内容是对用户名和密码 base64 编码,这个报文细节可以通过 curl -v 得到。

Load Balance

细心的小伙伴可能会发现上述 Health Check 的配置中 balance 使用了 source.

待续…