我正在分析应用程序中的间歇性负载平衡失败。
以前,我们一直在使用以下configuration中的AWS Elastic Load Balancer:
HTTP 80 -> HTTP 80 HTTPS 443 -> HTTPS 443, presenting the same certificate as the backend IIS servers are
现在我们意识到这是一个发脾气的设置(LB和IIS服务器做同样的encryption……浪费了工作),现在开始给我们带来一些问题。 具体来说,我们会间歇性地看到ELB请求的延迟时间,完整的60秒(默认超时),然后向客户端报告一个错误。 我们花了很多时间来确认延迟峰值与应用程序中的处理延迟无关。
如前所述,我们现在认识到这个设置很奇怪。 例如,ELB更自然的configuration工作得很好:
HTTP 80 -> HTTP 80 TCP 443 -> TCP 443, straight passthrough, all encryption happening on the IIS backend
缩小了一会儿,我们很好奇,如果我们可以重现在HAProxy的坏configuration间歇性故障。 这是HAProxy做SSL终止,然后启动另一个完整的SSL连接到后端服务器。 我们再一次意识到这是愚蠢的,但是正在研究比较ELB和HAProxy的黑盒子。
这是我尝试的简单configuration:
frontend https_frontend bind *:443 ssl crt /etc/ssl/certs/ourpublicandprivatecert.pem mode http default_backend web_server backend web_server mode http server s1 10.0.1.4:443 check
然后当浏览到HAProxy主机时,我们得到:
504 Gateway Time-out The server didn't respond in time.
我猜测HAProxy对于证书上的不匹配感到害怕,但我无法获得日志来证实这一点。 另一种可能是,因为这是一个奇怪的设置(混合SSL终止和直通)HAProxy只是不支持它,而不是迫使你更直接的直通或终止path。
任何人有任何见解?
当然你有一个最近版本的HAProxy,内置了OpenSSL支持。
看来你需要一些额外的参数来使用HTTPS后端。 HAProxy默认尝试正常的HTTP连接,不pipe端口号如何。
ssl参数确保SSL连接:
server s1 10.0.1.4:443 ssl check check-ssl
服务器证书没有被默认validation。 如果你想validation它,你需要添加verify required和ca-file <cafile>到服务器行。
有关这些选项的更多信息,请访问http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#5.2
我认为你的后端configuration有一个错误。 改为:
frontend https_frontend bind *:443 ssl crt /etc/ssl/certs/ourpublicandprivatecert.pem mode http default_backend web_server backend web_server mode http server s1 10.0.1.4:80 check
不断变化的港口! 同时也要确保你的networking服务器没有从80端口redirect到443端口,否则会造成混淆。
使用haproxy或ELB来执行SSL终止的一个好处是,它可以插入诸如X-Forwarded-For的头文件。
如果仅仅使用tcp选项传递SSL而不在ELB或HAProxy上执行SSL,则无法插入标题,因为stream是encryption的。 因此,Web服务器无法对请求进行智能化处理,Web服务器日志中的所有客户端连接都将看起来像来自elb或haproxy服务器IP!
所以,不要将encryption委托给后端,而是在ELB或HAProxy实例上完成,并使用X-Forwarded-For。