內網穿透&UDP打洞


文章轉載自:http://www.cnblogs.com/cinlap/articles/2684330.html

這兩天找度度重新回憶了一下關於內網穿透的事情,在百度文庫上找到了兩三篇寫的比較通俗易懂的文章,把內網穿透做個簡單總結。


首先文章建議 Cone NAPT 還有希望,要是 Symmetri NAPT 就別想了,接着介紹了兩種基本情況,一是一臺內網機器連接外網通信的情況,二是兩臺內網之間互聯的情況。


第一種,只需要內網主動發起連接就可以了。內網機器A(192.168.1.x:4000)要求連接外網服務端S(60.17.211.x:5000),發出連接請求後被A網所在網關NA(10.11.12.x)獲取,NA將A的地址轉變爲其自身地址,並分配臨時端口(6000)用作通訊,於是,當初的 A->S 就變成現在的 A->NA->S。那麼S接到請求後看到的並不是A的地址,而是NA的IP和Port,此時S如果照着此地址回覆,則NA收到,因爲NA此時有通訊臨時Session被創建了,所以在一定時間內(貌似根據不同硬件、軟件設備而不同)還記得發到6000的信息要轉給A,NA就會轉發給A。至此,通訊成功。


第二種,兩個內網之間就要複雜一些,有一個圖很好,我轉載了一下,特別聲明,是從百度文庫截圖下來的。

 

這個圖很清晰,做個簡單備註就可以了。

 

首先,兩個內網A和B誰都不能直接連誰,所以第一次,都是給S發送登錄、心跳之類的,目的是表明自己的存在,並建立session,當然,這個過程還是通過自身網絡的N實現的。那麼,如何做到UDP穿透呢?

 

1. 假設左邊的爲A(192.168.1.77:8000),A->NA(211.133.*:6000)->S,此時,S記住了 A 的存在,NA也與A建立了對應關係(發到6000的信息就是A的),一樣道理,B也與S建立了連接。

 

2. A通過S知道了B的存在(只是知道存在),A想連B,於是A告訴S,“讓B探測我一下”

 

3. S把A的要求發給B,於是B發送“探測”包給A,事實上就是 B->NB->NA,但是因爲 NA 不認識 NB(之前沒聯繫過),所以 NA 就不會轉發給 A,隨之丟棄。但是 NB 上已經建立起了目的是 NA 的 session,這是後面打洞成功的關鍵一步。

 

4. B 發送探測給 A 之後,因爲 NA 必定丟棄,所以 B 向 S 發送“反饋包”,就是圖中的步驟 4,目的是告訴 S 已經發送過探測包給 A 了。這一步的目的是,借 S 之手告訴 A ,我已經聯繫過你了,我已經有了關於你的 session 。

 

5. S 通知 A:“人家 B 已經聯繫過你了”。

 

6. A 知道之後,發送數據包給 B ,也就是 A->NA->NB->B。當 NA->NB 時,因爲 NB 存有當初鏈接 NA 的信息,所以 NB 認爲它自己認識 NA ,會接受 NA 發送的信息,轉發給 B,至此,理論上,打洞完成。AB之間可以互通了。還未經過自己試驗,不知道對不對。

 

圖中右上角步驟2中的文字“...給NAT211.134.*”應該是錯誤的,正確的應該是“211.133.*”,因爲是 S 讓 B 去連接 A,而 A 的地址是 211.133.*,另外還有幾點疑惑和說明的地方

 

1. “信息不請自來,NAT 安全起見,是會被丟棄的”——A->NA->S 時,NA 接到請求會創建 session ,分配某端口如6000對應 A ,目的是接到發到 6000 端口上的信息就知道轉發給 A,但只會接受當初 A 所請求的遠程主機 S 所發過來的信息纔會轉發給 A,其它地址則會丟棄。這也是爲什麼兩個內網不能直接互發的原因,舉個例子就是洞還沒打,外界發過來的信息,也會被看門人 NA 給扔掉,因 NA 那有一個記錄表,A 曾經要求連接 S,這條記錄就會有關於 S 的信息,比如另一臺 S2 發過來同樣的 6000 端口信息,由於 NA 沒有記錄不認識 S2 ,是會丟棄不會轉發的。 

 

2. 打洞要從內部向外部打,S 想連接 A,A 向 S 打洞(發起連接)。A 想連接 B,要通過 S 告訴 B 讓 B 向 A 打洞,B 打完 A 沿此路打回去,才能成功。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章