穿越NAT的迷霧:深入理解網(wǎng)絡地址轉換和NAT穿透,以及STUN、TURN、ICE的關系
NAT是什么?
NAT是Net Address Translation的縮寫,即網(wǎng)絡地址轉換。
NAT部署在網(wǎng)絡出口的位置,位于內網(wǎng)跟公網(wǎng)之間,是連接內網(wǎng)主機和公網(wǎng)的橋梁,雙向流量都必須經(jīng)過NAT,裝有NAT軟件的路由器叫NAT路由器,NAT路由器擁有公網(wǎng)IP。
你的家庭和辦公網(wǎng)絡環(huán)境大多是經(jīng)過NAT路由中轉的方式聯(lián)網(wǎng)。這也意味著你在家PC通過WIFI聯(lián)網(wǎng),你在PC上通過命令行(ifconfig)查看到的IP地址(內網(wǎng)),跟通過baidu查看到的IP地址(公網(wǎng)),不一樣,這也能證明你的PC處于NAT后面。
NAT解決什么問題?
NAT主要用來解決IPv4地址不夠用的問題。
IPv4用32位表示網(wǎng)絡地址,最大能表示2的32次方(2^32=40億)個IP地址,但隨著各種聯(lián)網(wǎng)設備的快速增長,IPv4地址不夠用了,IPv6又遠水不解近渴,怎么辦?NAT技術應運而生。
NAT是怎么工作的?
內網(wǎng)地址:RFC1918規(guī)定了三個保留地址段落:
- 10.0.0.0-10.255.255.255;
- 172.16.0.0-172.31.255.255;
- 192.168.0.0-192.168.255.255。
這三個范圍分別處于A、B、C類的地址段,不向特定的用戶分配,被IANA作為私有地址保留。這些地址可以在任何組織或企業(yè)內部使用,和其他Internet地址的區(qū)別就是,僅能在內部使用,不能作為全球路由地址。
NAT后面的內網(wǎng)主機使用內網(wǎng)地址,也叫本地地址,是主機上內網(wǎng)上的標識。內網(wǎng)主機要跟公網(wǎng)通信,必須經(jīng)過NAT中轉,NAT會自動為經(jīng)過的網(wǎng)絡包做內外網(wǎng)地址轉換(這也是NAT的含義),公網(wǎng)地址是主機在互聯(lián)網(wǎng)上的標識。
NAT原理:內網(wǎng)主機向外網(wǎng)主機發(fā)送的網(wǎng)絡包,在經(jīng)過NAT時,IP和PORT會被替換為NAT為該主機分配的外網(wǎng)IP/PORT,也就是該內網(wǎng)主機在NAT上的出口IP/PORT,外網(wǎng)主機收到該網(wǎng)絡包后,會視該網(wǎng)絡包是從NAT發(fā)送的;外網(wǎng)主機只能通過NAT為該內網(wǎng)主機分配的外網(wǎng)IP/PORT,向它發(fā)送網(wǎng)絡包,內網(wǎng)主機的本地地址對外界不可見,網(wǎng)絡包在經(jīng)過NAT的時候,會被NAT做外網(wǎng)IP/PORT到內網(wǎng)IP/PORT的轉換。
可見,NAT維護內網(wǎng)主機內網(wǎng)地址和在NAT上為它分配的外網(wǎng)地址之間的映射關系,需要維護一張關聯(lián)表。NAT在兩個傳輸方向上做兩次地址轉化,出方向做源(Src)信息替換,入方向做目的(Dst)信息替換,內外網(wǎng)地址轉換是在NAT上自動完成的。NAT網(wǎng)關的存在對通信雙方是透明的。
那NAT是如何緩解IPv4地址枯竭問題的呢?答案是端口多路復用,通過PAT(Port Address Translation),讓NAT背后的多臺內網(wǎng)主機共享一個外網(wǎng)IP,最大限度節(jié)省外網(wǎng)IP資源。
NAT背后的多臺內網(wǎng)主機是如何實現(xiàn)共享一個外網(wǎng)IP的呢?它是通過修改外出數(shù)據(jù)包的源IP和端口。
假設內網(wǎng)主機H1和H2位于NAT之后,H1通過本地地址10.0.0.1:port1給公網(wǎng)主機X發(fā)送數(shù)據(jù)包,在經(jīng)過NAT的時候,該數(shù)據(jù)包的IP:PORT被修改為NAT的外網(wǎng)地址1.2.3.4:2222。
H2通過本地地址10.0.0.2:port2向公網(wǎng)主機X發(fā)送數(shù)據(jù)包,在經(jīng)過NAT的時候,該數(shù)據(jù)包的ip:port被修改為NAT的外網(wǎng)1.2.3.4:3333。
雖然H1和H2的IP都被映射到了相同的NAT外網(wǎng)IP(1.2.3.4),但NAT為它們分配了不同的端口(2222和3333),所以可以通過端口區(qū)分H1和H2。之后公網(wǎng)主機X向內網(wǎng)主機H1發(fā)送網(wǎng)絡包的時候,只需要把1.2.3.4:2222作為目標地址:端口,就可以由NAT自動完成轉換,正確轉交到H1主機。
這便是基于端口復用的NAT方式(NPAT)的工作原理。通過將內網(wǎng)不同連接(主機到NAT)映射到同一公網(wǎng)IP的不同端口,從而實現(xiàn)公網(wǎng)IP的復用和解復用,這種一對多的方式也叫做端口轉換PAT或IP偽裝。
NAT的約束
NAT把網(wǎng)絡分為公網(wǎng)和內網(wǎng),內網(wǎng)主機可以給外網(wǎng)主機直接發(fā)送網(wǎng)絡包,而外網(wǎng)主機卻不能主動給內網(wǎng)主機發(fā)送網(wǎng)絡包,也就是說網(wǎng)絡通信必須由內網(wǎng)側主動發(fā)起,公網(wǎng)主機不能主動訪問內網(wǎng)主機,這是NAT帶來的限制和約束。
內網(wǎng)主機主動給外網(wǎng)主機發(fā)送過網(wǎng)絡包之后,外網(wǎng)主機才有可能給內網(wǎng)主機發(fā)送網(wǎng)絡包。
NAT的類型
NAT的實現(xiàn)方式分靜態(tài)轉換、動態(tài)轉換和端口多路復用三種,但目前用的最多的還是端口多路復用,是最典型的一種應用模式。
首先,從大的層面上,端口復用型NAT(Net Address Port Translation)可以分為對稱型NAT和非對稱型NAT。
- 對稱型NAT(Symmetric NAT),內網(wǎng)某主機向公網(wǎng)的不同網(wǎng)絡地址(或端口)發(fā)送2個不同的網(wǎng)絡包,對稱型NAT會為這2個不同的網(wǎng)絡包產生2個不同出口端口號。換言之,NAT網(wǎng)關會把內部主機“地址端口對”和外部主機“地址端口對”完全相同的報文看作一個連接,在NAT網(wǎng)關上創(chuàng)建一個公網(wǎng)“地址端口對”作為出口地址,只有收到報文的外部主機從對應的端口對發(fā)送回應的報文,才能被轉換。對稱型NAT無法打洞,只能通過TURN Server轉發(fā)。
- 非對稱型NAT(也叫錐型NAT),內網(wǎng)某主機向外網(wǎng)主機發(fā)送網(wǎng)絡包,NAT會為該內網(wǎng)主機生成一個公網(wǎng)(出口)IP:PORT,之后,不管該內網(wǎng)主機會通過該出口IP:PORT跟外網(wǎng)所有(如果可以)主機通信,而不會被映射到其他端口(出口IP顯然也不會變)。
錐型NAT細分:
- Full Cone NAT(全錐型NAT):只要內網(wǎng)某主機給外網(wǎng)地址主動發(fā)送過一個網(wǎng)絡包(NAT會為之生成公網(wǎng)出口IP:PORT),外網(wǎng)任何主機都可以通過該內網(wǎng)主機在NAT上的出口IP:PORT,向該內網(wǎng)主機發(fā)送網(wǎng)絡包,也就是對外網(wǎng)主機IP和PORT都不設限,這是最寬松的類型。
- Restricted Cone NAT(IP受限型NAT):如果內網(wǎng)某主機,給外網(wǎng)某IP發(fā)送過一個網(wǎng)絡包,則外網(wǎng)可以通過該IP向該內網(wǎng)主機發(fā)送網(wǎng)絡包,注意,只要以該IP作為網(wǎng)絡包src ip就行,其他IP作為src不行,不限制端口號。
舉個例子,內網(wǎng)主機10.0.0.1給外網(wǎng)1.2.3.4:2222主動發(fā)過網(wǎng)絡包,外網(wǎng)主機可以通過1.2.3.4:3333(作為src)向內網(wǎng)主機10.0.0.1發(fā)送網(wǎng)絡包,端口號不限,但不能通過其他ip向內網(wǎng)主機發(fā)送網(wǎng)絡包。
- Port Restricted Cone NAT(Port受限型NAT):跟IP受限類似,但是它更嚴格,既限制IP,又限制端口號。內網(wǎng)主機給外網(wǎng)主機10.0.0.1:2222發(fā)送過網(wǎng)絡包,外網(wǎng)只能以10.0.0.1:2222為src,向內網(wǎng)主機發(fā)送網(wǎng)絡包。
NAT類型檢測
NAT隔離內外網(wǎng),外網(wǎng)不能主動訪問內網(wǎng),但P2P項目,需要位于NAT后的主機(Peer)建立連接,所以需要檢測NAT類型,再判斷Peer之間能否直接建立連接,以及怎么建立連接。
檢測NAT類型主要是利用上述NAT特點,通過測試連通性和比對端口號來實現(xiàn)目的,所以要搞清楚類型檢測,必須對照NAT類型定義來看。
另外,重復一下:NAT后的主機給外網(wǎng)發(fā)網(wǎng)絡包,網(wǎng)絡包在經(jīng)過NAT的時候,NAT會為該主機分配出口IP:PORT,NAT會用該公網(wǎng)(出口)IP:PORT替換網(wǎng)絡包的SRC,這樣,接收端收到包之后,查閱包的src信息,會得到NAT出口IP:PORT,如同該包是直接從NAT發(fā)送過來的一樣。
NAT類型檢測的前提條件:需要有一臺位于公網(wǎng)的服務器(server),且該server擁有2個公網(wǎng)IP地址,并在ip1:port1和ip2:port2做監(jiān)聽。
注意:檢測步驟中的server通過ip:port向client回包,是指server回包的時候,會把ip:port設置為rsp包的src ip和src port。
檢測的步驟:
【步驟1】判斷client是否位于NAT后面
很簡單,位于NAT后面的主機跟公網(wǎng)通信要做內外網(wǎng)地址轉換,兩個IP不一樣。所以,可以通過以下操作完成:
- client向server ip1:port1發(fā)送一個req UDP包。
- server收到udp包之后,從IP頭部取出src IP,從UDP頭部取出src PORT,作為rsp UDP的payload,發(fā)送給client。
- client收到rsp UDP,取出payload里的IP和PORT,跟自己的IP對比,如果相同,則client位于公網(wǎng),擁有公網(wǎng)IP,檢測完成;否則,client位于NAT背后。
【步驟2】判斷是否全錐型Full Cone NAT
client向server ip1:port1發(fā)送一個req UDP包,請求server通過ip2:port2(以ip2:port2作為rsp UDP的src)向client回UDP包。
根據(jù)全錐型NAT的定義,如果client收到了rsp UDP,那說明NAT對外網(wǎng)發(fā)包IP都不限制,說明client是全錐型NAT。但全錐型NAT很少,大概率收不到rsp UDP包,如果收不到,則需要繼續(xù)判斷。
【步驟3】判斷是否對稱型 Symmetirc NAT
client向server ip2:port2發(fā)送一個req udp。server收到后,把收到的req udp的src ip和src port取出來,塞進rsp UDP的payload字段,通過ip2:port2(以ip2:port2作為rsp UDP的src)向client回UDP包。
收到的rsp UDP之后,取出payload中的ip和port,跟步驟1中的ip和port對比,如果不一樣,則是對稱型NAT。
因為根據(jù)前面的定義,對稱型NAT,會為同一內網(wǎng)IP,根據(jù)不同的外網(wǎng)IP,分配不同的NAT出口PORT。
如果一樣,那么肯定是錐型NAT,步驟2已經(jīng)測試了全錐型,那剩下的就只有ip受限錐型和port受限錐型兩種NAT類型需要繼續(xù)判斷了。
【步驟4】判斷是受限錐型Restricted Cone還是PORT受限錐型
client向server ip2:port2發(fā)送一個req udp,要求server用ip2、且不同于port2的端口向client回rsp udp。就是用ip2+不同于port2的其他port作為udp的src向client回包。
如果client能收到rsp udp,那說明只要ip相同,哪怕port不相同,NAT也放行,所以NAT是IP受限型;如果沒收到,那就是PORT受限型,說明只能通過port2回包。
至此,所有的NAT類型便都檢測出來了,是不是很簡單?
對稱型NAT不能直接建立P2P連接,只能通過中轉服務器relay包。
未完待續(xù)。
太長了,后面講打洞、STUN、TURN、ICE。