NAT穿透的詳解及分析

1、什麼是NAT?爲何要使用NAT?
NAT是將私有地址轉換爲合法IP地址的技術,通俗的講就是將內網與內網通訊時怎麼將內網私有IP地址轉換爲可在網絡中傳播的合法IP地址。NAT的出現完美地解決了lP地址不足的問題,並且還可以有效地避免來自網絡外部的攻擊,隱藏並保護網絡內部的計算機。 
2、NAT的分類
STUN標準中,根據內部終端的地址(LocalIP:LocalPort)到NAT出口的公網地址(PublicIP:PublicPort)的影射方式,把NAT分爲四種類型:
一、Full Cone NAT(徹底錐型):後端

        內網主機創建一個socket(LocalIP:LocalPort) 第一次使用這個socket給外部主機發送數據時NAT會給其分配一個公網(PublicIP:PublicPort),之後用這個socket向外面任何主機發送數據都將使用這對(PublicIP:PublicPort)。此外,任何外部主機只要知道這個(PublicIP:PublicPort)就能夠發送數據給(PublicIP:PublicPort),內網的主機就能收到這個數據包。 
二、Restricted Cone NAT(限制錐型):安全

        內網主機創建一個socket(LocalIP:LocalPort) 第一次使用這個socket給外部主機發送數據時NAT會給其分配一個公網(PublicIP:PublicPort),之後用這個socket向外面任何主機發送數據都將使用這對(PublicIP:PublicPort)。此外,若是任何外部主機想要發送數據給這個內網主機,只要知道這個(PublicIP:PublicPort)而且內網主機以前用這個socket曾向這個外部主機IP發送過數據。只要知足這兩個條件,這個外部主機就能夠用本身的(IP,任何端口)發送數據給(PublicIP:PublicPort),內網的主機就能收到這個數據包。
三、Port Restricted Cone NAT(端口限制錐型):服務器

        內網主機創建一個socket(LocalIP:LocalPort) 第一次使用這個socket給外部主機發送數據時NAT會給其分配一個公網(PublicIP:PublicPort),之後用這個socket向外面任何主機發送數據都將使用這對(PublicIP:PublicPort)。此外,若是任何外部主機想要發送數據給這個內網主機,只要知道這個(PublicIP:PublicPort)而且內網主機以前用這個socket曾向這個外部主機(IP,Port)發送過數據。只要知足這兩個條件,這個外部主機就能夠用本身的(IP,Port)發送數據給(PublicIP:PublicPort),內網的主機就能收到這個數據包。
四、Symmetric NAT(對稱型):網絡

        內網主機創建一個socket(LocalIP,LocalPort),當用這個socket第一次發數據給外部主機1時,NAT爲其映射一個(PublicIP-1,Port-1),之後內網主機發送給外部主機1的全部數據都是用這個(PublicIP-1,Port-1),若是內網主機同時用這個socket給外部主機2發送數據,NAT會爲其分配一個(PublicIP-2,Port-2), 之後內網主機發送給外部主機2的全部數據都是用這個(PublicIP-2,Port-2).若是NAT有多於一個公網IP,則PublicIP-1和PublicIP-2可能不一樣,若是NAT只有一個公網IP,則Port-1和Port-2確定不一樣,也就是說必定不能是PublicIP-1等於 PublicIP-2且Port-1等於Port-2。此外,若是任何外部主機想要發送數據給這個內網主機,那麼它首先應該收到內網主機發給他的數據,而後才能往回發送,不然即便他知道內網主機的一個(PublicIP,Port)也不能發送數據給內網主機,這種NAT沒法實現P2P通訊,可是若是另外一方是Full Cone NAT,仍是能夠實現穿透的,下面我會詳細分析各類類型NAT穿透的狀況。
  NAT 功能一般被集成到路由器、防火牆、ISDN路由器或者單獨的NAT設備中。因此咱們你們不多會知道NAT,上面NAT類型的概念描述是比較通俗的,但爲了更便於理解,我再舉例闡述一下NAT的原理。
  現有通訊的雙方A和B,當A和B都是在公網的時候,通訊是不用NAT的。假設A在內網,內網IP是192.168.1.3,端口號是5000,A通過NAT後的IP是221.221.221.100,端口號是8000,B的IP是202.105.124.100,端口是8500。若是B要去主動鏈接A,即便B知道A通過NAT後的IP和端口也是沒法鏈接成功的,由於A沒有向B(202.105.124.100:8500)發送過數據,因此B的數據包會被A的NAT丟棄,因而鏈接失敗。可是A若是去主動鏈接B,因爲B是在公網,因此會鏈接成功,通訊也就會創建。這也就是反彈鏈接木馬「反彈」二字的精髓。
