send-proxy vs send-proxy-v2 vs send-proxy-v2-ssl --1
下面我严格按你的要求结构来,不跳步、不混概念:
-
先对比
send-proxy / send-proxy-v2 / send-proxy-v2-ssl(结合你的场景) -
明确在 LVS TOA → HAProxy → Nginx 的正确选择
-
给出一套“能跑、不会踩坑、支持 TLS 透传 + HTTP/2”的完整配置
-
HAProxy
-
Nginx
stream -
Nginx
http
-
一、先对比三种 send-proxy(放在你的架构里看)
你的架构前提:
-
LVS 使用 TOA(真实源 IP 已在 TCP option 中)
-
HAProxy / Nginx 不依赖 TOA
-
TLS 必须透传
-
HTTP/2 必须支持
-
TLS 在 Nginx 终止
1️⃣ 能力对比表(结合 TLS 透传 & HTTP/2)
| 项目 | send-proxy | send-proxy-v2 | send-proxy-v2-ssl |
|---|---|---|---|
| PROXY 协议版本 | v1 | v2 | v2 |
| 编码方式 | 明文 | 二进制 | 二进制 |
| 客户端 IP | ✅ | ✅ | ✅ |
| IPv6 | ⚠️ 有限 | ✅ | ✅ |
| 性能 | 一般 | 高 | 高 |
| TLS 是否使用 | ❌ | ❌ | ✅ |
| TLS 版本 | ❌ | ❌ | ✅ |
| SNI | ❌ | ❌ | ✅ |
| ALPN / HTTP2 判断 | ❌ | ❌ | ✅ |
| TLS 透传 | ❌ | ⚠️ 不完整 | ✅ |
| HTTP/2 | ❌ | ⚠️ 易异常 | ✅ |
| 生产推荐 | ❌ | ⚠️ | ✅ |
2️⃣ 在你这个场景里的结论(非常明确)
LVS TOA + HAProxy TCP + TLS 透传 + HTTP/2 + Nginx 终止 TLS
✔ 只能用:send-proxy-v2-ssl
❌ 另外两个都会在 TLS / HTTP2 / SNI 上出问题
二、为什么 TLS 透传 + HTTP/2 必须是 send-proxy-v2-ssl
一句话解释:
HTTP/2 是跑在 TLS 之上的,而 TLS 透传时,后端只能靠 SSL TLV 判断“这是 HTTPS + h2”
没有 SSL TLV 会发生什么
-
Nginx
stream层:-
不知道是不是 SSL
-
ssl_preread信息不完整
-
-
Nginx
http层:-
HTTP/2 协议判断异常
-
日志 / real_ip 错乱
-
mTLS / 策略无法用
-
三、完整正确配置(可直接用)
下面是一整套标准生产写法。
1️⃣ HAProxy 配置(RS 机器上)
特点
-
TCP 模式
-
不解 TLS
-
注入 PROXY v2 + SSL TLV
global
log /dev/log local0
maxconn 200000
defaults
log global
mode tcp
timeout connect 5s
timeout client 1m
timeout server 1m
frontend ft_tls_passthrough
bind *:443
mode tcp
default_backend bk_nginx_tls
backend bk_nginx_tls
mode tcp
server nginx 127.0.0.1:443 send-proxy-v2-ssl
2️⃣ Nginx:stream 层(TLS 透传 + PROXY)
职责
-
接收 PROXY v2
-
接收 TLS 原始流
-
不解密 TLS
-
读取 SNI / TLS 信息
-
转交给 http 层
stream {
log_format stream_log
'$remote_addr:$remote_port '
'sni=$ssl_preread_server_name '
'protocol=$protocol';
server {
listen 443 proxy_protocol;
proxy_protocol on;
ssl_preread on;
proxy_pass 127.0.0.1:8443;
}
}
关键点解释
-
proxy_protocol on;
→ 接收 HAProxy 注入的 PROXY v2 / SSL TLV -
ssl_preread on;
→ 读取 SNI / TLS 信息(不解密)
3️⃣ Nginx:http 层(TLS 终止 + HTTP/2)
职责
-
终止 TLS
-
提供 HTTP/2
-
使用真实客户端 IP
http {
real_ip_header proxy_protocol;
set_real_ip_from 127.0.0.1;
log_format main
'$remote_addr - $host [$time_local] '
'"$request" $status $body_bytes_sent';
server {
listen 8443 ssl http2 proxy_protocol;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
proxy_pass http://backend_app;
}
}
}
关键点解释
-
listen ... ssl http2 proxy_protocol; -
HTTP/2 必须在 TLS 终止点
-
real_ip_header proxy_protocol;
→ 客户端真实 IP 生效
四、TOA 在这里的地位(避免误解)
LVS TOA 只影响 LVS → HAProxy
一旦 HAProxy 建立新连接到 Nginx:
-
TOA 已经不存在
-
必须靠 PROXY protocol 继续传递客户端信息
所以你这个链路里:
Client IP
↓ (TOA)
HAProxy
↓ (PROXY v2 + SSL TLV)
Nginx
五、最终一句话总结(架构级)
-
send-proxy:历史遗留,不适合 TLS / HTTP2
-
send-proxy-v2:仅适合非 TLS 或 TLS 已终止
-
send-proxy-v2-ssl:
👉 TLS 透传 + HTTP/2 + SNI + 真实 IP 的唯一正确选择
如果你愿意,我可以下一步帮你做:
-
LVS TOA + HAProxy + Nginx 的抓包验证方法
-
HTTP/2 / ALPN / SNI 是否生效的检查清单
-
stream → http 的多域名 SNI 分流方案
你现在问的,已经是七层负载与传输层边界的高级问题了。
浙公网安备 33010602011771号