一、NAT
NAT(Network Address Translator),網絡地址轉換。NAT是在IPv4地址日益缺乏的情況下產生一種緩解地址問題的方案。它的主要目的是為了地址重用。 NAT的基本思想是,由NAT設備(比如家用路由器)修改從私有網絡發送到互聯網的IP報文的源地址字段,以及修改從互聯網發送到私有網絡的IP報文的目標字段。分為兩類,一類是基本NAT,一類是NAPT(Network Address/Port Translator)。
基本NAT就是將這個節點的子網內IP轉化為一個全球唯一的IP,然后發送出去。(基本NAT會改變原IP包中的ip地址,但不會改變端口)。NAPT也會改變端口。目前基本全是NAPT。
舉例,如果某台內網的設備A經過網關(NAT設備)想要訪問外網Server,首先NAT有一個全球唯一IP地址,會將設備A發送給NAT的數據報中的IP地址修改為這個全球唯一IP地址,接着NAT設備會為這個設備創建一個session(一個抽象概念),並且為這個session創建一個端口,比如10000,然后改變這個數據包的源端口為10000.與此同時,NAT會記住端口與設備A的對應關系,從Server接收到的消息也會轉發到設備A上。
二、NAT類型
假設設備A需要訪問Server2,此時如果NAT再次創建session和端口號,則稱為Symmetric NAT;如果NAT創建session復用端口號的話,稱為Cone NAT。目前Symmetric NAT較少見,絕大多數是Cone NAT。
而Cone NAT又分為3種:
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包發送給該內部主機(在2的基礎上多了端口限制)。
可以看到內部向外部訪問比較容易,但外部想訪問內部較困難。怎么做呢?首先,必須在內網的NAT上打一個“洞”。這個洞不能由外部來打,只能由內網主機來打,而且這個洞是有方向的(時刻記住,打洞是為了讓對方的數據過來)。比如從內部某台主機IP A向外部某個IP B發送一個UDP包,那么就在這個內網NAT設備上打了一個方向為外網IP B的洞。以后外網IP B就可以通過這個洞與內網IP A聯系了。
舉例,如果Client A想向Client B發送信息,那么Client A發送命令給Server S,請求Server S命令Client B向Client A方向打洞。然后Client A就可以通過Client B的外網地址與Client B通信了。注意,僅僅是Client A和Client B互相知道對方的IP地址和端口,那么雙方是否可以跳過Server S直接通信了呢?答案是不行的。因為出於安全原因,NAT對於這種不請自來的信息一般是會執行丟棄動作。
三、STUN
STUN(Session Traversal Utilities for NAT, NAT會話穿透工具)是一種網絡協議,目的就是進行NAT穿透。它使用RFC5389自動探測當前的NAT類型、IP和端口(RFC5389是在RFC3489的基礎上改進而來,解決了3489 UDP穿透失敗的一些問題)。
1. STUN協議
包含20個字節的STUN header和0或者多個的Attribute的STUN body;
a. STUN header
STUN Message Type:2個字節(16bit)類型;前2位必須是00;2位用於分類(c0和c1),包含4種類型(請求、指示、成功應答、錯誤應答),剩下的12位用於定義請求和指示。
- 0b00:請求
- 0b01:指示
- 0b10:請求成功的響應
- 0b11:請求失敗的響應
0x0001 綁定消息
0x0101 綁定響應
0x0111 綁定錯誤
STUN Message Length:2個字節(16bit)消息長度,注意,這里的長度不包括消息頭;
Magic Cookie:魔法數,4個字節,固定值0x2112A442,可以通過此魔法數識別一些屬性
Transaction ID:12個字節(96bit)事務ID,請求與服務器返回的響應事務ID相同;
b. STUN body
每個消息頭后有0或者多個屬性,屬性有12種
每個屬性進行TLV編碼:Type(2字節),Length(2字節),Value。
2. STUN探測步驟
設備A,NAT B,Server C有兩個IP:IPC1,IPC2.
a. A向IPC1發送一個UDP包,C收到后返回給A一個UDP包。當A收到此UDP包后,把此UDP中的IP和自己的IP做比較,如果是一樣的,說明自己在公網;如果不一樣,說明有NAT存在,執行2;
b. A向IPC1發送一個UDP包,請求IPC2向A返回一個UDP包,如果A收到了這個UDP包,說明NAT來者不拒,即full cone NAT.如果不是,則執行3;
c. A向IPC2發送一個UDP數據包,IPC2返回一個UDP包。分析UDP包中的port,如果和1返回UDP包中的port一樣,則為cone NAT,否則為 symmetric NAT;
d. A向IPC2的一個端口port1發送數據包,要求IPC2使用不同於port1的端口port2發送數據包給A,如果A收到了,則為restricted NAT;如果A沒收到,則為port restricted NAT.
只要任意一台主機處於對稱型NAT或對稱型UDP防火牆后面就無法建立P2P連接,需要使用服務器進行中轉,這就是TURN。(也就是說STUN不需要中轉的穿透協議,TURN是需要中轉的穿透協議?)
四、TURN
TURN(Traversal Using Relay NAT),是一種資料傳輸協議, 允許在TCP或UDP的連線上跨越NAT或防火牆,保障雙方能夠百分之百進行通信。TURN是STUN的擴展,允許一個peer只使用一個relay address就可以和多個peer實現通信。TURN為每個peer分配一個中繼地址,其他peer向A的中繼地址發數據,TURN Server就會把數據准發給A(也就是說,數據經過了TURN Server的中轉)。
五、ICE
ICE(Interactive Connectivity Establishment),一種綜合性的NAT穿透技術,是一種framework,可以整合各種NAT穿透技術,如STUN、TURN等。該framework可以讓sip客戶端利用各種NAT穿透方式打穿遠程的防火牆。ICE方式能夠在不增加整個系統復雜性和脆弱性的情況下,實現對各種形式的NAT進行穿透,使得媒體流在通信雙方順利傳輸。