我可以使用 HAProxy 将 SSL 传递到与其他虚拟主机共享 IP 的虚拟主机吗?
我尝试
frontend https
bind *:443 #ssl
mode tcp
default_backend port_443
backend port_443
mode tcp
server web42 www.example.com
但我看到的是默认的网络服务器,而不是 www.example.com
我可以在前端执行 SNI,但如何向后端传达 - 这是针对域名 www.example.com 的?
server web1 www.example.com:443 sni str(www.example.com) verify none
也不起作用。
为了清楚起见,Web 服务器 www.default.com、www.example.com、www.example.net 都具有相同的 IP 和端口,例如 10.0.1.10:443 Apache/ngix 使用 SNI 选择正确的 vhost。
问题仍然没有解决。以下是一些图表
--------------------
|(All 10.0.1.10:443)
www2.example.com:443 -> HaProxy ->|www.default.com <- Apache vhost default
|www.example.com
|www.example.net
--------------------
我想要访问 www.example.com (使用 tcp 模式)
如果我有 www.example.com 和 www.example.net 的私钥。我是否可以访问 www.example.net(当用户输入 www.example.com 时)而不会出现安全问题?
答案1
您可以将连接传递到您想要的任何后端服务器/端口。
但我发现您的设置中缺少很多东西。
这是我自己的 HAProxy 设置,我用它将必须共享全局 IPv4 地址的 https 连接转发到所有具有唯一全局 IPv6(和唯一私有 IPv4)的后端服务器。
frontend https
bind :443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend goren_example_com if { req_ssl_sni -i awx.example.com }
use_backend goren_example_com if { req_ssl_sni -i goren.example.com }
use_backend goren_example_com if { req_ssl_sni -i tower.example.com }
backend goren_example_com
server goren 192.168.101.182:443 send-proxy-v2
请注意,我在这里进行 SNI 检查,并匹配 SNI 主机名以确定将连接发送到哪个后端。
然后我send-proxy-v2
使用PROXY 协议在后端连接上。这将让我告诉后端连接起源的 IP 地址。我们使用此协议是因为X-Forwarded-For
在此设置中不可能。
但是 PROXY 协议确实需要后端服务器知道这一点。要实现这一点,需要对我的 nginx 设置进行一些小的更改,即:
listen 443 ssl http2 proxy_protocol;
listen [::]:443 ssl http2;
set_real_ip_from 192.168.101.1;
real_ip_header proxy_protocol;
proxy_protocol
通过在listen
和中指定real_ip_header
,nginx 现在知道通过 PROXY 协议获取客户端的真实 IP 地址。(请注意,我没有在 IPv6 侦听器上使用它,因为我只通过 haproxy 代理 IPv4 连接。IPv6 连接直接进入,不需要代理。这是 IPv6 的一大优势。)
最后,旧版本的 nginx 使用 PROXY 协议的第 1 版,因此如果send-proxy-v2
不起作用haproxy.cfg
,则需要将其更改为send-proxy
。
(如果你仍在使用 Apache,请设置RemoteIPProxyProtocol on
。
答案2
这是不可能的。HAProxy 在 tcp 模式下会忽略每个 sni str(www.example.com)。(我认为 sni str() 用于终止并再次加密 SSL)但在 tcp 模式下,当客户端调用 www.example.com 时,您将访问 www.example.com,而不是默认服务器。我真正的问题是无法使用 www2.example.com 进行测试。(这是一个生产环境,所以我无法测试它)