這是一個關(guān)于網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)和應(yīng)用層代理工作層級差異的經(jīng)典問題。根本原因在于 數(shù)據(jù)包處理發(fā)生的網(wǎng)絡(luò)層級不同 以及 誰真正發(fā)起了到內(nèi)部Web服務(wù)器的TCP連接。
讓我們分解一下原因:
?? 1. 路由器端口轉(zhuǎn)發(fā)(DNAT)的工作原理(保留真實IP)
工作層級: 網(wǎng)絡(luò)層(IP層)或傳輸層(TCP/UDP層)。
過程:
外網(wǎng)訪客發(fā)送一個數(shù)據(jù)包到路由器的公網(wǎng)IP地址(假設(shè)是 WAN_IP:80
)。
路由器檢查其端口轉(zhuǎn)發(fā)(Destination NAT, DNAT)規(guī)則,發(fā)現(xiàn)目標(biāo)端口 80
需要轉(zhuǎn)發(fā)到內(nèi)網(wǎng)服務(wù)器 LAN_SERVER_IP:80
。
Web服務(wù)器視角: Web服務(wù)器看到這個TCP連接的源IP地址就是外網(wǎng)訪客的真實公網(wǎng)IP。因為從Web服務(wù)器的角度看,這個連接直接來自那個公網(wǎng)IP(雖然經(jīng)過了路由器修改目標(biāo)地址,但源地址沒變)。
連接建立者: 從Web服務(wù)器的TCP棧角度看,連接是外網(wǎng)訪客直接發(fā)起的(源IP是訪客IP)。路由器只是在中間修改了目標(biāo)地址,沒有中斷這個連接。
?? 2. Porttunnel 類軟件端口映射(通常是反向代理)的工作原理(顯示Porttunnel內(nèi)網(wǎng)IP)
工作層級: 應(yīng)用層(通常是HTTP層,但也可以是其他應(yīng)用層協(xié)議)。
過程:
關(guān)鍵操作: Porttunnel軟件創(chuàng)建一個全新的、獨立的TCP連接,從它自己(PORTTUNNEL_LAN_IP
)指向內(nèi)部Web服務(wù)器(LAN_SERVER_IP:80
)。
Porttunnel軟件將訪客發(fā)來的數(shù)據(jù)讀取出來,然后通過它自己新建的這個連接轉(zhuǎn)發(fā)給Web服務(wù)器。同樣地,它也會把Web服務(wù)器的響應(yīng)讀出來,通過它接收到的訪客連接發(fā)送回去。
Web服務(wù)器視角: Web服務(wù)器看到的這個TCP連接的源IP地址是運行Porttunnel軟件的電腦的內(nèi)網(wǎng)IP地址(PORTTUNNEL_LAN_IP
)。因為從Web服務(wù)器的角度看,這個連接是Porttunnel軟件自己主動發(fā)起的。
連接建立者: Web服務(wù)器的TCP棧確認(rèn)連接是由 PORTTUNNEL_LAN_IP
發(fā)起的。原始的訪客連接只到達了Porttunnel軟件,并未直接到達Web服務(wù)器。Porttunnel軟件充當(dāng)了中間人(代理)的角色。
?? 總結(jié)關(guān)鍵差異
特性 | 路由器端口轉(zhuǎn)發(fā) (DNAT) | Porttunnel類軟件 (應(yīng)用層代理/反向代理) |
---|
工作層級 | 網(wǎng)絡(luò)層/傳輸層 (IP/TCP頭修改) | 應(yīng)用層 (處理應(yīng)用數(shù)據(jù)) |
連接處理 | 修改原始數(shù)據(jù)包目標(biāo)地址,透傳連接 | 終結(jié)原始連接,新建到服務(wù)器的連接 |
源IP可見性 | Web服務(wù)器看到訪客真實公網(wǎng)IP | Web服務(wù)器看到Porttunnel主機的內(nèi)網(wǎng)IP |
本質(zhì) | 網(wǎng)絡(luò)地址轉(zhuǎn)換 (NAT) | 應(yīng)用層代理/反向代理 |
?? 為什么Porttunnel不保留源IP?(技術(shù)難點)
TCP連接狀態(tài): TCP是一個有狀態(tài)的協(xié)議。當(dāng)Porttunnel終結(jié)了訪客的連接,那個連接的狀態(tài)就結(jié)束了。它需要一個新的TCP連接狀態(tài)機來與后端服務(wù)器通信。
應(yīng)用層協(xié)議理解(可選但常見): 像Porttunnel這樣的工具,特別是配置為HTTP端口映射時,通常會理解HTTP協(xié)議。這使得它們能夠添加像 X-Forwarded-For
這樣的頭(見下文解決方案),但核心的TCP連接源IP仍然只能是Porttunnel本身的IP。
防火墻/NAT限制: 如果Porttunnel運行在Windows上,它本身可能位于另一個NAT設(shè)備(如家用路由器)后面,它甚至沒有公網(wǎng)IP來接收連接(除非做了端口映射到它),更不用說將原始源IP直接路由到內(nèi)部服務(wù)器了。
?? 如何在Porttunnel場景下獲取真實IP?(解決方案)
既然Web服務(wù)器只能看到Porttunnel的IP,要獲取真實訪客IP,必須依賴應(yīng)用層協(xié)議傳遞信息:
X-Forwarded-For
HTTP Header: 這是最通用的方法。配置Porttunnel(或任何反向代理,如Nginx, Apache, HAProxy)在新建到后端Web服務(wù)器的連接時,在HTTP請求頭中添加一個 X-Forwarded-For
頭,其值設(shè)置為原始訪客的IP地址。Web服務(wù)器應(yīng)用程序(如Apache, Nginx, IIS, 應(yīng)用代碼)需要配置為讀取并信任這個頭(來自已知代理的IP),并用這個頭的值來記錄或處理訪客IP,而不是使用TCP連接的源IP。
代理協(xié)議(Proxy Protocol): 這是一個更底層的標(biāo)準(zhǔn)(最初由HAProxy提出),在TCP連接建立之初,代理服務(wù)器就在發(fā)送應(yīng)用數(shù)據(jù)之前,先發(fā)送一行包含原始連接信息的文本(包括源IP/端口、目標(biāo)IP/端口)。Web服務(wù)器需要明確支持并配置理解Proxy Protocol。它不依賴于特定的應(yīng)用層協(xié)議(如HTTP),但需要代理和后端服務(wù)器都支持。
Windows防火墻日志(間接/不推薦): 如果Porttunnel運行在Windows上,且Windows防火墻記錄了傳入連接,你可能在防火墻日志中找到原始IP和Porttunnel收到的連接。但這非常不便于集成到Web日志中,且依賴防火墻配置。
?? 結(jié)論
路由器端口轉(zhuǎn)發(fā)工作在底層(網(wǎng)絡(luò)層),通過簡單的目標(biāo)地址修改直接透傳連接,使Web服務(wù)器能看到原始源IP。Porttunnel等軟件工作在應(yīng)用層,作為代理終結(jié)客戶端連接并新建服務(wù)器端連接,因此Web服務(wù)器看到的是代理自身的IP地址。要獲取真實IP,必須使用應(yīng)用層機制如 X-Forwarded-For
頭或Proxy Protocol。理解這個差異對于正確配置日志記錄、訪問控制和安全分析至關(guān)重要。???
相關(guān)教程:
?
采用端口轉(zhuǎn)向軟件映射到局域網(wǎng)內(nèi)的另外一臺WEB服務(wù)器時,利用Nginx實現(xiàn)抓取訪客真實外網(wǎng)IP[
2]
http://31874.oa22.cn
該文章在 2025/6/27 12:05:44 編輯過