当 SSL 终止并转发时,HAProxy SSL 轮循机制不起作用

oaz*_*bir 2 haproxy

我使用以下配置来终止 SSL,以便我可以检查请求、进行 URL 重写、ACL 等,然后将 SSL 流量转发回我的后端服务器。但是,我无法坚持工作。当我只使用“模式 tcp”并执行直接的 tcp 路由时,我可以粘着工作,但是一旦我开始在前端终止 SSL,粘性就会停止工作。

这是我的配置:

frontend https-forward
  bind *:443 ssl crt /etc/haproxy/certs.d/combo.pem

  option http-server-close
  option forwardfor
  reqadd X-Forwarded-Proto:\ https
  reqadd X-Forwarded-Port:\ 443

  capture request header Referrer len 64
  capture request header Content-Length len 10
  capture request header User-Agent len 64

  # set HTTP Strict Transport Security (HTST) header
  rspadd  Strict-Transport-Security:\ max-age=15768000

  # some ACLs and URL rewrites...

  default_backend backstuff

backend backstuff

  log 127.0.0.1 local2 notice

  balance roundrobin
  option ssl-hello-chk
  stick-table type binary len 32 size 30k expire 30m

  acl clienthello req_ssl_hello_type 1
  acl serverhello rep_ssl_hello_type 2

  tcp-request inspect-delay 5s
  tcp-request content accept if clienthello
  tcp-response content accept if serverhello

  stick on payload_lv(43,1) if clienthello
  stick store-response payload_lv(43,1) if serverhello

  server PO1 10.35.59.160:443 ssl verify none maxconn 5000
  server PO2 10.35.59.161:443 ssl verify none maxconn 5000
Run Code Online (Sandbox Code Playgroud)

Gre*_*egL 5

您不能像使用时那样坚持使用 SSL 会话 ID 的原因mode http(除非您明确指定,否则为默认设置mode tcp)是您尝试在数据包有效负载的某些字节上执行此操作,而实际上数据包已被解码这些偏移量可能包含完全随机的数据。

您在这里有两个选择。

  1. 基于源IP的棒

    如果您不反对坚持使用客户端的 IP,而不是像现在这样使用 SSL 会话 ID,那么您可以将配置更改为如下所示:

    frontend https-forward
      bind *:443 ssl crt /etc/haproxy/certs.d/combo.pem
      mode http
    
      option http-server-close
      option forwardfor
      reqadd X-Forwarded-Proto:\ https
      reqadd X-Forwarded-Port:\ 443
    
      capture request header Referrer len 64
      capture request header Content-Length len 10
      capture request header User-Agent len 64
    
      # set HTTP Strict Transport Security (HTST) header
      rspadd  Strict-Transport-Security:\ max-age=15768000
    
      # some ACLs and URL rewrites...
    
      default_backend backstuff
    
    backend backstuff
      mode http
      log 127.0.0.1 local2 notice
      balance roundrobin
      option ssl-hello-chk
    
      stick-table type ip size 30k expire 30m
      stick on src
    
      server PO1 10.35.59.160:443 ssl verify none maxconn 5000
      server PO2 10.35.59.161:443 ssl verify none maxconn 5000
    
    Run Code Online (Sandbox Code Playgroud)

    关键的变化是stick-tablestick on行,以及显式使用mode http

    正如您所说,如果访问您站点的许多客户端都在 NAT 之后,那么它们最终都会在同一台服务器上,因此这不是最流畅的分发,但它确实有效并提供了您想要的功能。

  2. 使用 HAProxy 解码的 SSL 会话 ID

    在这里,您必须通过ssl_fc_session_id( docs )利用 HAproxy 的连接知识。

    ssl_fc_session_id : binary
    当传入连接是通过 SSL/TLS 传输层建立时,返回前端连接的 SSL ID。将给定的客户端粘贴到服务器上很有用。需要注意的是,某些浏览器每隔几分钟刷新一次会话 ID。

    在这种情况下,您将使用与我上面提供的相同的配置,但将 stick-tablestick行更改为:

      stick-table type binary len 32 size 30k expire 30m
      stick on ssl_fc_session_id
    
    Run Code Online (Sandbox Code Playgroud)

    这与您要实现的目标非常相似。