奇怪 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 多次绑定到同一个套接字是有效的。
我们的架构在多个主机上有多个 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 多次绑定到同一个套接字是有效的。