[英]Nginx real client IP to TCP stream backend
我正在嘗試使用 Nginx 作為我的 TCP 守護程序的代理,使 Nginx 成為 SSL/TLS 前端以及負載控制。
我的后端應用程序需要真正的客戶端 IP,這是一個問題。
stream {
server {
listen 3333;
proxy_pass 127.0.0.1:2222;
}
}
我在文檔中找到了一種解決方案:
proxy_bind $remote_addr transparent;
但這太復雜了:
“為了使此參數起作用,需要以超級用戶權限運行 nginx 工作進程並配置 kernel 路由表以攔截來自代理服務器的網絡流量。”
還有其他方法可以將 $remote_addr 傳遞給后端嗎?
我嘗試使用 sub_filter 修改客戶端消息正文,發送 http 標頭等。但不幸的是,所有這些只能在 http 上下文中使用,不適用於 stream。
我的設置:
我的要求:在 access.log 中擁有真正的客戶端 ip(而不是來自 stream 模塊的 127.0.0.1)並且還用於地理封鎖
我的解決方案:
對於地理封鎖,您還必須使用 proxy_protocol_addr,但為了簡短起見,我將省略此處的描述。
nginx.conf:
...
stream {
upstream ssh {
server 127.0.0.1:2222;
}
upstream https {
server 127.0.0.1:444;
}
map $ssl_preread_protocol $upstream {
default ssh;
"TLSv1.2" https;
"TLSv1.3" https;
"TLSv1.1" https;
"TLSv1.0" https;
}
server {
listen 443;
proxy_pass $upstream;
proxy_protocol on;
ssl_preread on;
}
server {
listen 2222 proxy_protocol;
proxy_pass 192.168.2.76:22;
}
}
http {
log_format main '$proxy_protocol_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
...
server {
listen 444 ssl proxy_protocol;
...
}
}
“set_real_ip_from”指令應該是邊緣設備的地址/ CIDR
stream {
server {
listen 3333 proxy_protocol;
proxy_pass 127.0.0.1:2222;
proxy_protocol on;
set_real_ip_from 10.0.0.0/8;
}
}
據我所知,只有兩個解決方案: proxy_bind
和proxy_protocol
。
正如您從文檔中引用的那樣,工作流程將需要超級用戶權限。 明顯。 這不是最好的做法。 此外,它可能會導致連接問題回到遠程客戶端。
假設Nginx作為nginx
用戶運行,請運行此命令為其授予權限。
usermod -aG sudo nginx
此解決方案要求上游目標(例如后端應用程序)接受PROXY協議。
stream {
server {
listen 3333;
proxy_pass 127.0.0.1:2222;
proxy_protocol on;
}
}
上述解決方案假設Nginx服務器是網絡的入口點。 如果存在邊緣設備(例如負載平衡器),則很可能正在更改源IP。 在這種情況下,您需要在邊緣設備上啟用代理協議 ,並在server
塊中啟用proxy_protocol
偵聽器。 我還沒有測試過,但這樣的事情應該可行。
stream {
server {
listen 3333 proxy_protocol;
proxy_pass 127.0.0.1:2222;
proxy_protocol on;
set_real_ip_from $proxy_protocol_addr;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.