當客戶端A和B都是處在內網的時候,雙方因爲都不知道對方的公網IP和端口,就會無從下手,因此要在客戶端A和B之間架設一臺服務器S來爲它們牽線,並且S是處在公網,以保證A和B都能鏈接到S。客戶端A和B登陸時都首先鏈接S,S就會知道A和B通過NAT後的IP和端口,當A想要鏈接B時,就像S發出請求,S會把B通過NAT後的IP和端口告訴A,同時S向B發送A通過NAT後的IP和端口,並要求B發送數據給A,B發送數據到達A時會被A的NAT拋棄,可是B的NAT會有B發送數據到A的記錄,這是A再向B發送數據時就會被B的NAT放行,由於B曾經向A的外網IP和端口發送過數據。可能有點亂,下面以故事的形式敘述一下這個情景。
人物:A(男) NAT_A(A家接線員) B(女) NAT_B (B家接線員) S
場景介紹:A想認識B,可是不知道B的電話,S跟A、B都是朋友,而且知道A和B的電話。接線員的職責:對往外轉接的電話不作詢問,對往內轉接的電話則要過濾以避免有騷擾電話。過濾規則:在必定時間內沒有撥打過的號碼就過濾。
首先A給S打電話:
A說:我想認識你朋友B,你把她電話給我唄。
S說:行,她的電話是PublicIP_B,我讓她先給你打個電話,要不她家接線員不幫你轉接。
A說:好。

S跟B打電話:
S說:我有一個朋友A,人挺好的,他想認識你,你給他打個電話,他的電話號碼是PublicIP_A。
B說:行,打完告訴你。
S說:好的。

B打電話到A家,B家接線員NET_B看到女主人想往PublicIP_A打電話就轉接到A家了,同時把號碼PublicIP_A記錄下來,A家接線員NAT_A一看號碼是個近期沒打過的號,就給掛斷了。

B給S打電話:
B說:我打完電話了
S說:好,等着吧,一會他就給你打進來了。

S給A打電話:
S說:他給你打完電話了,你快點給她打。

A打電話到B家, A家接線員NET_A看到男主人想往PublicIP_B打電話就轉接到B家了,B家接線員NET_B看到是剛剛撥過的PublicIP_A號碼打過來的,就轉接給B了,A和B的電話也就打通了。
A和B通話:
A說:電話終於打通了,想認識你挺困難的。
B說:是啊。


以上雖然和實際不太同樣,但穿透的總體過程基本就是這樣。A往B發送數據的惟一阻礙就是NET_B,因此想要成功發送數據,必須把NET_B穿一個洞,A是沒法完成這項工做的,因此就得讓B完成這個打洞操做,也就是讓B往A發送數據,這樣NET_B就會誤覺得A發送的數據是上次會話的一部分從而不予阻攔。
可是,因爲NAT的類型沒有一個統一的標準,因此NAT穿透使用的技術有不少種,穿透的成功率也不同。還有些NAT類型的內網之間幾乎沒法穿透。下面咱們用實例詳細分析一下各類NAT類型穿透的可行性。

A機器在私網(192.168.0.3) 
A側NAT服務器(221.221.221.100) 
B機器在另外一個私網(192.168.0.5) 
B側NAT服務器(210.30.224.70) 
C機器在公網(210.202.14.36)做爲A和B之間的中介 
A機器鏈接C機器,假使是A(192.168.0.3:5000)-> A側NAT(轉換後221.221.221.100:8000)-> C(210.202.14.36:2000) 
B機器也鏈接C機器,假使是B(192.168.0.5:5000)-> B側NAT(轉換後210.30.224.70:8000)-> C(210.202.14.36:2000) 
A機器鏈接過C機器後,A向C報告了本身的內部地址(192.168.0.3:5000),此時C不只知道了A的外部地址(C經過本身看到的221.221.221.100:8000)也知道了A的內部地址。同理C也知道了B的外部地址(210.30.224.70:8000)和 內部地址(192.168.0.5:5000)。以後,C做爲中介,把A的兩個地址告訴了B,同時也把B的兩個地址告訴了A。 
假設A先知道了B的兩個地址,則A從192.168.0.3:5000處同時向B的兩個地址192.168.0.5:5000和210.30.224.70:8000發包,因爲A和B在兩個不一樣的NAT後面,故從A(192.168.0.3:5000)到B(192.168.0.5:5000)的包確定不通,如今看A(192.168.0.3:5000)到B(210.30.224.70:8000)的包,分以下兩種狀況: 
一、B側NAT屬於Full Cone NAT 
        則不管A側NAT屬於Cone NAT仍是Symmetric NAT,包都能順利到達B。若是程序設計得好,使得B主動到A的包也能借用A主動發起創建的通道的話,則即便A側NAT屬於Symmetric NAT,B發出的包也能順利到達A。 
