使用 HAProxy 实现 TCP 粘性会话以处理 SSL 直通流量

使用 HAProxy 实现 TCP 粘性会话以处理 SSL 直通流量

当 SSL 必须在后端服务器上终止时,我们如何在 HAProxy 中实现会话粘性?我们需要粘性,因为后端无法共享会话。

这是我的原始配置:

# SSL passthrough
listen https_handler
    bind 1.2.3.4:443
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

# haproxy logs (not sticking)
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.396] fe BACKEND_Website/s1 37/0/1/3/41 200 8364
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s1 36/0/1/1/39 200 9082
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s2 35/0/1/3/39 200 2529
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 35/0/0/3/38 200 1460
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.501] fe BACKEND_Website/s2 36/0/1/1/109 200 376
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 36/0/1/1/74 200 2298
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.604] fe BACKEND_Website/s1 35/0/1/2/38 200 5542

下面的配置是我尝试读取的src

这会导致 502 Bad Gateway 错误。我猜想,这是因为流量到达后端时已被解密。

# terminate SSL at HAProxy 
listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

请注意,我将证书插入到绑定中。这是为了让 HAProxy 能够读取 src 并设置 stick-table。(不确定这是否正确。)此时,流量已经解密。

我认为问题在于当解密的流量传递到需要加密流量的后端服务器时......

我看到了这些建议:

  1. 在 HAProxy 1.5 上终止 SSL- 就我而言不可能。SSL 需要由后端服务器处理。
  2. 使用 SSL 会话 ID 来保持粘性。- 我对此持怀疑态度,因为我还不太明白。而且它似乎使用的是修改版(?)的 haproxy。
  3. 使用send-proxy指令和X-Forward-Proto标头.——但意识到这也需要一个仅 HTTP 的后端。

如果有任何建议我将非常感激。

答案1

最简单的解决方案是使用balance source,但如果许多客户端来自同一个 IP,则对您的后端服务器可能不太公平。

http://blog.haproxy.com/2013/04/22/client-ip-persistence-or-source-ip-hash-load-balancing/以了解有关实现此目的的方法的更多讨论。

答案2

如果问题的根源在于后端服务器期望流量是 HTTPS 而不是 HTTP,请尝试加密HTTP 并执行常规 Layer7 负载平衡。

listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode http
    balance leastconn
    # any stick rules you need
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

更简单的是 - 无论如何,你显然都试图坚持src,为什么你首先要解密 TCP 流量?

listen https
    bind 1.2.3.4:443 # <- NO ssl setting
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

在 TCP 模式下,您不必关心有效载荷。具体来说,您不必关心它是否加密以及如何加密。

相关内容