http://www.cnblogs.com/whyandinside/archive/2010/12/08/1900492.htmlhtml
http://www.gzsec.com/oldversion/filesys/news_view.asp?newsid=84服務器
在現實Internet網絡環境中,大多數計算機主機都位於防火牆或NAT以後,只有少部分主機可以直接接入Internet。不少時候,咱們但願網絡中的兩臺主機可以直接進行通訊,即所謂的P2P通訊,而不須要其餘公共服務器的中轉。因爲主機可能位於防火牆或NAT以後,在進行P2P通訊以前,咱們須要進行檢測以確認它們之間可否進行P2P通訊以及如何通訊。這種技術一般稱爲NAT穿透(NAT Traversal)。最多見的NAT穿透是基於UDP的技術,如RFC3489中定義的STUN協議。網絡
STUN,首先在RFC3489中定義,做爲一個完整的NAT穿透解決方案,英文全稱是Simple Traversal of UDP Through NATs,即簡單的用UDP穿透NAT。session
在新的RFC5389修訂中把STUN協議定位於爲穿透NAT提供工具,而不是一個完整的解決方案,英文全稱是Session Traversal Utilities for NAT,即NAT會話穿透效用。RFC5389與RFC3489除了名稱變化外,最大的區別是支持TCP穿透。socket
TURN,首先在RFC5766中定義,英文全稱是Traversal Using Relays around NAT:Relay Extensions to Session Traversal Utilities for NAT,即便用中繼穿透NAT:STUN的擴展。簡單的說,TURN與STUN的共同點都是經過修改應用層中的私網地址達到NAT穿透的效果,異同點是TURN是經過兩方通信的「中間人」方式實現穿透。tcp
NAT(Network Address Translation,網絡地址轉換)的原理ide
NAT網絡包含一個 NAT管理設備及該管理設備後面的網絡節點。工具
NAT網絡怎麼可以節約公網IP地址呢?這是由於它可以讓由私有IP構成的局域網內全部的計算機經過一臺具備公網IP和NAT功能的計算機進入公網(Internet),好比上網衝浪,這樣一個局域網就只須要一個或不多幾個公網IP就好了,從而達到了節約公網IP地址的目的。也許你要問了,爲何須要NAT呢?局域網的私有IP計算機不是可以經過網關直接進入公網嗎?非也,內網IP的數據包根本就不可能在公網上傳播,由於公網上的路由器都是屏蔽掉了這些私網IP的,這是由於私有IP原本就是人爲保留出來專供私有網絡通訊用的(RFC 1597中描述)。從另外一個角度說,即便私有數據包可以到達公網目標地址,目標地址的響應包也不可能返回真正的源地址,由於源地址是私有IP,目標發送的響應包一種多是被目標地址所在的擁有相同網絡號的內網接收,一種可能就是這種子網不存在,數據包被拋棄。因此內網數據包在進入公網以前,必須被翻譯成公網IP,這就是NAT網絡的功能,並且NAT技術發展到如今,已不只侷限於翻譯IP地址,如今實際翻譯時,它不光翻譯IP地址,還會翻譯TCP/UDP端口。因爲這個功能,NAT一般都位於網關計算機上,起着一種路由器的做用,爲了講述方便,之後咱們就稱這臺網關計算機爲NAT管理設備。下面就來看看NAT翻譯的基本過程(假如局域網192.168.0.0的NAT設備公網IP是218.70.201.185,私有IP是192.168.0.1,如今客戶機192.168.0.88要經過NAT管理設備訪問cn.yahoo.com的網頁,cn.yahoo.com的IP是202.43.216.55)。
當客戶機192.168.0.88經過IE向 http://cn.yahoo.com發出請求時,它發出的數據包含有下面的信息:
源地址和源端口:192.168.0.88:1234
目標地址和目標端口:202.43.216.55:80
當這個數據包到達NAT管理設備時,它會檢測到這個數據包是要發向公網的,因此它會對源IP地址和端口進行修改(翻譯),並在映射表中新建IP和端口的映射條目,而後再把修改的數據包轉發出去,下面就是修改後數據包的相關信息。
源:218.70.201.185:8999
目標:202.43.216.55:80 (無需變)
當cn..yahoo.com響應時,它會把數據包發給NAT管理設備,它的數據包含有下面的信息,
源:202.43.216.55:80
目:218.70.201.185:8999
當NAT管理設備收到響應時,它會檢查它的IP地址/端口映射表,而且會找到218.70.201.185:8999與192.168.0.88:1234的映射條目,因而它又修改數據包,而後把數據包轉發給192.168.0.88。相關數據包信息以下:
源:202.43.216.55:80
目:192.168.0.88:1234
具體的翻譯步驟就如圖1所示,其中圖1黑線左側是內網發向公網的翻譯過程,右側則是公網發向內網的翻譯過程,從中能夠看出,翻譯過程也是從上層向下層進行的。
從上面能夠看出,最開始發起鏈接的內網計算機(這裏是192.168.0.88)對網關進行NAT翻譯是一無所知的,它根本就不知道網關對它的數據包「作了手腳」,上面所講的能夠說是最理想的翻譯,這種翻譯對IP地址和端口信息只存在於IP首部和TCP/UDP首部的數據包是很是適合的,但偏偏這個世界是複雜的,網絡世界也不例外,每種技術都會有它的缺陷,下面就來看看NAT所面臨的網絡鏈接問題。ui
NAT有4種不一樣的類型spa
1) Full Cone
這種NAT網絡內部的機器A鏈接過外網機器C後,NAT會打開一個端口.而後外網的任何發到這個打開的端口的UDP數據報均可以到達A.無論是否是C發過來的.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000)
任何發送到 NAT管理設備(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000)
2) Address Restricted Cone
這種NAT網絡內部的機器A鏈接過外網的機器C後,NAT打開一個端口.而後C能夠用任何端口和A通訊.其餘的外網機器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
任何從C發送到 NAT管理設備(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000)
3) Port Restricted Cone
這種NAT網絡內部的機器A鏈接過外網的機器C後,NAT打開一個端口.而後C能夠用原來的端口和A通訊.其餘的外網機器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
C(202.88.88.88:2000)發送到 NAT管理設備(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000)
以上三種NAT通稱Cone NAT(圓錐形NAT).咱們只能用這種NAT進行UDP打洞.
4) Symmetric(對稱形)
對於這種NAT。鏈接不一樣的外部Server,NAT管理設備打開的端口會變化。也就是內部機器A鏈接外網機器B時,NAT管理設備會打開一個端口,鏈接外網機器C時又會打開另一個端口。
對於雙方都是Port Restricted Cone NAT的時候,則須要利用UDP打洞原理進行「先打洞,而後才能直接通訊」。
對 於Cone NAT.要採用UDP打洞.須要一個公網機器server C來充當」介紹人」.處於NAT以後的內網的A,B先分別和C通訊,打開各自的NAT端口.C這個時候知道A,B的公網IP: Port. 如今A和B想直接鏈接.好比A給B直接發包,除非B是Full Cone,不然不能通訊.反之亦然.
爲何啊?由於對於處於NAT管理設備以後的A,B。 若是想A要與外界的D通訊,則首先必需要A發包到D,而後A通過NAT管理設備NA,NA把A的內網地址和端口轉換爲NA的外網地址和端口。和D通訊以後,D 才能通過NA和A通訊。也就是說,只能A和外界主動通訊,外界不能主動和處於NA以後的A通訊。這種包會被NA直接丟棄的。這也就是上面所說的Port Restricted Cone 的情形啊! A(192.168.8.100:5000) -> NA(202.100.100.100:8000) -> D(292.88.88.88:2000)可是咱們能夠這樣.
A --- NA --- Server C --- NB --- B
注意: 路由器和防火牆的UDP打洞的端口有個時間限制的,在必定時間內若是沒有數據通信會自動關閉
STUN
STUN 的全稱是Simple Traversal of UDP Through NAT,即UDP對NAT的簡單穿越方式。應用程序(即STUN CLIENT)向NAT外的STUN SERVER經過UDP發送請求STUN 消息詢問自身的轉換後地址,STUN SERVER收到請求消息,產生響應消息,響應消息中攜帶請求消息的源端口,即STUN CLIENT在NAT上對應的外部端口。而後響應消息經過NAT發送給STUN CLIENT,STUN CLIENT經過響應消息體中的內容得知其在NAT上對應的外部地址,而且將其填入之後呼叫協議的UDP負載中,告知對端,同時還能夠在終端註冊時直接注 冊這個轉換後的公有IP地址,這樣就解決了H.323/MGCP/SIP穿越NAT的通訊創建問題以及做爲被叫時的問題。本端的接收地址和端口號爲NAT 外的地址和端口號。因爲經過STUN協議已在NAT上預先創建媒體流的NAT映射表項,故媒體流可順利穿越NAT。
須要注意的是,NAT/PAT 對於地址轉換關係是有必定生命期的,某個地址轉換後在一段時間內沒有被使用將會被清除,當這個業務流再次出現時,將會創建一個新的地址轉換關係,這就意味 着STUN的詢問過程以及終端的註冊過程都須要再執行一遍才能保證通訊的正確。解決這個問題一個比較通行的方案是採用某種方式保持NAT/PAT的轉換關 系,例如在NAT/PAT生命期內重複註冊一次,好比NAT/PAT的生命期是3分鐘,那麼就將註冊重複週期設置爲2分鐘。
另外STUN server並不是指一個專用的服務器,而是指一種功能、一個協議,咱們能夠在softswitch或者任何一個須要此功能的服務器上內置此協議, 後面代碼也包含一個簡單的Server實現。
但 是在NAT採用對稱模式(symmetric NAT)工做時,STUN的方案就會出現問題。假如咱們在softswitch上提供STUN server功能,終端A經過STUN能夠得到NAT爲終端A與softswitch之間通訊分配的地址A',並將這個地址註冊在softswitch 上,當一個公網上的終端B呼叫終端A時,A'和B經過softswitch完成呼叫創建過程。當B試圖向A'發送媒體流時,問題就出現了。由於對稱NAT 只容許從softswitch發送數據給地址A',從B發送的媒體流將被丟棄。因此STUN沒法應用於工做在對稱模式的NAT.
STUN協議最大的優勢是無需現有NAT/FW設備作任何改動,同時STUN方式可在多個NAT串聯的網絡環境中使用. STUN的侷限性在於STUN並不適合支持TCP鏈接的穿越,同時STUN方式不支持對對稱NAT(Symmetric NAT).
TURN
這 種方式又稱SPAN(Simple Protocol for Augmenting NATs)方式. TURN方式解決NAT問題的思路與STUN類似,也是基於私網接入用戶經過某種機制預先獲得其私有地址對應在公網的地址(STUN方式獲得的地址爲出口 NAT上的地址,TURN方式獲得地址爲TURNServer上的地址),而後在報文負載中所描述的地址信息直接填寫該公網地址的方式,實際應用原理也是 同樣的。
TURN的全稱爲Traversal Using RelayNAT,即經過Relay方式穿越NAT,TURN應用模型經過分配TURNServer的地址和端口做爲客戶端對外的接受地址和端口,即私網 用戶發出的報文都要通過TURNServer進行Relay轉發,這種方式除了具備STUN方式的優勢外,還解決了STUN應用沒法穿透對稱 NAT(Symmetric NAT)以及相似的Firewall設備的缺陷,即不管企業網/駐地網出口爲哪一種類型的NAT/FW,均可以實現NAT的穿透,同時TURN支持基於 TCP的應用,如H323協議。TURN的侷限性在於全部報文都必須通過TURNServer轉發,增大了包的延遲和丟包的可能性.
ICE
ICE跟STUN和TURN不同,ICE不是一種協議,而是一個framework,它整合了STUN和TURN。
UPnP
UPnP是若干網絡協議的組合,主要用於設備的互聯,可是一種叫作Internet Gateway Device (IGD) Protocol的防火牆穿越技術是基於UPnP的。
http://blog.chinaunix.net/uid-11572501-id-2868684.html
STUN簡介 STUN(Simple Traversal of UDP over NATs,NAT 的UDP簡單穿越)是一種網絡協議,它容許位於NAT(或多重NAT)後的客戶端找出本身的公網地址,查出本身位於哪一種類型的NAT網絡以後以及NAT管理設備爲某一個本地端口所綁定的Internet端端口。這些信息被用來在兩個同時處於NAT路由器以後的主機之間創建UDP通訊。該協議由RFC 3489定義。
一旦客戶端得知了Internet端的UDP端口,通訊就能夠開始了。
SIP之類的協議是使用UDP分組在Internet上傳輸音頻和/或視頻數據的。不幸的是,因爲通訊的兩個末端每每位於NAT管理設備以後,所以用傳統的方法是沒法創建鏈接的。這也就是STUN發揮做用的地方。
STUN是一個客戶機-服務器協議。一個VoIP電話或軟件包可能會包括一個STUN客戶端。這個客戶端會向STUN服務器發送請求,以後,服務器就會向STUN客戶端報告NAT路由器的公網IP地址以及NAT爲容許傳入流量傳回內網而開通的端口。
以上的響應同時還使得STUN客戶端可以肯定正在使用的NAT類型——由於不一樣的NAT類型處理傳入的UDP分組的方式是不一樣的。四種主要類型中有三種是可使用的:徹底圓錐型NAT、受限圓錐型NAT和端口受限圓錐型NAT——但大型公司網絡中常常採用的對稱型NAT(又稱爲雙向NAT)則不能使用。
NAT工做原理:NAT主要的經過對數據包頭的地址替換來完成內網計算機訪問外網服務的。當內部機器要訪問外部網絡時,NAT管理設備把內部的IP1與端口號1(網絡層地址與傳輸層地址),轉換成NAT的外部IP2與新的端口號2,再送給外部網絡,數據返回時,再把目的爲IP2:端口2的數據包替換爲IP1:端口 1,送給內網機器。若通信協議的內容中有IP地址的傳遞,如FTP協議,NAT管理設備在翻譯時還要注意數據包內涉及協議地址交互的地方也要替換,不然協議就會出現地址混亂。在NAT管理設備中維護了這個要替換地址的映射表,並根據內部計算機的通信需求維護該表。外部網絡來數據包可否進入NAT,主要是看是否已經有可映射的表項,若沒有就會丟棄
NAT給P2P帶來的問題是:NAT只容許單方面發起鏈接,通信的雙方不是平等的,P2P網絡的基礎有了問題,具體的表現爲:
STUN標準中,根據內部終端的地址(P:p)到NAT出口的公網地址(A:b)的影射方式,把NAT分爲四種類型:
1. Full Cone:來自相同的內部地址的請求消息映射爲相同的外部地址,與外部地址(目的地址)無關。映射關係爲P:p↔A:b,任何外部主機可經過(A:b)發送到數據到(P:p)上。
2. Restricted Cone:來自相同的內部地址的請求消息映射爲相同的外部地址,返回的數據只接受該內部節點曾發數據的那個目的計算機地址X。映射關係爲P:p↔A:b↔X,只有來自X的數據包纔可經過(A:b)發送到數據到(P:p)上。
3. Port Restricted Cone:來自相同的內部地址的請求消息映射爲相同的外部地址,返回的數據只接受該內部節點曾發數據的那個目的地址X:x。映射關係爲 P:p↔A:b↔X:x,只有來自X:x的數據包纔可經過(A:b)發送到數據到(P:p)上。
4. Symmetric(對稱) NAT:只有來自相同的內部地址(P:p),而且發送到同一個地址(X:x) 的請求消息,才被映射爲相同的外部地址(A:b),返回的數據只接受該內部節點曾發數據的那個目的地址X:x。映射關係爲P:p↔A:b↔X:x,當 (P:p)訪問(Y:y)時,映射爲P:p↔B:c↔Y:y。
P2P利用STUN穿越NAT:
位於NAT後面終端A與B要穿越NAT直接通信,能夠藉助在公網上的第三者Server來幫助。
穿越NAT的狀況分爲爲兩種方式:
一、一方在NAT管理設備以後,一方在公網上。這種狀況相對簡單,只要讓NAT管理設備以後的終端先發起通信,NAT管理設備就沒有做用了,它能夠從Server上取得另外一個Peer的地址,主動鏈接,回來的數據包就能夠方便地穿越NAT。
二、雙方都在NAT管理設備以後,鏈接的成功與否與兩個NAT網絡的類型有關。
主要的思路的先經過終端與Server的鏈接,得到兩個終端在NAT管理設備的外部地址(IP與端口號),再由終端向對方的外部地址發邀請包,獲取本身與對方通信的外部地址,俗稱爲「打洞」。關鍵是獲取了NAT管理設備外部映射的地址,就能夠發包直接溝通,創建鏈接。但當一方是對稱型,另外一方是Port Restricted或對稱型時,沒法有效獲取外部地址,邀請包沒法到達對方,也就沒法穿越NAT。具體的分析能夠根據兩個NAT網絡的類型分紅若干狀況分析,這裏給通常的穿越例子。
實例:UDP穿越NAT管理設備:
A登陸Server,NAT管理設備A 分配端口11000,Server獲得A的地址爲100.10.10.10:11000 (其實是NAT管理設備A的地址和端口)
B登陸Server,NAT管理設備B 分配端口22000,Server獲得B的地址爲200.20.20.20:22000
此時B會把直接來自A的包丟棄(A也會直接把來自B的包丟棄),因此要在NAT管理設備B 上打一個方向爲A的洞,那麼A就能夠向200.20.20.20:22000發送數據了
打洞的指令來自Server。即Server告訴B向A的地址100.10.10.10:11000發一個UDP報文,被NAT管理設備A 丟棄,但在NAT管理設備B上創建了映射記錄,NAT管理設備B不在丟棄來自A的報文。
Server通知A當即與B進行通信,A發起數據UDP包給B,NAT管理設備B放行,B收到A的包,雙方開始通信
注:如果對稱NAT網絡,當B向A打洞的端口要從新分配(NAT A不會再分配11000端口),B沒法獲取這個端口,因此不適用本方法。
實例:TCP穿越NAT:
tcp打洞與udp打洞的區別:tcp在傳輸數據前要connect,connect 過程當中兩方要通訊
A登陸Server,NAT管理設備A 分配端口11000,Server獲得A的地址爲100.10.10.10:11000
B登陸Server,NAT管理設備B 分配端口22000,Server獲得B的地址爲200.20.20.20:22000
Server告訴A向B發送TCP數據包 SYN:192.168.10.11:1234 => 200.20.20.20:22000,在NAT管理設備A上打洞
Server再告訴B向A發送TCP數據包 SYN:192.168.20.22:1234 => 100.10.10.10:11000,在NAT管理設備B上打洞
通道創建,A與B三次握手創建TCP鏈接
TCP(傳輸控制協議)和UDP(用戶數據報協議是網絡體系結構TCP/IP模型中傳輸層一層中的兩個不一樣的通訊協議。
TCP:傳輸控制協議,一種面向鏈接的協議,給用戶進程提供可靠的全雙工的字節流,TCP套接口是字節流套接口(stream socket)的一種。
UDP:用戶數據報協議。UDP是一種無鏈接協議。UDP套接口是數據報套接口(datagram socket)的一種。