結論1:只要單側NAT屬於Full Cone NAT,便可實現雙向通訊。 
二、B側NAT屬於Restricted Cone或Port Restricted Cone 
則包不能到達B。再細分兩種狀況 
(1)、A側NAT屬於Restricted Cone或Port Restricted Cone 
        雖然先前那個初始包未曾到達B,但該發包過程已經在A側NAT上留下了足夠的記錄:A(192.168.0.3:5000)->(221.221.221.100:8000)->B(210.30.224.70:8000)。若是在這個記錄沒有超時以前,B也重複和A同樣的動做,即向A(221.221.221.100:8000)發包,雖然A側NAT屬於Restricted Cone或Port Restricted Cone,但先前A側NAT已經認爲A已經向B(210.30.224.70:8000)發過包,故B向A(221.221.221.100:8000)發包可以順利到達A。同理,此後A到B的包,也能順利到達。 
結論2:只要兩側NAT都不屬於Symmetric NAT,也可雙向通訊。換種說法,只要兩側NAT都屬於Cone NAT,便可雙向通訊。 
(2)、A側NAT屬於Symmetric NAT 
         由於A側NAT屬於Symmetric NAT,且最初A到C發包的過程在A側NAT留下了以下記錄:A(192.168.0.3:5000)->(221.221.221.100:8000)-> C(210.202.14.36:2000),故A到B發包過程在A側NAT上留下的記錄爲: 
A(192.168.0.3:5000)->(221.221.221.100:8001)->B(210.30.224.70:8000)(注意,轉換後端口產生了變化)。而B向A的發包,只能根據C給他的關於A的信息,發往A(221.221.221.100:8000),由於A端口受限,故此路不通。再來看B側NAT,因爲B也向A發過了包,且B側NAT屬於Restricted Cone或Port Restricted Cone,故在B側NAT上留下的記錄爲:B(192.168.0.5:5000)->(210.30.224.70:8000)->A(221.221.221.100:8000),此後,若是A還繼續向B發包的話(由於同一目標,故仍然使用前面的映射),若是B側NAT屬於Restricted Cone,則從A(221.221.221.100:8001)來的包可以順利到達B;若是B側NAT屬於Port Restricted Cone,則包永遠沒法到達B。 
結論3:一側NAT屬於Symmetric NAT,另外一側NAT屬於Restricted Cone,也可雙向通訊。 
反過來想,則能夠得出另外一個結論:兩個都是Symmetric NAT或者一個是Symmetric NAT、另外一個是Port Restricted Cone,則不能雙向通訊,由於NAT沒法穿透;(me:symmetricNAT之因此難以穿透是由於:AB「彙報」給S的外部端口與鏈接A/B時的端口不一樣所致。由於與不一樣主機通訊時,NAT爲其分配不一樣外部端口。) 
上面的例子雖然只是分析了最初發包是從A到B的狀況,可是,因爲二者的對稱性,前面得出的幾條結論沒有方向性,雙向都適用。 
咱們上面得出了四條結論,natcheck網站則把他歸結爲一條:只要兩側NAT都屬於Cone NAT(含Full Cone、Restricted Cone和Port Restricted Cone三者),便可雙向通訊。沒有把咱們的結論3包括進去。
通常狀況下,只有比較注重安全的大公司會使用Symmetric NAT,禁止使用P2P類型的通訊,不少地方使用的都是Cone NAT,所以穿透技術仍是有發展前景的。
3、使用UDP、TCP穿透NAT
上面講的狀況能夠直接應用於UDP穿透技術中,使用TCP 協議穿透NAT 的方式和使用UDP 協議穿透NAT 的方式幾乎同樣,沒有什麼本質上的區別,只是將無鏈接的UDP 變成了面向鏈接的TCP 。值得注意是:
一、 B在向A打洞時,發送的SYN 數據包,並且一樣會被NAT_A 丟棄。同時,B須要在原來的socket 上監聽,因爲重用socket ,因此須要將socket 屬性設置爲SO_REUSEADDR 。
A向B發送鏈接請求。一樣,因爲B到A方向的孔已經打好,因此鏈接會成功,通過3 次握手後,A到B之間的鏈接就創建起來了。具體過程以下:
(me:UDP過程不須要建立兩個socket,過程與上述描述的方法一致,不需再羅列)
一、 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會紀錄這次鏈接的源地址和端口號,爲接下來真正的連 接作好了準備,這就是所謂的打洞,即B向A打了一個洞,下次A就能直接鏈接到B剛纔使用的端口號了。
七、 客戶端B打洞的同時在相同的端口上啓動偵聽。B在一切準備就緒之後經過與S的【主鏈接】回覆消息「我已經準備好」,S在收到之後將B通過NAT-B轉換後的公網IP和端口號告訴給A。
八、 A收到S回覆的B的公網IP和端口號等信息之後,開始鏈接到B公網IP和端口號,因爲在步驟6中B曾經嘗試鏈接過A的公網IP地址和端口,NAT-B紀錄了這次鏈接的信息,因此當A主動鏈接B時,NAT-B會認爲是合法的SYN數據,並容許經過,從而直接的TCP鏈接創建起來了。併發

