NAT路由器打洞原理

什麼是打洞,爲何要打洞html

因爲Internet的快速發展 IPV4地址不夠用,不能每一個主機分到一個公網IP 因此使用NAT地址轉換。服務器

下面是我在網上找到的一副圖網絡

 

通常來講都是由私網內主機(例如上圖中「電腦A-01」)主動發起鏈接,數據包通過NAT地址轉換後送給公網上的服務器(例如上圖中的「Server」),鏈接創建之後可雙向傳送數據,NAT設備容許私網內主機主動向公網內主機發送數據,但卻禁止反方向的主動傳遞,但在一些特殊的場合須要不一樣私網內的主機進行互聯(例如P2P軟件、網絡會議、視頻傳輸等),TCP穿越NAT的問題必須解決。併發

 

下面是NAT的幾種類型spa

NAT設備的類型對於TCP穿越NAT,有着十分重要的影響,根據端口映射方式,NAT可分爲以下4類,前3種NAT類型可統稱爲cone類型。
(1)全克隆( Full Cone) : NAT把全部來自相同內部IP地址和端口的請求映射到相同的外部IP地址和端口。任何一個外部主機都可經過該映射發送IP包到該內部主機。
(2)限制性克隆(Restricted Cone) : NAT把全部來自相同內部IP地址和端口的請求映射到相同的外部IP地址和端口。可是,只有當內部主機先給IP地址爲X的外部主機發送IP包,該外部主機才能向該內部主機發送IP包。
(3)端口限制性克隆( Port Restricted Cone) :端口限制性克隆與限制性克隆相似,只是多了端口號的限制,即只有內部主機先向IP地址爲X,端口號爲P的外部主機發送1個IP包,該外部主機纔可以把源端口號爲P的IP包發送給該內部主機。
(4)對稱式NAT ( Symmetric NAT): 對稱式NAT與端口限制性克隆相似,惟一不一樣的是當同一內部主機使用相同的端口與不一樣IP地址或端口的外部主機進行通訊時, NAT對該內部主機的端口映射會有所不一樣,這種狀況下NAT會針對不一樣IP地址或端口的外部主機爲內部主機的相同端口分配新的外部端口號。對稱式NAT不保證全部會話中的私有地址端口和公開地址端口之間綁定的一致性。相反,它爲每一個新的會話分配一個新的端口號。這種狀況下內部主機的「內網IP地址和端口」與「NAT IP地址和端口」之間會造成一對多關係。3d

 

這是我在網上找到的另外一份關於NAT四種類型的解釋,我以爲這個敘述更加清楚明瞭,這裏寫下來做爲補充,請按照順序和上面敘述的四種NAT類型進行對照理解:視頻

從內網主機發出報文訪問外網目標時,可用四元組[源IP,源端口,目標IP,目標端口]來表示會話:
[私有源地址,私有源端口,全局目標地址,全局目標端口]
     ↓NAT
[全局源地址,全局源端口,全局目標地址,全局目標端口]
   NAT在對不一樣的私有源地址進行轉換的時候,可能轉換成同一全局源地址,也可能轉換成不一樣的全局源地址(若是NAT地址池配置有多個全局地址)。
   而對於同一私有源地址和端口的轉換狀況則分爲如下幾種:
(1)徹底Cone NAT 不管目標地址和端口怎樣,每次都把該私有源IP地址/端口映射到同一個全局源地址/端口;外網的任何主機均可以發送報文到該映射的全局地址而訪問到該內部主機。路由器的靜態地址映射就是屬於這種。
(2)限制Cone NAT 地址/端口映射的狀況同徹底Cone NAT的,但外網的主機要訪問內網主機,該內網主機必須先發送過報文給該外網主機的地址。
(3)端口限制Cone NAT 地址/端口映射狀況同徹底Cone NAT的,但外網主機要訪問內網主機,該內網主機必須先發送過報文給該外網主機的地址和端口。大多數路由器的NAPT就是屬於這種狀況。本文後面論及的Cone NAT也是指這種狀況。htm

(4)Symmetric NAT 對不一樣的目標地址/端口,源私有地址映射到源全局地址不變,可是映射的全局端口會改變。外網主機必須先收到過內網主機的報文,才能訪問到該內網主機。一些路由器和防火牆產品的NAT就是屬於這種狀況。blog

    Symmetric NAT並不對新會話進行端口綁定,而是分配一個全新的NAT端口給每個新的會話.路由

