iptables與stun Stun協議(Rfc3489、詳見http://www.ietf.org/rfc/rfc3489.txt)將NAT粗略分為4種類型,即Full Cone、Restricted Cone、Port Restricted Cone和Symmetric。舉個實際例子(例1)來說明這四種NAT的區別: A機器在私網(192.168.0.4) NAT服務器(210.21.12.140) B機器在公網(210.15.27.166) C機器在公網(210.15.27.140) 現在,A機器連接過B機器,假設是 A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:8000)-> B(210.15.27.166:2000)。 同時A從來沒有和C通信過。 則對於不同類型的NAT,有下列不同的結果: Full Cone NAT:C發數據到210.21.12.140:8000,NAT會將數據包送到A(192.168.0.4:5000)。因為NAT上已經有了192.168.0.4:5000到210.21.12.140:8000的映射。 Restricted Cone:C無法和A通信,因為A從來沒有和C通信過,NAT將拒絕C試圖與A連接的動作。但B可以通過210.21.12.140:8000與A的192.168.0.4:5000通信,且這裡B可以使用任何端口與A通信。如:210.15.27.166:2001 -> 210.21.12.140:8000,NAT會送到A的5000端口上。 Port Restricted Cone:C無法與A通信,因為A從來沒有和C通信過。而B也只能用它的210.15.27.166:2000與A的192.168.0.4:5000通信,因為A也從來沒有和B的其他端口通信過。該類型NAT是端口受限的。 Symmetric NAT:上面3種類型,統稱為Cone NAT,有一個共同點:只要是從同一個內部地址和端口出來的包,NAT都將它轉換成同一個外部地址和端口。但是Symmetric有點不同,具體表現在:只要是從同一個內部地址和端口出來,且到同一個外部目標地址和端口,則NAT也都將它轉換成同一個外部地址和端口。但如果從同一個內部地址和端口出來,是到另一個外部目標地址和端口,則NAT將使用不同的映射,轉換成不同的端口(外部地址只有一個,故不變)。而且和Port Restricted Cone一樣,只有曾經收到過內部地址發來包的外部地址,才能通過NAT映射後的地址向該內部地址發包。 現針對Symmetric NAT舉例說明(例2): A機器連接過B機器,假使是 A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:8000)-> B(210.15.27.166:2000) 如果此時A機器(192.168.0.4:5000)還想連接C機器(210.15.27.140:2000),則NAT上產生一個新的映射,對應的轉換可能為A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:8001)-> C(210.15.27.140:2000)。此時,B只能用它的210.15.27.166:2000通過NAT的210.21.12.140:8000與A的192.168.0.4:5000通信, C也只能用它的210.15.27.140:2000通過NAT的210.21.12.140:8001與A的192.168.0.4:5000通信,而B或者C的其他端口則均不能和A的192.168.0.4:5000通信。 通過上面的例子,我們清楚了Stun協議對NAT進行分類的依據。那麼,我們現在根據上述分類標准(或例子),來簡要分析一下iptables的工作原理,看看他又是屬於哪種NAT呢? 首先,我們去網上下載一個使用Stun協議檢測NAT的工具,網址在http://sourceforge.net/projects/stun/,使用該工具對iptables的檢測結果是Port restricted NAT detected。 我們先不要急著接受這個檢測結果,還是先來分析一下iptables的工作原理吧! iptables在轉換地址時,遵循如下兩個原則: 1、盡量不去修改源端口,也就是說,ip偽裝後的源端口盡可能保持不變。 2、更為重要的是,ip偽裝後只需保證偽裝後的源地址/端口與目標地址/端口(即所謂的socket)唯一即可。 仍以前例說明如下(例3): A機器連接過B機器,假使是 A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:5000)-> B(210.15.27.166:2000)。(注意,此處NAT遵循原則1、故轉換後端口沒有改變) 如果此時A機器(192.168.0.4:5000)還想連接C機器(210.15.27.140:2000),則NAT上產生一個新的映射,但對應的轉換仍然有可能為A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:5000)-> C(210.15.27.140:2000)。這是因為NAT(轉換後210.21.12.140:5000)-> B(210.15.27.166:2000)和NAT(轉換後210.21.12.140:5000)-> C(210.15.27.140:2000)這兩個socket不重復。因此,對於iptables來說,這既是允許的(第2條原則)、也是必然的(第1條原則)。 在該例中,表面上看起來iptables似乎不屬於Symmetric NAT,因為它看起來不符合Symmetric NAT的要求:如果從同一個內部地址和端口出來,是到另一個目標地址和端口,則NAT將使用不同的映射,轉換成不同的端口(外部地址只有一個,故不變)。相反,倒是符合除Symmetric NAT外的三種Cone NAT的要求:從同一個內部地址和端口出來的包,NAT都將它轉換成同一個外部地址和端口。加上iptables具有端口受限的屬性(這一點不容置疑,後面舉反例證明之),所以好多檢測工具就把iptables報告為Port restricted NAT類型了。 下面仍以前例接著分析(例4): 在前例中增加D機器在A同一私網(192.168.0.5) A機器連接過B機器,假使是 A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:5000)-> B(210.15.27.166:2000) D機器連接過C機器,假使是 D(192.168.0.5:5000)-> NAT(轉換後210.21.12.140:5000)-> C(210.15.27.140:2000) 由iptables轉換原則可知,上述兩個轉換是允許且必然的。 如果此時A機器(192.168.0.4:5000)還想連接C機器(210.15.27.140:2000),則NAT上產生一個新的映射,但對應的轉換則變為A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:5001)-> C(210.15.27.140:2000)。這是因為,如果仍然將其轉換為210.21.12.140:5000的話,則其所構成的socket(210.21.12.140:5000->210.15.27.140:2000)將和D->C的socket一致,產生沖突,不符合iptables的第2條原則(注意,此處以5001表示轉換後不同的端口,但事實上,iptables卻並不按照內部端口+1的原則來產生新的端口)。在本例中我們注意到,從同一個內部地址和端口A(192.168.0.4:5000)出來,到不同的目標地址和端口,則NAT使用了不同的映射,轉換成不同的端口。 上面這個例子在實際環境中比較少見,我們再以QQ為例舉一個真實且常見的例子(例5)。
假設 A(192.168.0.4)和 D(192.168.0.5)是同一NAT服務器(210.21.12.140)保護的兩台私網機器,都運行了QQ客戶端程序。 B機器在公網(210.15.27.166),運行QQ服務器程序。 C機器在公網(210.15.27.140),運行QQ客戶端程序。 A上QQ先登陸到B,按照原則1,使用如下映射: A(192.168.0.4:4000)-> NAT(轉換後210.21.12.140:4000)-> B(210.15.27.166:8000)(原則1,端口不變) 接著D上QQ也登陸到B,按照原則2,使用如下映射: D(192.168.0.5:4000)-> NAT(轉換後210.21.12.140:4001)-> C(210.15.27.166:8000)(原則2,scoket不能有重復,此處4001僅表示轉換後不同的端口,實際環境中決不是4001) 然後D欲和公網C(210.15.27.140)上的QQ通信,按照iptables轉換原則,使用如下映射: D(192.168.0.5:4000)-> NAT(轉換後210.21.12.140:4000)-> C(210.15.27.140:4000) 到此我們發現,和上例一樣,從同一個內部地址和端口D(192.168.0.5:4000)出來,到不同的目標地址和端口,則NAT使用了不同的映射,轉換成不同的端口。但和上例不一樣的是,本例顯然普遍存在於實際環境中。 上面所舉兩例表明,結論剛好和例3相反,即iptables應該屬於Symmetric NAT。 為什麼會出現彼此矛盾的情況呢?首先從NAT分類的定義上來看, Stun協議和iptables對映射的理解不同。Stun協議認為,一個映射的要素是:內部地址端口和NAT轉換後地址端口的組合。而在iptables看來,一個映射的要素是:NAT轉換後地址端口和外部目標地址端口的組合。另一方面則是Stun協議裡Discovery Process給出的測試環境不夠全面之故,他只考慮了NAT後面僅有一台私網機器的特例(例3),沒有考慮NAT後面可以有多台私網機器的普遍例子(例5)。正是由於這兩個原因,直接導致了上述矛盾的發生。所以,凡按照Stun協議標准設計的NAT分類檢測工具對iptables的檢測結果必然是Port restricted NAT。(事實上,在例3那樣的特例下,iptables確實是一個標准的Port restricted NAT) 那麼,iptables究竟屬於哪種NAT呢?我們再來回顧一下Stun協議對Cone NAT的要求:所有(或只要是)從同一個內部地址和端口出來的包,NAT都將它轉換成同一個外部地址和端口。雖然iptables在部分情況下滿足“從同一個內部地址和端口出來的包,都將把他轉換成同一個外部地址和端口”這一要求,但它不能在所有情況下滿足這一要求。所以理論上,我們就只能把iptables歸為Symmetric NAT了。 下面,我們再來分析一下iptables的端口受限的屬性,我們舉一個反例證明之(例6),仍以前例說明如下: A機器連接過B機器,假使是 A(192.168.0.4:5000)-> NAT(轉換後210.21.12.140:5000)-> B(210.15.27.166:2000) D機器連接過C機器,假使是 D(192.168.0.5:5000)-> NAT(轉換後210.21.12.140:5000)-> C(210.15.27.140:2000) 現假設iptables不具有端口受限的屬性,則另一E機器在公網(210.15.27.153:2000)或C(210.15.27.140:2001)向210.21.12.140:5000發包的話,應該能夠發到內部機器上。但事實是,當這個包到達NAT(210.21.12.140:5000)時,NAT將不知道把這個包發給A(192.168.0.4:5000)還是D(192.168.0.5:5000)。顯然,該包只能丟棄,至此,足以證明iptables具有端口受限的屬性。 所以,iptables是貨真價實的Symmetric NAT。
附: 1、Stun全稱Simpl