Apache ProxyPass HTTPS 和带 SNI 的远程服务器

Apache ProxyPass HTTPS and remote server with SNI

我想在 Apache 中使用反向代理来前置 AWS APIGateway URL。原因是由于一个过程需要一个静态 IP 来在严格的防火墙后面提供服务,并且当前的基础设施已经 mod_proxy 到位。我要实施的解决方案是简单地通过 mod_proxy.

路由 https->https(apiGateway)

但是.. AWS 使用 SNI,我无法 mod_proxy 握手。

我启用了以下设置

<IfModule mod_ssl.c>
<VirtualHost *:443>
  ProxyPreserveHost On
  SSLProxyEngine On

  ProxyPass /api/1_0/ https://xxx.execute-api.eu-west-1.amazonaws.com/1_0/
  ProxyPassReverse /api/1_0/ https://xxx.execute-api.eu-west-1.amazonaws.com/1_0/

以下日志在调试模式下可用

proxy_util.c(2020): AH00942: HTTPS: has acquired connection for (xxx.execute-api.eu-west-1.amazonaws.com)
proxy_util.c(2610): AH00962: HTTPS: connection complete to 52.x.x.x:443 (xxx.execute-api.eu-west-1.amazonaws.com)
AH01964: Connection to child 0 established (server domain.com:443)
AH02003: SSL Proxy connect failed
SSL Library Error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
AH01998: Connection closed to child 0 with abortive shutdown (server domain.com:443)
AH01997: SSL handshake failed: sending 502

如果我使用 openssl 连接,我会出现类似的错误

openssl s_client -tls1_2 -connect xxx.execute-api.eu-west-
1.amazonaws.com:443
CONNECTED(00000003)
140735866254216:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert 
handshake failure:s3_pkt.c:1494:SSL alert number 40
140735866254216:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:

为 SNI 添加 -servername,导致有效连接

SSL handshake has read 3601 bytes and written 489 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
...

因此我认为 mod_proxy 和 mod_ssl 没有将服务器名发送到远程 https 服务器,这可能是一个错误。

我 运行 Ubuntu 14.04 服务器版本:Apache/2.4.7 (Ubuntu) 服务器构建:2017 年 9 月 18 日 16:37:54 OpenSSL 1.0.1f 2014 年 1 月 6 日

我试图将 SSLProxyProtocol 和密码列表限制为 TLS1_2,但是不管怎样,sslv3 警报握手失败日志仍然存在。

有没有人遇到过这个并且知道如何确保发送 SNI 值,或者这是 Apache 模块中的限制?

这是因为 ProxyPreserveHost On 在配置的早期设置。 在代理标记下设置 ProxyPreserveHost Off 按预期完成:

<Proxy "https://xxx.execute-api.eu-west-1.amazonaws.com/1_0">
    ProxyAddHeaders off
    ProxyPreserveHost off
</Proxy>

指令信息:

When enabled, this option will pass the Host: line from the incoming request to the proxied host, instead of the hostname specified in the ProxyPass line.

This option should normally be turned Off. It is mostly useful in special configurations like proxied mass name-based virtual hosting, where the original Host header needs to be evaluated by the backend server.