奇怪 behavior/error 尝试使用 HAProxy 将请求转发到 ELB

Weird behavior/error trying to use HAProxy to forward requests to ELBs

我们的架构在多个主机上有多个 API。每个 API 都位于一个 AWS ELB 后面。我们想在前面放置一个代理,它将根据 URI 将请求路由到 ELB。

到目前为止我所做的大部分工作,但大约十分之三的请求导致以下错误(使用 cURL,但问题不是 cURL):

curl: (35) Unknown SSL protocol error in connection to test-router.versal.com:-9847

我感觉ELB是罪魁祸首。 SSL 在那里终止。

这是我们的 HAProxy 配置:

global
  log 127.0.0.1   local0
  log 127.0.0.1   local1 notice
  maxconn 10240
  user haproxy
  group haproxy
  daemon
  debug
  stats socket /var/run/haproxy.sock
  log-send-hostname test-router.domain.com
  description "HAProxy on test-router.domain.com"

defaults
  log     global
  mode    http
  option  httplog
  option  dontlognull
  retries 3
  option redispatch
  option forwardfor
  option httpclose
  option dontlognull
  option tcpka
  maxconn 10240
  timeout connect 10000ms
  timeout client 600000ms
  timeout server 600000ms

frontend public
  bind *:80
  bind *:443
  acl elb0 path_beg /elb0
  acl elb1 path_beg /elb1
  use_backend elb0 if elb0
  use_backend elb1 if elb1

  bind 0.0.0.0:443 ssl crt /etc/ssl/cert.pem no-sslv3 ciphers AES128+EECDH:AES128+EDH

backend elb0
  server server_vcat elb0.domain.com:443 ssl verify none

backend elb1
  server server_laapi elb1.domain.com:443 ssl verify none

来自 curl 的 SSL 在 ELB 处终止。它在 HAProxy 处终止,在您的配置中...

bind 0.0.0.0:443 ssl crt /etc/ssl/cert.pem no-sslv3 ciphers AES128+EECDH:AES128+EDH

...然后 HAProxy 在与 ELB 的连接上建立了一个完全不同的 SSL 会话:

server ... ssl verify none

在此配置中,ELB 的 SSL 问题不可能通过 HAProxy 传播回 curl。

问题出在您的 HAProxy 配置中,此处:

bind *:443

删除该行。这是多余的(而且不正确)。

您两次告诉 HAProxy 绑定到端口 443:一次使用 SSL,一次使用 SSL。

因此,据统计,在大约 50% 的连接尝试中,curl 发现 HAProxy 没有在端口 443 上使用 SSL——它只是使用 HTTP,而 curl 不能(也不应该)优雅地处理它。

我相信这个(错误的)配置没有被 HAProxy 检测到,不是因为一个实际的错误,而是因为一些事情在 HAProxy 内部实现的方式,与多进程部署和热重载相关,在在这种情况下,将 HAProxy 多次绑定到同一个套接字是有效的。