轉自:http://alexanderlaw.blog.hexun.com/31883661_d.html
1. NAT 的劃分
RFC3489 中將 NAT 的實現分爲四大類:
1. Full Cone NAT 完全錐形 NAT
2. Restricted Cone NAT 限制錐形 NAT (可以理解爲 IP 限制)
3. Port Restricted Cone NAT 端口限制錐形 NAT ( IP+Port 限制)
4. Symmetric NAT 對稱 NAT
其中完全錐形的穿透性最好,而對稱形的安全性最高
1.1 錐形NAT與對稱NAT的區別
所謂錐形NAT 是指:只要是從同一個內部地址和端口出來的包,無論目的地址是否相同,NAT 都將它轉換成同一個外部地址和端口。
“同一個外部地址和端口”與“無論目的地址是否相同”形成了一個類似錐形的網絡結構,也是這一名稱的由來。
反過來,不滿足這一條件的即爲對稱NAT 。
1.2 舉例說明
假設:
NAT 內的主機 A : IP 記爲 A ,使用端口 1000
NAT 網關 : IP 記爲 NAT ,用於 NAT 的端口池假設爲( 5001-5999 )
公網上的主機 B : IP 記爲B ,開放端口 2000
公網上的主機 C : IP 記爲C ,開放端口 3000
假設主機 A 先後訪問主機 B 和 C
1 )如果是錐形 NAT :
那麼成功連接後,狀態必然如下:
A ( 1000 ) —— > NAT ( 5001 )—— > B ( 2000 )
A ( 1000 ) —— > NAT ( 5001 )—— > C ( 3000 )
也就是說,只要是從 A 主機的 1000 端口發出的包,經過地址轉換後的源端口一定相同。
2 )如果是對稱形 NAT :
連接後,狀態有可能(注意是可能,不是一定)如下:
A ( 1000 ) —— > NAT ( 5001 )—— > B ( 2000 )
A ( 1000 ) —— > NAT ( 5002 )—— > C ( 3000 )
兩者的區別顯而易見。
1.3 三種CONE NAT之間的區別
仍然以上面的網絡環境爲例, 假設 A 先與 B 建立了連接:
A ( 1000 ) —— > NAT ( 5001 )——— > B ( 2000 )
1) Port Restricted Cone NAT:
只有 B ( 2000 )發往 NAT ( 5001 )的數據包可以到達 A ( 1000 )
===========================================================
B ( 2000 ) —— > NAT ( 5001 ) ——— > A ( 1000 )
B ( 3000 ) —— > NAT ( 5001 ) — X — > A ( 1000 )
C ( 2000 ) —— > NAT ( 5001 ) — X — > A ( 1000 )
2) Restricted Cone NAT
只要是從 B 主機發往 NAT ( 5001 )的數據包都可以到達 A ( 1000 )
==========================================================
B ( 2000 ) —— > NAT ( 5001 ) ——— > A ( 1000 )
B ( 3000 ) —— > NAT ( 5001 ) ——— > A ( 1000 )
C ( 2000 ) —— > NAT ( 5001 ) — X — > A ( 1000 )
3) Full Cone NAT
任意地址發往 NAT ( 5001 )的數據包都可以到達 A ( 1000 )
==========================================================
B ( 2000 ) —— > NAT ( 5001 ) ——— > A ( 1000 )
B ( 3000 ) —— > NAT ( 5001 ) ——— > A ( 1000 )
C ( 3000 ) —— > NAT ( 5001 ) ——— > A ( 1000 )
2. Linux的NAT
Linux的NAT“MASQUERADE”屬於對稱形NAT。
說明這一點只需要否定 MASQUERADE 爲錐形 NAT 即可。
Linux 在進行地址轉換時,會遵循兩個原則:
儘量不去修改源端口,也就是說,ip 僞裝後的源端口儘可能保持不變。
更爲重要的是,ip 僞裝後必須 保證僞裝後的源地址/ 端口與目標地址/ 端口(即所謂的socket )唯一。
假設如下的情況( 內網有主機 A 和 D ,公網有主機 B 和 C ):
先後 建立如下三條連接:
A ( 1000 ) —— > NAT ( 1000 )—— > B ( 2000 )
D ( 1000 ) —— > NAT ( 1000 )—— > C ( 2000 )
A ( 1000 ) —— > NAT ( 1001 )—— > C ( 2000 )
可以看到,前兩條連接遵循了原則 1 ,並且不違背原則 2
而第三條連接爲了避免與第二條產生相同的 socket 而改變了源端口
比較第一和第三條連接,同樣來自 A(1000) 的數據包在經過 NAT 後源端口分別變爲了 1000 和 1001。說明 Linux 的 NAT 是對稱 NAT 。
3. 對協議的支持
CONENAT 要求原始源地址端口相同的數據包經過地址轉換後,新源地址和端口也相同,換句話說,原始源地址端口不同的數據包,轉換後的源地址和端口也一定不同。
那麼,是不是 Full Cone NAT 的可穿透性一定比 Symmetric NAT 要好呢,或者說,通過 Symmetric NAT 可以建立的連接,如果換成 Full Cone NAT 是不是也一定能成功呢?
假設如下的情況:
(內網有主機A和D,公網有主機B和C,某 UDP 協議服務端口爲 2000 ,並且要求客戶端的源端口一定爲 1000 。 )
1)如果A使用該協議訪問B:
A ( 1000 ) —— > NAT ( 1000 )——— > B ( 2000 )
由於 Linux 有儘量不改變源端口的規則,因此在 1000 端口未被佔用時,連接是可以正常建立的
如果此時D也需要訪問B:
D ( 1000 ) —— > NAT ( 1001 )—X— > B ( 2000 )
端口必須要改變了,否則將出現兩個相同的 socket ,後續由 B(2000) 發往NAT( 1000 )的包將不知道是轉發給A還是D。
於是B將因爲客戶端的源端口錯誤而拒絕連接。
在這種情況下, MASQUERADE 與 CONENAT 的表現相同。
2)如果A連接B後,D也像C發起連接,而在此之後,A又向C發起連接
① A ( 1000 ) —— > NAT ( 1000 )——— > B ( 2000 )
如果是 MASQUERADE :
② D ( 1000 ) —— > NAT ( 1000 )——— > C ( 2000 )
③ A ( 1000 ) —— > NAT ( 1001 )—X— > C ( 2000 )
如果是 CONENAT :
② D ( 1000 ) —— > NAT ( 1001 )—X— > C ( 2000 )
③ A ( 1000 ) —— > NAT ( 1000 )——— > C ( 2000 )
對於 MASQUERADE 來說,只要在沒有重複的 socket 的情況下,總是堅持儘量不改變源端口的原則,因此第二條連接仍然採用源端口 1000 ,而第三條連接爲了避免重複的 socket 而改變了端口。
對於 CONENAT ,爲了保證所有來自 A(1000) 的數據包均被轉換爲 NAT(1000) ,因此 D 在向 C 發起連接時,即使不會產生重複的 socket ,但因爲 NAT 的 1000 端口已經被 A(1000) “佔用”了,只好使用新的端口。
可以看出,不同的 target 產生不同的結果。我們也不能絕對的說,在任何時候,全錐形 NAT 的可穿透性都比對稱 NAT 要好,比如上面的例子,如果只存在連接①和②,顯然是對稱形 NAT 要更適用。
因此,選擇哪種 NAT ,除了對網絡安全和普遍的可穿透性的考慮外,有時還需要根據具體應用來決定。