關於iptables NAT的一個問題

考慮這樣一個情況: 某台設備擁有公網IP A.B.C.D,同時作為OpenVPN客戶端連接到IP為E.F.G.H的OpenVPN服務器,並且設置route將OpenVPN服務器作為本機的默認網關(本地設備和OpenVPN服務器上都配置了ip forwarding和iptables MASQUERADE/SNAT)。 當這台設備主動連接Internet上的某個IP I.J.K.M時,I.J.K.M所看到的訪問請求來源是E.F.G.H,而它發送給E.F.G.H的響應reverse SNAT後被轉發給A.B.C.D,完成了一次雙向通信。 而如果是I.J.K.M主動連接A.B.C.D的某個開放的端口昵?A.B.C.D響應的數據包,根據route規則,會通過OpenVPN的tun設備發送。問題是,這個響應的數據包是否會做SNAT(將source地址由A.B.C.D改為本機分配到的OpenVPN客戶端私有地址)? 如果有做DNAT,那麼I.J.K.M就不可能收到「A.B.C.D」發來的響應,會話建立失敗。如果沒有DNAT,那麼I.J.K.M可以正確地收到A.B.C.D的響應並且建立會話,只是整個過程中A.B.C.D發給I.J.K.M方向的數據包會經過E.F.G.H中轉一次。 I.J.K.M主動連接A.B.C.D的數據包connection state是NEW;而A.B.C.D響應的數據包state應該是ESTABLISHED。我不知道iptables對這種情況是否會做NAT。 Update: 只有會話中的第一個數據包會通過iptables nat表。所以這種connection已經建立的情況下應該不會再對響應數據包NAT,我做了一個實驗,證實了這點。 如果A.B.C.D是一個家庭網關上的路由器,而I.J.K.M是通過A.B.C.D主動連接家庭內網某台機器(路由器上開啟了端口映射),那麼情況會有所不同。這時I.K.J.M發送的數據包在A.B.C.D上已經做了DNAT,則內網機器響應的數據包在A.B.C.D上自動reverse DNAT並通過OpenVPN的tun接口發送,不會再進行SNAT。

Continue reading