NAT的完全分析及其UDP穿透的完全解決方案

NAT的完全分析及其UDP穿透的完全解決方案
 
一:基本術語
防火牆
防火牆限制了私網與公網的通信,它主要是將(防火牆)認爲未經授權的的包丟棄,防火牆只是檢驗包的數據,並不修改數據包中的IP地址和TCP/UDP端口信息。
網絡地址轉換(NAT)
當有數據包通過時,網絡地址轉換器不僅檢查包的信息,還要將包頭中的IP地址和端口信息進行修改。以使得處於NAT之後的機器共享幾個僅有的公網IP地址(通常是一個)。網絡地址轉換器主要有兩種類型.
P2P應用程序
P2P應用程序是指,在已有的一個公共服務器的基礎上,並分別利用自己的私有地址或者公有地址(或者兩者兼備)來建立一個端到端的會話通信。
P2P防火牆
P2P防火牆是一個提供了防火牆的功能的P2P代理,但是不進行地址轉換.
P2P-NAT
P2P-NAT 是一個 P2P代理,提供了NAT的功能,也提供了防火牆的功能,一個最簡的P2P代理必須具有錐形NAT對Udp通信支持的功能,並允許應用程序利用Udp打洞技術建立強健的P2P連接。
迴環轉換
NAT的私網內部機器想通過公共地址來訪問同一臺局域網內的機器的時,NAT設備等價於做了兩次NAT的事情,在包到達目標機器之前,先將私有地址轉換爲公網地址,然後再將公網地址轉換回私有地址。我們把具有上敘轉換功能的NAT設備叫做“迴環轉換”設備。
 
二:NAT分類
可以分爲基礎NAT網絡地址和端口轉換(NAPT)兩大類
(一):基礎NAT
基礎NAT 將私網主機的私有IP地址轉換成公網IP地址,但並不將TCP/UDP端口信息進行轉換。基礎NAT一般用在當NAT擁有很多公網IP地址的時候,它將公網IP地址與內部主機進行綁定,使得外部可以用公網IP地址訪問內部主機。(實際上是隻將IP轉換,192.168.0.23 <-> 210.42.106.35,這與直接設置IP地址爲公網IP還是有一定區別的,特別是對於企業來說,外部的信息都要經過統一防火牆才能到達內部,但是內部主機又可以使用公網IP)
(二):網絡地址和端口轉換 (NAPT)
這是最普遍的情況,網絡地址/端口轉換器檢查、修改包的IP地址和TCP/UDP端口信息,這樣,更多的內部主機就可以同時使用一個公網IP地址。
請參考[RFC1631]和[RFC2993]及[RFC2663]這三個文檔瞭解更多的NAT分類和術語信息。另外,關於NAPT的分類和術語,[RFC2663]做了更多的定義。當一個內部網主機通過NAT打開一個“外出”的TCP或UDP會話時,NAPT分配給這個會話一個公網IP和端口,用來接收外網的響應的數據包,並經過轉換通知內部網的主機。這樣做的效果是,NAPT[私有IP:私有端口][公網IP:公網端口]之間建立了一個端口綁定。
端口綁定指定了NAPT將在這個會話的生存期內進行地址轉換任務。這中間存在一個這樣的問題,如果P2P應用程序從內部網絡的一個[私有IP地址:端口]對同時發出多條會話給不同的外網主機,那麼NAT會怎樣處理呢?這又可以分爲錐形NAT (CONE NAT)對稱NAT (SYMMTRIC NAT)兩大類來考慮:
A.錐形NAT
(爲什麼叫做錐形呢?請看以下圖形,終端和外部服務器,都通過NAT分派的這個綁定地址對來傳送信息,就象一個漏斗一樣,篩選並傳遞信息)
                               
  當建立了一個 [私有IP:端口]-[公網IP:端口] 端口綁定之後,對於來自同一個[私有IP:端口]會話,錐形NAT服務器允許發起會話的應用程序 重複使用這個端口綁定,一直到這個會話結束才解除(端口綁定)。
  例如,假設 Client A(IP地址信息如上圖所示)通過一個錐形NAT 同時發起兩個外出的連接,它使用同一個內部端口(10.0.0.1:1234)給公網的兩臺不同的服務器,S1和S2。錐形NAT 只分配一個公網IP和端口(155.99.25.11:62000)給這個兩個會話,通過地址轉換可以確保 Client使用端口的“同一性”(即這個Client只使用這個端口)。而基礎NATs和防火牆卻不能修改經過的數據包端口號,它們可以看作是錐形NAT的精簡版本。
