如何使用透明套接字設定 Nginx?

如何使用透明套接字設定 Nginx?

類似Cloudflare 部落格文章,我正在嘗試使用透明套接字設定 Nginx(使用IP_TRANSPARENT插座選項)。我想這樣做是為了實作一個有效綁定到所有連接埠的反向 TCP 代理程式。

套接字IP_TRANSPARENT選項是本身不支持透過 Nginx 進行監聽,所以我嘗試使用建立套接字Systemd 套接字單元然後使用以下命令將其傳遞給 Nginx 進程NGINX環境變數

插座單元如下(不重要的線已去掉):

[Socket]
ListenStream=127.0.0.1:1234
Transparent=true

[Install]
WantedBy=sockets.target

我的Nginx服務單元如下(不重要的行已被刪除):

[Service]
# Configure Nginx to use the socket inherited from Systemd
Environment=NGINX=3;
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf

我的nginx.conf如下(不重要的行已被刪除,並且upstream是我要代理的上游主機的主機名稱):

stream {
    server {
        proxy_pass upstream:443
        listen 127.0.0.1:1234;
    }
}

Nginx 運行在 GCP 計算實例上內部直通負載平衡器IP 位址為 10.11.12.13,因此我新增了以下 iptables 規則以將流量重新導向至透明通訊端:

iptables -t mangle -I PREROUTING -d 10.11.12.13/32 -p tcp -j TPROXY --on-port=1234 --on-ip=127.0.0.1

如上所述這裡,GCP 為負載平衡器安裝本機路由,因此無需自行執行此操作。換句話說,以下命令返回RTNETLINK answers: File exists

ip route add local 10.11.12.13/32 dev lo src 127.0.0.1

但是,以下curl指令掛起:

curl https://10.11.12.13

從curl的角度來看,TCP連線正在正確建立,但是當追蹤Nginx工作進程時,它似乎掛在系統accept4呼叫上。

tcpdump從執行 Nginx 的執行個體執行顯示以下內容:

15.59.51.564902 IP [REDACTED].50028 > 10.11.12.13.443: Flags [S], seq 3519046460, win 65535, options [mss 1320,nop,wscale 6,nop,nop,TS val 3905128064 ecr 0,sackOK,eol], length 0
15.59.51.564973 IP 10.11.12.13.443 > [REDACTED].50028: Flags [S.], seq 2512605282, ack 3519046461, win 28400, options [mss 1420,nop,nop,sackOK,nop,wscale 7], length 0
15.59.51.601898 IP [REDACTED].50028 > 10.11.12.13.443: Flags [.], ack 1, win 4096, length 0
15.59.51.601898 IP [REDACTED].50028 > 10.11.12.13.443: Flags [P.], seq 1:370, ack 1, win 4096, length 369
15.59.51.601898 IP 10.11.12.13.443 > [REDACTED].50028: Flags [.], ack 370, win 231, length 0

據我了解,這意味著客戶端正在發送數據,伺服器正在確認它,但隨後客戶端不再發送任何數據,大概是因為它期待來自伺服器的回應,但它沒有收到。因此,我懷疑Nginx只是忽略了客戶端發送的資料。

我希望我已經提供了足夠的背景來理解這個問題。我不太確定從這裡到哪裡去,或者我想做的事情是否有根本性的錯誤。任何幫助將不勝感激。

答案1

我找到了解決方案這裡這是在 Nginx 服務單元上設定以下選項:

[Service]
NonBlocking=true

據推測,Nginx 假設在建立偵聽套接字時設定了此選項,因此如果 Systemd 向其傳遞未設定此選項的套接字,則無法讀取資料。

相關內容