我先寫一下NAT的基本概念,NAT的類型。接下來再仔細談主要的NAT解決方案STUN,由於STUN有許多不完美的地方,所以還有後的版本,叫做TUNE,這留到以後有需要的時候再寫。
一、NAT (Network Address Translation)
先談一下NAT,為了解決IP Address不足的問題,大部份的IPv4網路都使用NAT的方式來提供TCP/IP的連線服務。簡單來說,家庭網路的路由器100%都具備有NAT的功能。所以例如我們的Router有四個LAN PORT,一個WAN Port。這個WAN Port被賦予一個唯一的Public IP (或是說合法的IP),而LAN的部分被設定為Local IP (或稱之為 Private IP)。Router的NAT功能,可以讓所有的Private IP都可以透過轉換連接到全世界所有的具備合法IP的電腦主機。
依照RFC 1918的定義,Private IP可以依照不同大小的網路,選擇Private IP的規劃:
- Class A: 10.0.0.0 ~ 10.255.255.255
- Class B: 172.16.0.0 ~ 172.31.255.255
- Class C: 192.168.0.0 ~ 192.168.255.255
Class A/B 大都提供給企業使用,而Class C大都是提供給家庭網路使用。
由於Private IP見不了光,所以就要倚靠 Router 的NAT的機制。基本上,Router會建立一個NAT Table。把眾多的連線需求,利用 “Socket Port”,對應到同一個Public IP的不同Port上面。
下圖簡單的描畫出NAT的做法。
在Router上面會建立一個NAT Table,當作內網與外網的資訊傳遞橋梁。基本上每次的連線,都是由位於Intranet的設備來啟動連線,以上面的例子來說,
- Host A要與位於 IP 162.100.7.34的伺服器連線,連線的封包,會自動交給位於 10.1.1.1 (Default Route)的NAT Router做處理。
- 位於Router上的NAT功能自動會找出一對內外網的Port,建立一個NAT Table。
- 然後Router代理Host A向Server發出連線請求,Server也對Router做出回應。
- Router再將資訊轉送給Host A。
如果Server沒有回應,NAT Table之中的連線紀錄,在一定的時間後,便會自動清除。這時候連線就會失敗。但這與 Host A上的Client沒有關係,Client會因為自已的Time Out而結束連線。Router一樣會在一段時間之後,回收表格的資訊。
NAT有四種不同的連線機制,必須要說明清楚:
1. Full Cone NAT
Full Cone 只是單純的做位址轉換,並未對進出的封包設限。一旦一個內部位址(Internal_IP_Addr:Port)對映到外部位址(External_IP Addr:Port)之後,所有發自Internal_IP_Addr:Port的封包都經由External_IP_Addr:Port向外傳送。任意外部主機也都能通過給External_IP_Addr:Port發封包到達Internal_IP_Addr:Port。以上圖來說,一但Client A透過NAT與Server A進行連線成功之後,Server B也可以透過同一個 IP Address與Port,與Client取的聯繫。
這方法可以用一個例子來做更詳細的說明。假設Client是CWMP Agent、Server A是STUN SERVER。SERVER B是ACS SERVER。
CWMP Agent先與STUN聯繫上,取得我目前使用的Public IP連線的IP Address與Port是139.223.200.200:1920。然後,STUN告訴ACS SERVER,有人在139.223.200.200:1920等你下命令,這時候ACS就可以與CLIENT取的聯繫了。第二種方式也可以由CLIENT得到自己的IP Address之後,趕快告訴ACS SERVER,麻煩到這個IP ADDRESS聯繫我。
2. Restricted Cone NAT (Address Restricted Cone)
Restricted Cone NAT 對於封包的進出稍加限制。從內部送出之封包的目的地 IP 位址會被記住,只有這些曾經收過這些封包的位址可以送封包進入NAT。由其他位址送進來的封包,都會被檔下。換言之, 只有收過NAT 內部送來的封包的地址才能將封包送入 Restrict Cone NAT 內。如果碰到這種類型的NAT,顯然上面的例子的一種連線方式就不可行,但是第二種方式還是可行的。
3. Port Restricted Cone NAT
Port Restricted Cone 對於封包進出比Restricted Cone 增加了一個限制, 從內部送出之封包的目的地的IP 位址及 Port Number 會被記住。 由外部送進來的封包,除了由那些接收過內部所送出 的封包的IP 位址及 Port Number 所送來的封包之外,都會被檔下。換言之, 只有收過NAT 內部送來的封包的地址及 Port Number 才能將封包送入 Restrict Cone NAT 內。簡單來說,同一個IP Address,如果Port不一樣,就不准進來。當然Server B無論如何都無法與Client連線。
4. Symmetric NAT
Symmetric NAT 在四種Cone NAT中最為嚴謹。前三種NAT在做位址轉換時,無論封包是送往何處, Client的地址,連到NAT後,都對應到同一個外部位址。但在Symmetric NAT內則每一內部位址,連線到不同的目的地,都會對應到不同的外部位址(當然Port也不同)。隨著網路安全的要求越來越高,使用此種NAT有越來越多的趨勢。
講到這裡,NAT的缺點就很明顯了,包含:
- 每一份資料都要經過NAT做轉換,因此加重Router的Loading。
- Delay必然會增加。
- 外網的伺服器無法連接內網設備來讀取資訊。
- 只要是外網發起的連線服務都不可行,Web/FTP …
可以看到NAT如果不同,Client穿越NAT的方式也許會不同。這些解決方案稱之為NAT穿越技術(NAT Traversal),穿越技術一般會使用UDP來連線。
二、NAT穿越方案的選擇
我們目前想要解決的問題有三種:
- TR069與ACS Server連接時所遇到的困難。
- 使用者來到外網之後,想要用APP來管理家中的網路裝置。
- 未來還有VOIP打電話的應用要處理。
目前,根據對NAT支援的不同,處理機制的不同,常用的NAT的穿越方法,一般有分為以下幾種:
- ICE
- STUN
- TURN
- UPnP
- ALG
- SBC
這些方案都有其各自的特點,不同的應用軟體,會使用不同的的技術。大致上面向家庭用戶的應用,選擇簡單的NAT穿越方案,包含STUN、TURN、ICE三種。
大致上總結如下:
STUN 可以處理大部份的NAT問題。
TURN是STUN的加強版本,專門用來處理對稱型 的NAT穿越。
ICE 是 STUN與TURN的綜合體。
下面將集中討論最簡單的STUN。
三、STUN的流程機制
STUN是最簡單的架構。但常見的STUN其實還有兩個版本,比較舊的是RFC 3489 (叫做Classic STUN),後來又有RFC5389,稱之為New STUN。
事實上,這兩個東西都叫做STUN,事實上,完全不同,甚至連簡寫的意義都不同。
RFC 3489 (Classic STUN) = Simple Traversal of User Datagram Protocol (UDP) through Network address translators (NATs)
RFC 5389 (New STUN) = Session Traversal Utilities for NAT
在RFC 5389的規定中,RFC3489被定義為羽量級的工具,RFC3489在有幾個方面有所不足:
- IP 和 Port 有時可以作為Peer來進行通信,有時則不能,Classic STUN沒有提供準確的方法來處理這些問題。
- Classic STUN的演算法對多層NAT可能發生錯誤。
- Classic STUN存在安全性漏洞,駭客會利用某些 Port 重新映射時,進行位址或者Port的竄改。
根據RFC 5389對STUN所執行的增加功能包括:
• 用於ICE連接支援 (MMUSIC-ICE)
• 用於用戶端的初始化連接 (SIP-OUTBOUND)
• NAT行為發現 (BEHAVE-TURN)。
STUN 的用途簡單來說,就是要解決使用非法IP的內網程式(稱之為Client A),要使用位於路由器上面的NAT功能,將這個位於內網的程式(Client A),能正確的連接到外網的服務程式(下面的例子稱之為Client B)。
下面這個圖,簡單的說明一下 STUN 的作法:
但是上面的例子,只是讓Client找到了自己的外網連線IP Address與port。如果加上雲端應用程式,行為可以使用下圖來表示:
上圖當中,描述了連線的四個步驟:
- Client (位於內網的程式)內網程式通過NAT對STUN(STUN位於外網的Public IP)發出請求。
- STUN Server 使用UDP,預設埠是3478,送出一個回應。回應的訊息當中,包含了MAPPED-ADDRESS、RESPONSE-ORIGIN、OTHER-ADDRESS和XOR-MAPPED-ADDRESS這四個參數。為了支持NAT的映射和過濾行為機制,STUN伺服器必須支持兩個公網IP位址和兩個不同的埠,分別稱之為主訊息位址和可選訊息位址。
- 第三步,Client對位於外網的Signaling Server發出訊息,Signaling Server會將Client所使用的外網位址(IP Address)和連接埠(Port)資訊通知Server。
- 於是Server就可以使用這資訊對Client 發送資訊。其實也是分為兩段,Server先對NAT路由器發送訊息,路由器的NAT再轉發到Client 的Local IP/Port。
在上面的流程中,NAT是如何被檢測的?RFC 5780 規定了三個階段的NAT檢測方式:
這個測試,需要有STUN有兩個Public IP Address,能提供Client能利用以下方法,檢測試出NAT屬於哪一類型的NAT。
有兩種類型的請求:綁定請求(通過UDP發送)和共享密鑰請求(發送TLS (通過TCP))。共享秘密請求服務器返回一個臨時的用戶名和密碼。此用戶名和密碼用於在隨後的 Binding Request(綁定請求)和Binding Response(綁定響應),身份驗證和消息完整性的目的。
Test I:
STEP1.
Client發送一個STUN Binding Request到Server_IP1,但是在STUN封包屬性CHANGE-REQUEST與 RESPONSE-ADDRESS屬性,都不要設定任何的值。這會導致SERVER將NAT的地址和Port #,用SENDING RESPONSE,回覆給CLIENT。
STEP 2:
如果STEP 1的Response沒有反應,那就有兩種可能:
1、STUN服務器不存在,或者你弄錯了port。
2、Router的NAT拒絕由外部向內部發送的UDP封包(不支援Cone NAT)。
Client收到了Sending Response,Client便會檢查所收到UDP封包的MAPPED-ADDRESS屬性 。
STEP 3:
比對這個IP Address 、Port # 和 Client的Local IP Address/Port
STEP3.1:
如果這個IP Address 、Port # 和 Client的Local IP Address/Port完全相同,Client可以知道,它與SERVER之間,並沒有NAT的存在。這時候就繼續進行Test II (請跳到Test II部分看,去偵測防火墻的類型)。
STEP3.2:
如果IP地址不同的話,就知道自己是在NAT的後面,先把自己的IP/Port記起來,繼續進行STEP 4 。
STEP 4:
Client發送一個帶有”Change IP”和”Change port”的CHANGE-REQUEST屬性的Binding Request到Server_IP1,請求STUN Server 使用不同於 STEP1的 IP和 Port,端口來回應請求(記得嗎? STUN Server要準備兩個不同的IP地址)。
STEP4.1:
如果Client 收到了STUN Server用Server_IP2和Port2發送回來的UDP封包,那說明什麽?說明NAT來著不拒,不對封包進行任何過濾,這也就是STUN標準中的Full Cone NAT。
遺憾的是,因為安全的疑慮,實務中Full Cone NAT並不多見,這也意味著你能收到這個封包的可能性不大。如果沒收到,那麽系統進行STEP4的操作。
STEP 5:
Client再向STUN Server的Server_IP2地和Port2端口發送一個封包,Server收到封包後,把這個封包的Source IP和Port#寫到UDP包中,然後通過用Server_IP2和Port2把此包發還給Client。和 STEP1一樣,Client由於發完就在同一個位置上等待回應,所以肯定能收到這個由SERVER回應的UDP包。這封封包中的port是我們最關心的數據,下面我們來分析:
如果這個Port#和Step1中的Port#一樣,那麽可以肯定這個NAT是個”XXXX Cone NAT”,否則就是Symmetric NAT (對稱型)。
道理很簡單:根據對稱NAT的規則,當目的地址的IP和port有任何一個改變,那麽NAT都會重新分配一個port使用,而在Step4中,若與Step1的結果比較,NAT改變了IP和Port#。而對稱型NAT,那這兩個Port肯定是不同的。
如果在你的應用中,到此步的時候PORT是不同的,恭喜你,你的STUN已經死了,因為STUN無法處理Symmetric NAT。如果相同,那麽只剩下了Address Restricted Cone NAT和Port restricted Cone。進入STEP 5。
TEST III:
Client向Server的Server_IP2的Port # 發送設定為”change port”的CHANGE-REQUEST Attribute的Binding Request,要求Server用Server_IP2地址和不同於原先Port#,發送一個封包給Client。
我們來分析結果:如果Client收到了,那也就意味著只要IP相同,即使Port不同,NAT也允許UDP包通過。顯然這是Address Restricted Cone NAT。如果沒收到,沒別的可能,Port Restricted NAT。
Test II
Client發送一個帶有設定”Change IP”和”Change port”的CHANGE-REQUEST屬性的Binding Request到STUN Server_IP1,請求STUN Server 用不同於Test II Step 1的地址和端口來響應該請求。如果Client 收到了STUN server用server_IP2地址和port2端口發送來的UDP封包,那說明什麽? 說明NAT來著不拒,不對封包進行任何過濾,Client知道它是開放互聯網(或者,至少有一個防火牆,其行為像Full Cone NAT,但是沒有轉發)。
如果Client沒有收到Response,就知道它是在對稱的UDP防火墻後面(主機出口處沒有NAT設備,但有防火牆,且防火墻規則如下;從主機UDP端口A發出的封包保持源地址,但只有從之前該主機發出包的目的IP/PORT發出到該主機端口A的包才能通過防火牆)。
下面有一個流程圖,這是CWMP Agent (WAP-7531使用的是netcwmp),工作的流程圖,讓大家可以看一下實際工作的做法:
這個程式位於 cwmpd/src/httpd.c 當中:










沒有留言:
張貼留言