我在使用我们的 NGINX 负载均衡器(基于流模块)和最终用户的真实远程 IP 时遇到了问题。
情况
我们的情况包括很多服务器,但相关的服务器有两台:
- 服务器 A -> 使用流模块运行 NGINX 的负载均衡器
- 服务器 B -> 上游运行 NGINX 反向代理到我们的相关应用程序,负责 SSL 终止
服务器 A 使用 SNI 路由到各种上游(使用ssl_preread on
)。
我认为我们希望实现以下的情况:
Client ---[HTTPS]---> NGINX LB ---[PROXY PROTOCOL]---> NGINX Reverse proxy incl. SSL-termination ---[HTTP]---> PHP-container
配置
针对这种特定情况,我向我们的流添加了一个具有不同端口的附加服务器块,以便能够与其他一些项目一起测试它。服务器 A 上的相关配置位:
stream {
server {
listen 4431;
listen [::]:4431;
ssl_preread on;
proxy_pass 172.16.25.4:4431;
proxy_protocol on;
}
}
可以看出,端口 4431 转发到我们端口 4431 上的上游,因此proxy_protocol on
这里应该使用代理协议。
在我们的服务器 B(上游172.16.25.4
)上,我有另一个 NGINX 实例,其配置如下:
server {
server_name <REDACTED>;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header x-forwarded-proto https;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Real-IP $proxy_protocol_addr;
}
listen 4431 ssl proxy_protocol;
ssl_certificate /etc/letsencrypt/live/<REDACTED>/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<REDACTED>/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
您会看到另一个监听端口 4431,带有ssl
和proxy_protocol
指令。据我所知,这意味着监听服务器应该支持来自我们的负载均衡器的 PROXY 协议消息。
SSL 连接问题
但是我无法建立 SSL 连接。我知道从服务器 B 无法建立 SSL 连接(因为客户端不使用 PROXY 协议),但我认为从服务器 A 可以建立 SSL 连接。如果我尝试连接,我会收到以下响应:
user@ServerA $ openssl s_client -connect 127.0.0.1:4431 -servername <REDACTED>
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
我不明白为什么我无法使用 SSL 从我们的负载均衡器进行连接,我想(或者也许我更希望如此)一定是我遗漏了一些非常简单的东西。有谁知道我做错了什么或遗漏了什么?