如下是文本形式的展示,能夠把下面的內容複製到txt等文本文件中查看。


     Server S1                                     Server S2
        18.181.0.31:1235                              138.76.29.7:1235
               |                                             |
               |                                             |
               +----------------------+----------------------+
                                      |
          ^  Session 1 (A-S1)  ^      |      ^  Session 2 (A-S2)  ^
          |  18.181.0.31:1235  |      |      |  138.76.29.7:1235  |
          v 155.99.25.11:62000 v      |      v 155.99.25.11:62001 v
                                      |
                                 Symmetric NAT
                                 155.99.25.11
                                      |
          ^  Session 1 (A-S1)  ^      |      ^  Session 2 (A-S2)  ^
          |  18.181.0.31:1235  |      |      |  138.76.29.7:1235  |
          v   10.0.0.1:1234    v      |      v   10.0.0.1:1234    v
                                      |
                                   Client A
                                10.0.0.1:1234
    如上圖,若是Client A同時發起兩個會話到S1和S2,對稱NAT會分配NAT地址155.99.25.11:62000給Session1,而後分配另外一個不一樣的NAT地址155.99.25.11:62001給Session2.對稱NAT可以區別兩個不一樣的會話並進行地址轉換,應用程序每發出一個會話都會使用一個新的端口.

 

下面咱們接着來看看對NAT進行打洞的流程與原理

先假設:有一個服務器S在公網上有一個IP,兩個私網分別由NAT-A和NAT-B鏈接到公網,NAT-A後面有一臺客戶端A,NAT-B後面有一臺客戶端B,如今,咱們須要藉助S將A和B創建直接的TCP鏈接,即由B向A打一個洞,讓A能夠沿這個洞直接鏈接到B主機,就好像NAT-B不存在同樣。

實現過程以下:
一、 S啓動兩個網絡偵聽,一個叫【主鏈接】偵聽,一個叫【協助打洞】的偵聽。
二、 A和B分別與S的【主鏈接】保持聯繫。
三、 當A須要和B創建直接的TCP鏈接時,首先鏈接S的【協助打洞】端口,併發送協助鏈接申請。同時在該端口號上啓動偵聽。注意因爲要在相同的網絡終端上綁定到不一樣的套接字上,因此必須爲這些套接字設置 SO_REUSEADDR 屬性(即容許重用),不然偵聽會失敗。
四、 S的【協助打洞】鏈接收到A的申請後經過【主鏈接】通知B,並將A通過NAT-A轉換後的公網IP地址和端口等信息告訴B。
五、 B收到S的鏈接通知後首先與S的【協助打洞】端口鏈接,隨便發送一些數據後當即斷開,這樣作的目的是讓S能知道B通過NAT-B轉換後的公網IP和端口號。
六、 B嘗試與A的通過NAT-A轉換後的公網IP地址和端口進行connect,根據不一樣的路由器會有不一樣的結果,有些路由器在這個操做就能創建鏈接,大多數路由器對於不請自到的SYN請求包直接丟棄而致使connect失敗,但NAT-B會紀錄這次鏈接的目標地址和端口號(即A通過NAT-A轉換後的公網IP和端口號),爲接下來真正的鏈接作好了準備,這就是所謂的打洞,即B向A打了一個洞,下次A就能直接鏈接到B剛纔使用的端口號了。
七、 客戶端B打洞的同時在相同的端口上啓動偵聽。B在一切準備就緒之後經過與S的【主鏈接】回覆消息「我已經準備好」,S在收到之後將B通過NAT-B轉換後的公網IP和端口號告訴給A。
八、 A收到S回覆的B的公網IP和端口號等信息之後,開始鏈接到B公網IP和端口號(此時NAT-A也會紀錄這次鏈接的目標地址和端口號(即B通過NAT-B轉換後的公網IP和端口號),即A也向B打了一個洞,以後B也能直接鏈接到A的公網IP和端口號了),因爲在步驟6中B曾經嘗試鏈接過A的公網IP地址和端口,NAT-B紀錄了這次鏈接的信息,因此當A主動鏈接B時,NAT-B會認爲是合法的SYN數據,並容許經過,從而直接的TCP鏈接創建起來了。

 

有了必定的知識補充,接下來開始實現UDP和TCP打洞。由於沒幹過這個 可能要花必定的時間

 

本文轉自原文:http://www.cnblogs.com/yuanfan/archive/2010/12/17/1909379.html

出處:http://www.cnblogs.com/OpenCoder/diary/2011/06/29/2093895.html

相關文章
相關標籤/搜索