我的 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
- 指令。據我了解,這意味著偵聽伺服器應該支援來自我們的負載平衡器的代理協定訊息。
SSL 連線問題
但是我無法建立 SSL 連線。我可以理解,這在伺服器 B 上是不可能的(因為客戶端不使用 PROXY 協定),但我認為在伺服器 A 上應該可以。如果我嘗試連接,我會收到以下回應:
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 進行連接,我認為(或者也許更多的是我希望的)它一定是我所缺少的非常簡單的東西。有誰知道我做錯了什麼或錯過了什麼?