進一步分析可以將CONE NAT受限制錐形NAT (RESTRICT CONE)端口受限錐形NAT (PORT RESTRICT CONE) 三大類,以下是詳細論述: 分爲全雙工錐形NAT (FULL CONE) ,
1.全雙工錐形NAT
當內部主機發出一個“外出”的連接會話,就會創建了一個公網/私網 地址,一旦這個地址對被創建,全雙工錐形NAT會接收隨後任何外部端口傳入這個公共端口地址的通信。因此,全雙工錐形NAT有時候又被稱爲"混雜"NAT。
2.受限制錐形NAT
受限制的錐形NAT會對傳入的數據包進行篩選,當內部主機發出“外出”的會話時,NAT會記錄這個外部主機的IP地址信息,所以,也只有這些有記錄的外部IP地址,能夠將信息傳入到NAT內部,受限制的錐形NAT 有效的給防火牆提煉了篩選包的原則——即限定只給那些已知的外部地址“傳入”信息到NAT內部。
3.端口受限錐形NAT
端口受限制的錐形NAT,與受限制的錐形NAT不同的是:它同時記錄了外部主機的IP地址和端口信息,端口受限制的錐形NAT給內部節點提供了同一級別的保護,在維持端口“同一性”過程中,將會丟棄對稱NAT傳回的信息。
B.對稱NAT
對稱NAT,與Cone NAT是大不相同的,並不對會話進行端口綁定,而是分配一個全新的公網端口 給每一個新的會話。
還是上面那個例子:如果 Client A (10.0.0.1:1234)同時發起兩個 "外出" 會話,分別發往S1和S2。對稱Nat會分配公共地址155.99.25.11:62000給Session1,然後分配另一個不同的公共地址155.99.25.11:62001給Session2。對稱Nat能夠區別兩個不同的會話並進行地址轉換,因爲在 Session1 和 Session2中的外部地址是不同的,正是因爲這樣,Client端的應用程序就迷失在這個地址轉換邊界線了,因爲這個應用程序每發出一個會話都會使用一個新的端口,無法保障只使用同一個端口了。
TCP和UDP通信中,(到底是使用同一個端口,還是分配不同的端口給同一個應用程序),錐形NAT和對稱NAT各有各的理由。當然錐形NAT在根據如何公平地將NAT接受的連接直達一個已創建的地址對上有更多的分類。這個分類一般應用在Udp通信(而不是Tcp通信上),因爲NATs和防火牆阻止了試圖無條件傳入的TCP連接,除非明確設置NAT不這樣做。
三:NAT對session的處理
以下分析NAPT是依據什麼策略來判斷是否要爲一個請求發出的UDP數據包建立Session的.主要有一下幾個策略:
A. 源地址(內網IP地址)不同,忽略其它因素, 在NAPT上肯定對應不同的Session
B. 源地址(內網IP地址)相同,源端口不同,忽略其它的因素,則在NAPT上也肯定對應不同的Session
C. 源地址(內網IP地址)相同,源端口相同,目的地址(公網IP地址)相同,目的端口不同,則在NAPT上肯定對應同一個Session
D. 源地址(內網IP地址)相同,源端口相同,目的地址(公網IP地址)不同,忽略目的端口,則在NAPT上是如何處理Session的呢?
A,B,C三種情況的都是比較簡單的,可以很容易的實現.而D的情況就比較複雜了.所以D情況纔是我們要重點關心和討論的問題。
四:完全解決方案
以下針對四種SESSION與四種NAT的完全解決方案,爲了方便將使用以下縮寫形式:
C代表 CONE NAT
S代表SYMMETRIC NAT,
FC代表 FULL CONE NAT,
RC代表 RESTRICT CONE NAT,
PC 代表 PORT RESTRICT CONE NAT.
首先依據CLIENT (客戶)端在NAT後 的個數不同可以分爲兩大類:
TYPE ONE :一個在NAT後 + 一個在公網中.
這種情況下可以分爲兩大類:
A. S VS 公網:此種情況下,由於公網的地址在一個SESSION內是不變的,所以可以打洞是可以成功的.
B. C VS 公網: 與上面類似,這種情口下打洞是可以成功的.
TYPE TWO:兩個客戶都在NAT後面.
這種情況下也可以細分爲兩大類:
A. 其中一個NAT 是 S(SYMMETRIC NAT) 的,既:S VS C或者是S VS S .
下面論證這種情口下按照常規打洞是行不通的,在常規打洞中,所有的客戶首先登陸到一個服務器上去.服務器記錄下每個客戶的[公網IP:端口],然後在打洞過程中就使用這個記錄的值,然而對於S的NAT來說,它並不綁定[私網IP:端口][公網IP:端口]的映射.所以在不同的SESSION中,NAT將會重新分配一對[公網IP:端口].這樣一來對於S型的NAT來說打洞的[公網IP:端口]與登記在服務器上的[公網IP:端口]是不同的.而且也沒有辦法將打洞的[公網IP:端口]通知到另一個位於NAT下的客戶端, 所以打洞是不會成功的.然而如果另一個客戶端是在公網時,打洞是可以的.前面已經論證了這種情況.
這種情況下的解決方案是隻能通過端口預測來進行打洞,具體解決方法如下:例如(以兩個都是S型的爲例) NAT A 分配了它自己的UDP端口62000用來保持 客戶端A 服務器S的通信會話 NAT B 也分配了31000端口用來保持客戶端B服務器S 的通信會話通過與 服務器S的對話客戶端A 和 客戶端B都相互知道了對方所映射的真實IP和端口
  客戶端A發送一條UDP消息到138.76.29.7:31001(請注意到端口號的增加)同時客戶端B發送一條UDP消息到155.99.25.11:62001如果NAT A 和NAT B繼續分配端口給新的會話,並且從A-S和B-S的會話時間消耗得並不多的話,那麼一條處於客戶端A和客戶端B之間的雙向會話通道就建立了。
  客戶端A發出的消息送達B導致了NAT A打開了一個新的會話,並且我們希望NAT A將會指派62001端口給這個新的會話,因爲62001是繼62000NAT會自動指派給 從服務器S客戶端A之間的新會話的端口號;類似的,客戶端B發出的消息送達A導致了 NAT B打開了一個新的會話,並且我們希望 NAT B將會指派31001這個端口給新的會話;如果兩個客戶端都正確的猜測到了對方新會話被指派的端口號,那麼這個 客戶端A-客戶端B的雙向連接就被打通了。其結果如下圖所示:
