我们的架构在多个主机上有多个API。每个API都位于AWS ELB后面。我们希望在前面放置一个代理,将基于URI的请求路由到ELB。
到目前为止我所做的大部分都有效,但是大约有10个请求会导致以下错误(使用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
答案 0 :(得分:1)
来自curl的SSL
server ... ssl verify none
...然后HAProxy在与ELB的连接上建立了完全不同的SSL会话:
bind *:443
在此配置中,ELB的SSL问题无法通过HAProxy传播回卷曲。
问题在于您的HAProxy配置,此处:
// don't provide keys to reducers that don't supply them
const filterReducer = (reducer) => {
let lastState = undefined;
return (state, action) => {
if (lastState === undefined || state == undefined) {
lastState = reducer(state, action);
return lastState;
}
var filteredState = {};
Object.keys(lastState).forEach( (key) => {
filteredState[key] = state[key];
});
var newState = reducer(filteredState, action);
lastState = newState;
return newState;
};
}
删除该行。这是多余的(也是不正确的)。
你告诉HAProxy绑定到端口443两次:一次说SSL,一次不说SSL。
因此,从统计上来说,在大约50%的连接尝试中,curl发现HAProxy没有在端口443上说SSL - 它只是说HTTP,并且curl不能(也不应该)优雅地处理它。
我相信HAProxy不会检测到这个(错误的)配置,不是因为实际的错误,而是因为HAProxy内部实现了一些事情,与多进程部署和热重新加载有关,在这种情况下让HAProxy多次绑定到同一个套接字是有效的。