==================================== 另外一遍 ===================================================socket

簡述

基於UDP的P2P應用須要考慮NAT的類型,由於不一樣的NAT組合的穿透的方式並不一致,有的能通, 有的不能通。tcp

通常來說, NAT能夠分爲四種類型,分別是:網站

1, 全錐型(Full Cone)spa

2,  受限錐型(Restricted Cone), 或者說是IP受限錐型.net

3,  端口受限錐型(Port Restricted Cone), 或者說是IP + PORT受限錐型

4,  對稱型(Symmetric)

其中1,2,3屬於同一種類型,都是錐型,區別只是路由器的不一樣的安全策略。

還有些NAT不屬於這四種中的任何一種,就不在本文的討論範圍了。

爲何有四種類型的NAT

  NAT緩解了IPV4地址不夠用的問題,同時也也帶了限制,那就是NAT外部的主機沒法主動跟位於NAT內部的主機通訊,NAT內部主機想要通訊,必須主動和公網的一個IP通訊,路由器負責創建一個映射關係,從而實現數據的轉發, 這就是NAT的工做原理。

假定

公網server1 ip是1.1.1.1, 監聽端口是1111

公網server2 ip是2.2.2.2, 監聽端口是2222

NAT router ip是8.8.8.8

NAT內部client是192.168.0.3

client發送數據的時候,無論是tcp仍是udp必須本地綁定一個端口,通常來說,這個過程都是自動的。

假定client(192.168.0.3, 100)給 server(1.1.1.1, 1111)發送報文,報文到達路由器,路由器在本身的公網ip上開闢一個端口800,從而創建了一個隱射關係(8.8.8.8, 800)<--->(192.168.0.3, 100),  創建映射關係後,因此(192.168.0.3, 100)和(1.1.1.1, 1111)之間的報文都經過這個映射關係進行轉發。

NAT之間主要的區別分兩種狀況討論

1. client(192.168.0.3, 100)和server(1.1.1.1, 1111)在路由器上創建好映射關係後,若是client(192.168.0.3, 100)又給(2.2.2.2, 2222)發送數據,路由器該怎麼處理呢?

  1,  複用舊的映射關係(8.8.8.8, 800)<--->(192.168.0.3, 100)和(2.2.2.2, 2222)通訊, 這就是錐型(Cone) NAT

  2,  建立新的映射關係(8.8.8.8, 801)<--->(192.168.0.3, 100)和(2.2.2.2, 2222)通訊, 這就是對稱型NAT

  注:  (8.8.8.8, 801)只是舉例,到底用什麼端口取決於路由器的端口管理策略,總之是另外的一個端口,有的路由器有多個公網IP,不一樣的IP也會參與到這個映射關係中。

2. client(192.168.0.3, 100)和server(1.1.1.1, 1111)在路由器上創建好映射關係後,若是這個時候路由器(8.8.8.8)在800端口上收到從另一臺server(2.2.2.2, 2222)發來的數據,是否是應該轉發給(192.168.0.3, 100)呢?

  有四種狀況:

  1, 無條件轉發給(192.168.0.3, 100), 這就是全錐型(Full Cone)NAT。

  2, 若是(192.168.0.3, 100)以前給(2.2.2.2)發送過數據,則轉發, 這就是受限錐型(Restricted Cone)。

  3, 若是(192.168.0.3, 100)以前給(2.2.2.2, 2222)發送過數據,則轉發, 這就是端口受限錐型(Port Restricted Cone)。

  4, 丟棄報文,拒絕轉發, 這就是對稱型NAT。

從上面也描述也能夠看出,安全性係數,  對稱型 > 端口受限錐型 > 受限錐型 > 全錐型

 

不一樣NAT的穿透性

NAT有10種組合


---------------------

轉自:https://blog.csdn.net/g_brightboy/article/details/12704933

原文:https://blog.csdn.net/mycloudpeak/article/details/53550405 

相關文章
相關標籤/搜索