明顯的,有許多因素會導致這個方法失敗:如果這個預言的新端口(62001和31001) 恰好已經被一個不相關的會話所使用,那麼NAT就會跳過這個端口號,這個連接就會宣告失敗;如果兩個NAT有時或者總是不按照順序來生成新的端口號,那麼這個方法也是行不通的
如果隱藏在NATA後的一個不同的客戶端X(或者在NAT B後)打開了一個新的“外出”UDP 連接,並且無論這個連接的目的如何;只要這個動作發生在客戶端A 建立了與服務器S的連接之後客戶端A 與 客戶端B 建立連接之前;那麼這個無關的客戶端X 就會趁人不備地“偷” 到這個我們渴望分配的端口。所以,這個方法變得如此脆弱而且不堪一擊,只要任何一個NAT方包含以上碰到的問題,這個方法都不會奏效。
在處於 cone NAT 系列的網絡環境中這個方法還是實用的;如果有一方爲 cone NAT 而另外一方爲 symmetric NAT,那麼應用程序就應該預先發現另外一方的 NAT 是什麼類型,再做出正確的行爲來處理通信,這樣就增大了算法的複雜度,並且降低了在真實網絡環境中的普適性。
    最後,如果P2P的一方處在兩級或者兩級以上的NAT下面,並且這些NATS 接近這個客戶端是SYMMETRIC NAT的話,端口號預言是無效的!
因此,並不推薦使用這個方法來寫新的P2P應用程序,這也是歷史的經驗和教訓!
B. 兩個都是CONE NAT型.
這種情況下可以分爲六大類型:
A: FC + FC
B: FC + RC
C: FC + PC
D: PC + RC
E: PC + PC
F: RC + RC
雖然有這麼多種情況,但是由於CONE NAT 的特性,所以還是很好辦的,因爲對於CONE NAT 來說,在同一個SESSION中它會綁定一對[私網IP:端口][公網IP:端口]的映射,所以它們打洞用的[公網IP:端口]與登記在服務器上的[公網IP:端口]是一致的,所以打洞是可以行的通的.
綜上所述,就已經完全的概括了所有類型的NAT之間的可能的通信情況了.並且都提供了可行的解決方案.
五:對前一階段的總結
1.前一階段使用的打洞方法是有缺陷的,它只適應於兩個都是FULL CONE NAT的類型的CLIENT(客戶端).以下論證它不適應於兩個都是CONE NAT的類型中的
B: FC + RC
C: FC + PC
D: PC + RC
E: PC + PC
F: RC + RC
這五種情況.
因爲對於受限的NAT它登記了外出包的[IP地址&端口],它僅僅接受這些已登記地址發過來的包,所以它們報告服務器的端口只能接受來自服務器的包.不能接受來自另一客戶端的包.所以前一階段的打洞方法是不可行的.
六: 存在的問題
按照理論.NAT將在一定時間後關閉UDP的一個映射,所以爲了保持與服務器能夠一直通信,服務器必須要發送UDP心跳包,來保持映射不被關閉.這就需要一個合適的時間值.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章