Contents

為什麼內網連内網對外 IP 會不通?淺談 NAT Loopback (Hairpin NAT) 運作原理

對於許多剛接觸網路架構或自建服務的工程師來說,設定 Port Forwarding (DNAT) 讓外部網路能夠存取內網的 Web 服務是家常便飯。然而,當我們嘗試「在內網環境中,直接透過外部 IP (Public IP) 連線到內網伺服器」時,卻常常會遇到一種詭異的現象:有些環境可以通,有些環境卻完全連不上。

最近這篇文章看到有人說這個問題。這讓我回想起自己的經驗:以前在家裡使用中華電信數據機加上 ASUS Router 時,設定好 DNAT 後,內網直接打 Public IP 就能無縫連上 Web 服務。但同樣的操作,在我朋友家那台企業級的 Fortigate 防火牆上卻行不通。

為什麼會有這樣的差異?答案其實藏在一個名為 NAT Loopback(或稱 Hairpin NAT、NAT Reflection)的路由器功能中。

缺乏 NAT Loopback 時,封包發生了什麼事?

要理解 NAT Loopback,我們先來看看「沒有」這個功能時,封包的流向會發生什麼致命的錯誤。

假設我們的網路環境如下:

  • Router WAN IP (外部 IP): 203.0.113.1
  • Router LAN IP (閘道器): 192.168.1.1
  • Web Server (內網伺服器): 192.168.1.20
  • Client (內網測試機): 192.168.1.10
  • Router 規則: 已設定 DNAT,將 203.0.113.1:80 導向 192.168.1.20:80

當內網的 Client (192.168.1.10) 嘗試連線到外部 IP (203.0.113.1) 時,流程如下:

  1. 發出請求: Client 送出封包,來源是 192.168.1.10,目的地是 203.0.113.1。因為目的地不是同網段,封包被送到 Default Gateway (Router)。
  2. Router 處理 DNAT: Router 收到封包,觸發了 DNAT 規則,將目的地 IP 改為 Web Server 的 192.168.1.20,並將封包從 LAN 介面丟給 Web Server。
  3. 非對稱路由的災難: Web Server 收到封包,看到來源 IP 是 Client 的 192.168.1.10。因為 Client 跟 Server 處於同一個內網網段,Server 在回覆時,不會將封包交還給 Router,而是透過 Layer 2 (MAC Address) 直接把回覆封包丟給 Client。
  4. 連線中斷: Client 送出請求給 203.0.113.1,卻收到來自 192.168.1.20 的回覆。對於 Client 的 TCP/IP 堆疊來說,這是一個未知的連線(這不是我要的對象!),於是直接把封包丟棄(Drop)或發送 TCP RST 終止連線。

結果就是:連線逾時,你看不到網頁。

技術解析:NAT Loopback 是如何拯救這一切的?

為了讓上述的封包能夠順利「有去有回」,路由器需要同時對這個封包做「兩次 NAT」處理,這個過程就像髮夾彎一樣(Hairpin),封包從 LAN 進來,又從 LAN 出去。

當 Router 有開啟 NAT Loopback 時,流程會變成這樣:

  1. 發出請求: Client (192.168.1.10) 請求 203.0.113.1
  2. Router 處理 DNAT + SNAT:
  • DNAT (目的地位址轉換): 將目的地 203.0.113.1 改為 192.168.1.20 (Web Server)。
  • SNAT (來源位址轉換): 同時,將來源 IP 192.168.1.10 改為 Router 自己的 LAN IP 192.168.1.1
  1. 伺服器回覆: Web Server 收到封包,這次它看到的來源 IP 是 Router (192.168.1.1)。因此,Web Server 會乖乖地把回覆封包交還給 Router。
  2. Router 解譯並回傳: Router 收到回覆後,反向解除剛剛的 SNAT 與 DNAT,將來源改回 203.0.113.1,目的地改回 192.168.1.10,然後傳給 Client。

Client 成功收到來自 203.0.113.1 的回覆,TCP Three-way Handshake 順利完成,Web 服務正常顯示!

設備哲學的差異:ASUS vs. Fortigate

了解原理後,就能解釋為什麼不同設備有不同結果了:

  • 家用路由器 (如 ASUS Router): 設計理念是「隨插即用、使用者體驗優先」。因此,這類設備通常在底層預設開啟 NAT Loopback 功能。對一般用戶來說,他們只管設定好 Port Forwarding,不管在內網還是外網輸入同一個 Domain Name 或 IP,都能無縫連上,這減少了極大的客服成本。
    ASUS Router預設是打開的,參考: [規格] 哪些華碩路由器型號支援NAT Loopback ? | 官方支援 | ASUS Hong Kong

  • 企業級防火牆 (如 Fortigate):
    設計理念是「預設拒絕 (Default Deny)、嚴格的安全控管」。Hairpin NAT 本質上是一種路由的「欺騙」與額外消耗設備資源的行為(流量明明不用出網關,卻硬要繞一圈做兩次 NAT)。因此,企業級防火牆預設通常是關閉此功能的。工程師必須手動撰寫明確的 Policy 或開啟 NAT Reflection 選項,允許這條流量通過。
    可參考: Hairpin NAT | FortiGate / FortiOS 8.0.0 | Fortinet Document Library

替代方案:除了 NAT Loopback 還能怎麼做?

雖然 NAT Loopback 很方便,但在大型網路環境中會增加 Router 的負載。比起讓內網流量硬繞去 Router 做轉換,更專業的做法是設定 Split DNS (內部 DNS 解析)。可以參考我研究這篇(Split DNS 架構整理與小實驗)文章。

透過架設內部 DNS Server (例如 AdGuard Home 或 Pi-hole):

  • 當你在外網查詢 web.example.com 時,公共 DNS 回傳 Public IP (203.0.113.1)。
  • 當你在內網查詢 web.example.com 時,內部 DNS 直接回傳 Server 的 LAN IP (192.168.1.20)。

這樣一來,內網的流量就會直接在 Layer 2 進行端對端通訊,完全不需要依賴 Router 的 NAT 轉換,不僅速度最快,也最節省網路資源。

參考資源

心智圖

mindmap root((NAT Loopback)) 問題情境 內網用公網 IP 連不通 根本原因:非對稱路由 NAT Loopback 運作原理 DNAT 目的地改為內網 IP SNAT 來源改為 Router LAN IP 設備哲學差異 家用路由器預設開啟 企業級防火牆預設關閉 替代方案 Split DNS 內網 DNS 直接解析內網 IP 不依賴 Router NAT