在Apache负载均衡器和后端之间使用Https

我正在使用一个配置为负载均衡器的Apache(2.4)服务器,位于两个Apache服务器的前面。当我在负载均衡器和后端之间使用HTTP连接时,它工作正常,但是使用HTTPS时却无法正常工作。 负载均衡器的配置如下:
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
<Proxy balancer://testcluster>
  BalancerMember https://[Backend1]:443/test
  BalancerMember https://[Backend2]:443/test
</Proxy>
ProxyPass /test balancer://testcluster

目前后端只有自签名证书,这就是为什么证书验证被禁用的原因。
负载均衡器上的错误日志包含以下内容:
[proxy:error] [pid 31202:tid 140325875570432] (502)Unknown error 502: [client ...] AH01084: pass request body failed to [Backend1]:443 ([Backend1])
[proxy:error] [pid 31202:tid 140325875570432] [client ...] AH00898: Error during SSL Handshake with remote server returned by /test/test.jsp
[proxy_http:error] [pid 31202:tid 140325875570432] [client ...] AH01097: pass request body failed to [Backend1]:443 ([Backend1]) from [...] ()

浏览器中的错误页面包含:
Proxy Error

The proxy server could not handle the request GET /test/test.jsp.
Reason: Error during SSL Handshake with remote server

如我在上面已经提到的,将配置更改为http协议和端口80是有效的。此外,客户端和负载均衡器之间的https连接也可以正常工作,因此负载均衡器的ssl模块似乎已经正确设置。
直接通过https连接到后端也没有出现任何错误。
非常感谢您的时间。
编辑: 我找到了解决方法,问题是我的证书的通用名称与服务器名称不匹配。我以为SSLProxyVerify none会忽略这个不匹配,但实际上并不会。在apache 2.4.5之前,可以使用SSLProxyCheckPeerCN off来禁用此检查,但在较高版本(我使用的是2.4.7)中,还需要指定SSLProxyCheckPeerName offApache文档中关于sslproxycheckpeername的链接 有效的配置如下所示:
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

<Proxy balancer://testcluster>
  BalancerMember https://[backend1]:443/test
  BalancerMember https://[backend1]:443/test
</Proxy>
ProxyPass /test balancer://testcluster

很不幸,由于声望不足,我无法回答自己的问题,所以我编辑了我的问题。 希望这能帮助到遇到类似问题的任何人。

有趣。我以前用apache2.2做这个,从来不需要设置SSLProxyVerify为none,也从未遇到过自签名证书的问题。你确定后端服务器没问题吗? - ETL
@ETL 我不知道是否需要“SSLProxyVerify none”,我只是希望通过添加这个来解决问题。在负载均衡服务器上调用“wget https://[backend1]/test/test.jsp --no-check-certificate”可以下载到预期的文件。 ng - user3240383
3个回答

问题最终发现是证书的公共名称与服务器名称不匹配。
在Apache 2.4.5之前,可以使用SSLProxyCheckPeerCN off来禁用此检查,但在较高版本(如2.4.7)中,还需要指定SSLProxyCheckPeerName offApache文档中关于SSLProxyCheckPeerName的说明 有效的配置如下:
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

<Proxy balancer://testcluster>
  BalancerMember https://[backend1]:443/test
  BalancerMember https://[backend1]:443/test
</Proxy>
ProxyPass /test balancer://testcluster

您可以使用以下方法检查您所拥有的Apache版本
apachectl -V

和/或

apache2ctl -V

嘿,我有完全相同的问题,只是配置有点不同: <Location /margin-tool> ProxyPass https://xxxx.thoughtworks.net:8443/margin-tool ProxyPassReverse https://xxxx.thoughtworks.net:8443/margin-tool </Location> 相同的设置不起作用。有什么想法吗? - user157735
由于类似的错误,我来到了这里。在我的特定情况下,解决方法是使用负载均衡器成员的DNS名称而不是IP地址。现在通用名称与证书上的名称匹配,所以Apache可以正确处理它--无需使用SSLProxyVerify、SSLProxyCheckPeer...等元素,这些元素是上述答案所需的。 - David Fackler

以下添加解决了问题。
SSLProxyProtocol +TLSv1

8提供神秘的配置示例并不是一个高质量的答案。从互联网上复制粘贴字符串也不是一个专业的系统管理员所做的事情。解释它,说明它的作用和原因。 - peterh
在使用Java12时遇到了这个问题 - 除此之外,这个解决方案还解决了我的问题... - womd

我使用Apache 2.4.9,并将以下代码添加到httpd-ssl.conf文件中
SSLProxyProtocol +SSLv3 +TLSv1 +TLSv1.1
我已经解决了这些问题

3听说过POODLE吗?应该禁用SSLv3。 - Sven
3SSLv3存在漏洞。 - insider