HAProxy 1.6 SSL 连接重置

HAProxy 1.6 SSL 连接重置

我已经为这个 HAProxy 问题苦苦思索了很长时间,我希望这里有人之前已经遇到过这个问题。

以下是一些信息:

  1. 我们的 HAP 实例位于三个区域的 AWS 中
  2. 这些实例接收的唯一流量来自我们的客户
  3. 我们的每个客户都安装了 HAProxy,将其最终用户的请求分别通过 80 和 443 转发至 1025 和 1026。
  4. 这些请求通过代理协议通过 TCP 转发到我们的 HAP 实例。
  5. 然后,我们的 HAP 实例通过 SSL 传输请求并将其转发到端口 80 上的后端。
  6. 我们的路由都是在 Route53 内部通过健康检查完成的。
  7. 如果实例未能及时回复,这些健康检查将在 30 秒内进行三次,并将该实例标记为失败。检查每秒进行四次左右。

现在来看看问题:这些服务器时常会挂在 SSL 握手上,导致握手重置(在故障期间在 tcpdump 中发现此问题),从而导致健康检查挂起足够长的时间,导致故障。周末在 6 个实例中发生了约 450 次这种情况。

即使在握手过程中,内存和 CPU 的峰值也不会足以引起任何警报。 

以下是 HAP 实例的配置:

# HAProxy Config
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log         127.0.0.1 local2

    pidfile     /var/run/haproxy.pid
    maxconn     30000
    user        haproxy
    group       haproxy
    daemon
    ssl-default-bind-options no-sslv3 no-tls-tickets
    tune.ssl.default-dh-param 2048

# turn on stats unix socket
#    stats socket /var/lib/haproxy/stats`

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    retries                 3
    timeout http-request    5s
    timeout queue           1m
    timeout connect         31s
    timeout client          31s
    timeout server          31s
    maxconn                 15000

# Stats
    stats           enable
    stats uri           /haproxy?stats
    stats realm         Strictly\ Private
    stats auth          $StatsUser:$StatsPass

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------

frontend shared_incoming
    maxconn 15000
    timeout http-request 5s

#    Bind ports of incoming traffic
    bind *:1025 accept-proxy # http
    bind *:1026 accept-proxy ssl crt /path/to/default/ssl/cert.pem ssl crt /path/to/cert/folder/ # https
    bind *:1027 # Health checking port
    acl gs_texthtml url_reg \/gstext\.html    ## allow gs to do meta tag verififcation
    acl gs_user_agent hdr_sub(User-Agent) -i globalsign    ## allow gs to do meta tag verififcation

#      Add headers
    http-request set-header $Proxy-Header-Ip %[src]
    http-request set-header $Proxy-Header-Proto http if !{ ssl_fc }
    http-request set-header $Proxy-Header-Proto https if { ssl_fc }

#     Route traffic based on domain
    use_backend gs_verify if gs_texthtml or gs_user_agent    ## allow gs meta tag verification
    use_backend %[req.hdr(host),lower,map_dom(/path/to/map/file.map,unknown_domain)]

#     Drop unrecognized traffic
    default_backend unknown_domain

#---------------------------------------------------------------------
# Backends
#---------------------------------------------------------------------

backend server0  ## added to allow gs ssl meta tag verification
    reqrep ^GET\ /.*\ (HTTP/.*)    GET\ /GlobalSignVerification\ \1
    server server0_http server0.domain.com:80/GlobalSignVerification/

backend server1
    server server1_http server1.domain.net:80

backend server2
    server server2_http server2.domain.net:80

backend server3
    server server3_http server3.domain.net:80

backend server4
    server server4_http server4.domain.net:80

backend server5
    server server5_http server5.domain.net:80

backend server6
    server server6_http server6.domain.net:80

backend server7
    server server7_http server7.domain.net:80

backend server8
    server server8_http server8.domain.net:80

backend server9
    server server9_http server9.domain.net:80

backend unknown_domain
    timeout connect 4s
    timeout server 4s
    errorfile 503 /etc/haproxy-shared/errors/404.html

答案1

如果涉及 SSL,我会查看您的熵池——也许您已经用尽了它。密切关注“cat /proc/sys/kernel/random/entropy_avail”,看看当您发现问题时它是否下降到 0 左右。

(参考:https://major.io/2007/07/01/check-available-entropy-in-linux/

如果是这样,您可能需要考虑安装 rngd 来将内核已经执行的操作添加到池中。

相关内容