0%

【踩坑記】NAT Loopback

前言

使用RouterOS架設自己的私人網路篇最後有提到在過程中有遇到的兩個小坑,這篇主要先來分享關於NAT Loopback的問題。這個問題主要會發生在從內網裝置透過路由器外部IP存取透過設定Dst NAT規則所轉發的內網相關服務連線上,需要更改一下路由器上NAT相關的設定便可解決。

問題

該問題叫做NAT Loopback(又稱作NAT Hairpin),可以參考Mikrotik官網的說明,上面也有相關的介紹以及解決辦法。

如同前言所說,這個問題主要會發生在從內網裝置透過路由器外部IP存取透過設定Dst NAT規則所轉發的內網相關服務連線上。那麼,成因是什麼呢?

我們用圖片以追蹤封包的方式來為大家解說。

假設我們用內網10.30.9.70的主機想要透過外網140.115.52.22的5000連接埠連接一個在內網10.30.9.77的網頁伺服器,而路由器上已經設定好Dst NAT的規則,其他網際網路上的主機皆可正常訪問該網頁伺服器。

以下為目前路由器關於5000連接埠的所有相關設定,

上圖為允許路由器對從WAN連線5000連接埠的所有封包進行轉發的規則設定,這將使從WAN進來的連線能夠被順利的轉發到LAN上連接內網的網頁伺服器

上圖為將對路由器上收到目標地址是外網IP並連接5000連接埠的封包進行目標地址改寫的Dst NAT規則設定,符合規則的封包其目標地址將會被改寫成10.30.9.77:5000

我們從內網主機開始發送封包開始看起,

一開始,10.30.9.70會發送一個目的地是140.115.52.22、連接埠是5000的封包出去。而因為140.115.52.22為外網IP,不在內網遮罩的範圍內,故此封包會送給路由器處理。

上圖為10.30.9.70發送一個目的地是140.115.52.22、連接埠是5000的封包給路由器路由之示意圖

接著,路由器收到此封包後,由於路由器有設定對目標地址是外網IP並連接5000連接埠的封包進行目標地址改寫的Dst NAT規則設定,此封包會被進行目標地址改寫,原為140.115.52.22的目標IP將被改寫成10.30.9.77。

上圖為路由器對目標地址是外網IP並連接5000連接埠的封包進行目標地址改寫之示意圖

再來,此封包會從路由器送到內網的網頁伺服器上進行處理。

上圖為路由器將封包送到內網的網頁伺服器上進行處理之示意圖

最後,內網的網頁伺服器傳送回應來回應發出請求的人。

上圖為內網的網頁伺服器回應請求之示意圖

看完上面的封包追蹤,相信大家已經看出問題發生在哪裡了。

沒錯,問題就是發生在內網的網頁伺服器傳送回應的這個過程上。

由於網頁伺服器或任何服務在收到封包後,皆是回應封包上所記載的來源地址。這時來源地址為內網IP的封包經過路由器改寫了目標地址後,來源地址仍然還是內網IP。便會發生網頁伺服器在收到封包後,回應將直接透過內網IP傳送回發出請求的電腦。

但是這時發出請求的電腦原本是使用目標地址為外網IP的封包發出請求,此時電腦會期望該連線的回應是從外網IP回來。但現在的情況是回應的封包是從內網回來,該封包便會被發出請求的電腦當作無效的封包直接丟棄,自然連線上就會發生連線逾時的情況。

解決

解決的辦法便是在路由器增加一條Src NAT的規則,對從內網IP來、目標地址為內網IP的封包做IP Masquerade,將來源IP偽裝成路由器IP,回應則由路由器來轉送回發出請求的電腦,便可解決該問題。

上圖為解決NAT Loopback之IP Masquerade規則