尝试使用HAProxy将请求转发给ELB的奇怪行为/错误

时间:2017-04-07 20:26:52

标签: ssl haproxy amazon-elb

我们的架构在多个主机上有多个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

1 个答案:

答案 0 :(得分:1)

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

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多次绑定到同一个套接字是有效的。