我需要将 HTTPS 流从 HAProxy 重定向到 Nginx,无需 SSL 终止,也不会丢失有关原始客户端 IP 的信息。不幸的是,我无法更改 Nginx 上默认 443 站点的配置,因为它由 Synology NAS 配置维护。
我正在考虑在 Nginx 上设置新的监听端口,接受来自 HAProxy 的代理协议,并将内部重定向到本地 443 端口,无需 SSL 解码/编码,但传递从 HAProxy 获取的原始客户端 IP。这可能吗?
编辑: 背景是我在同一个外部 443 端口上建立了 OpenVPN 和 Web 服务的隧道,因此实际上它看起来如下所示:
router 443 TCP -> HAProxy -> SNI check -> stunnel -> OpenVPN
|
------> SSL termination -> Nginx 443 HTTPS
我使用 HAProxy,因为 ngx_stream_ssl_preread_module 在 Synology 的内置 Nginx 上不可用。
编辑:我认为情况和问题可以更加通用:
Nginx:
port X accessed via proxy protocol with SSL/TLS
port Y
如何使用源客户端 IP 信息将流从端口 X 传递到 Y,而无需 SSL 终止?在端口 Y 上使用 proxy_protocol 的 listen 指令是唯一可行的选择吗?
答案1
是的,您可以使用 nginx 完成上述操作。
一个简单的谷歌搜索揭示了listen
自 1.5.12 版本以来,指令有一个proxy_protocol
参数,出于安全原因,该参数可能应与set_real_ip_from
指示:
请注意,这将不可避免地需要对您提到的第三方工具维护的 nginx 配置进行最少的修改;出于明显的安全原因,如果不进行任何此类修改,就不可能传递客户端 IP 信息。
此外,请注意,你实际上并不需要HAProxynginx 中的新流功能已经允许您对 TCP 和 SSL 流进行操作,包括从最新版本开始,基于 SNI(服务器名称指示)区分未打开的 SSL 流的功能 — 请参阅ssl_preread
以及相应的$ssl_preread_server_name
自 1.11.5 起。
答案2
一个可能的解决方案是SSL 桥接使用 HAProxy。这意味着 HAProxy 将:
1. 解密 SSL 连接。2
. 插入 X-Real-IP 标头。3
. 与 Nginx 通信时再次加密连接。
解密 SSL 连接需要 HAProxy 以 HTTP 模式运行,但同时 HAProxy 应该接收来自同一 443 端口的隧道流量。所以我能想到的解决方案是首先通过虚拟后端分割两个流量。
当然,这会带来额外的性能成本,但如果负载不是很高,则不会引人注意。
frontend ft_ssl
bind *:443
mode tcp
acl web_traffic req_ssl_sni -i <web-domain>
acl stunnel_traffic req_ssl_sni -i <stunnel-domain>
use_backend bk_ssl_dummy if web_traffic
use_backend bk_ssl_stunnel if stunnel_traffic
backend bk_ssl_stunnel
mode tcp
server stunnel1 <IP>:<PORT> check
backend bk_ssl_dummy
mode tcp
server web_ssl_offload 127.0.0.1:8888 send-proxy-v2-ssl-cn check
frontend ft_web_offload
bind 127.0.0:8888 ssl crt <path-to-crt> accept-proxy
mode http
http-request set-header X-Real-IP %[src]
default_backend bk_ssl_nginx
backend bk_ssl_nginx
mode http
server nginx1 <sIP>:443 ssl check
由于我们使用安全套接字服务器行中的参数。
配置 Nginx 以使用代理协议将使您拥有更加简单的 HAProxy 配置,因此仅当您无法更改 Nginx 配置时,此解决方案才有意义。