2009年10月18日 星期日

NAT Traversal

COdE fr3@K » Blog Archive » NAT Traversal, part 0
NAT Traversal, part 0
Posted on September 20th, 2006 at 1:43 by fr3@K

根據 wikipedia 的定義, 一個 peer-to-peer (p2p) computer network 是一個主要依賴該網路上參與者 (相對於依賴服務器) 的運算能力與帶寬的網路.


P2p 網路的達成主要有兩個困難點:

1. Signal, 一個 peer 如何找到另一個 peer 並與其溝通
2. P2p 資料傳輸

達成第一點的方法, 也就是使用的 signalling protocol 有很多, 現階段的規範也比較成熟完善. 例如 SIP 與 IMS. 相對來說, p2p 的資料傳輸是更走在技術的前沿.

無論原因為何, 大多數的裝置 (通常是電腦) 不是直接連上 Internet, 而是透過 NAT 或 NAPT (以下均稱為 NAT) 連上 Internet. 在這種情況下, NAT 的穿透 (NAT traversal) 成為了 p2p 資料傳輸的前提.

這些在 NAT 後面的裝置沒有公網 IP, 如不利用服務器轉送, 傳統上幾乎沒有廣泛通用的方法1 從一台這樣的裝置把資料傳輸資料到另一個這樣的裝置.

技術是一直在往前走的, 現在, IETF 的 behave , midcom 與 mmusic 等 working group 已提出在多數狀況下達到 p2p 資料傳輸的方法 (protocol). 在開始進入這些方法之前, 對 NAT 的相關行為必須要有透徹的了解.

這一系列的 NAT Traversal 將從了解 NAT 的行為開始, 到 STUN 與 TURN, 計畫會在 ICE 以及 ICE 在 SIP 的應用劃下句點.

繼續閱讀 NAT Traversal, part 1 – NAT Behavior.

1. 部份 NAT 支持由 Micro$oft 提出的 UPnP, 在應用程式也支持時也可達成 NAT traversal. UPnP 的功能包山包海, 因此其最大缺點為肥大以及容易產生安全漏洞. [↩]
COdE fr3@K » Blog Archive » NAT Traversal, part 1 – NAT Behavior
NAT Traversal, part 1 – NAT Behavior
Posted on September 21st, 2006 at 1:12 by fr3@K

續自 NAT Traversal, part 0.

NAT (不包含防火牆) 處理 UDP 封包的行為中, 對 p2p 影響最大的兩類為:

1. External Port Mapping
2. Filtering


exteranl-port-mapping.640x550.png

External Port Mapping 指的是當使用內部同一個端口 (L:l) 對外部發封包的時候, NAT 對外面是否使用同一個端口 (N:?):

* 若 NAT 對外使用的都是同一個端口 (n1 == n2 && n2 == n3), 則該 NAT 的 External Port Mapping 行為是 endpoint independent (與外部端點無關).
* 若只有在外部端點 IP 不變只變 port 的情況下, NAT 對外使用的都是同一個端口 (n1 == n2 && n2 != n3) 則該 NAT 的 External Port Mapping 行為是 address dependent (與外部端點地址有關).
* 若對任何不同的外部端點 NAT 對外使用的都不是同端口 (n1 != n2 && n2 != n3 && n1 != n3) 則該 NAT 的 External Port Mapping 行為是 address port dependent (與外部地址與端口都有關).

filtering.640x550.png

Filtering 指的是在不考慮封包掉了的情況下, 當一個位於內部的端口 (L:l) 對外部的一個端口 (X:x1) 發了封包, 外部不同端口 (X:x1, X:x2 and Y:y) 對 NAT 上 map 出來的端口 (N:n) 發封包時的過濾行為:

* 若內部端口都能收到任何外部端口所發的封包, 則 該 NAT 的 Filtering 行為是 endpoint independent.
* 若內部端口能收到外部同一個 IP 的另一個端口 (X:x2) 所發的封包, 則該 NAT 的 Filtering 行為是 address dependent.
* 若內部端口僅能收到外部同一個 IP 固定端口 (X:x1) 所發的封包, 則該 NAT 的 Filtering 行為是 address port dependent.

在所有 NAT 上, 這兩類行為都同時存在. 但組合起來時, 不是如直覺般產生九種組合 (3 X 3 的矩陣). 細想一下就會知道只能有六種組合:

* External Port Mapping 為 endpoint independent 時, Filtering 可為 endpoint independent, address dependent 或 address port dependent.
* External Port Mapping 為 address dependent 時, Filtering 可為 address dependent 或 address port dependent.
* External Port Mapping 為 address port dependent 時, Filtering 只能是 address port dependent.

繼續閱讀 NAT Traversal, part 2 – STUN.
COdE fr3@K » Blog Archive » NAT Traversal, part 2 – STUN
NAT Traversal, part 2 – STUN
Posted on October 1st, 2006 at 23:46 by fr3@K

續自 NAT Traversal, part 1 – NAT Behavior.

Intro

STUN 是個非常簡單的 protocol. 就只一種功能性的 request - Binding Request1. 可以先簡單想像為 ping, 不同之處在於 server 的 response 會將 client 發出 request 的 source ip:port 放在裡面回應.


當 client 收到 response, 從中得到 server 稍早 `看到’ request 的 source ip:port 可大略分為兩種狀況:

* 與 client 發出 request 封包的 ip:port 一樣, client 可藉由這種狀況發現自己擁有公網 ip.
* 與 client 發出 request 封包的 ip:port 不同, client 可藉由 response 知道發出 request 的私網 ip:port 被 NAT 被 map 成外部的那個端點. 這也正是這個 request 叫做 Binding Request 的原因.

絕大多數的 protocol, server 都會用收到 request 的 ip:port 來發出 response 以回應 client. STUN 特有一個很有趣的 attribute, 叫做 CHANGE-REQUEST. 用來要求 server 回應 client 的時候, 換一個 port (ip 不變) 或是換一個 ip 發送 response.

藉由把 STUN daemon 跑在一個 ip 的兩個 port 以及第二個 ip 上, client 就可以藉此了解它所處內網對外的 NAT 對 p2p 傳輸最具影響力的兩種行為; External Port Mapping 以及 Filtering.

External Port Mapping

Client 先用同一個 port 對 server 的兩個 ip (X:x1 and Y:y) 各發送一個 Binding Request, 如果兩個 response 顯示的 source ip:port 一樣 (N:n1 == N:n3), 則該 NAT 的 External Port Mapping 行為是 endpoint independent. 若不一樣, 就再對 server 在其中一個 ip 的第二個 port (X:x2) 發送一個 Binding Request, 如果這次的 response 回應的 source ip:port 與第一個 response 一樣 (N:n1 == N:n2), 該 NAT 的 External Port Mapping 行為是 address dependent. 否則為 address port dependent.

Filtering

等一段時間之後2, 接著 client 對 server 的一個 port (X:x1) 發送兩個 request, 其中第二個 request 要求 server 以不同 ip (Y:y) 回應. 如果 server 能收到第二個 request 的 response, 那表示該 NAT 的 Filtering 行為是 endpoint independent. 若收不到, 則再發一個 request, 要求 server 以同一個 ip 的另一個 port (X:x2) 回應, 如果這次收到了response, 這個 NAT 的 Filtering 就是 address dependent, 否則為 address port dependent.

External Port Mapping 與 Filtering 都是 endpoint independent 的 NAT 對 p2p 傳輸而言最為有利. 任何端點 (X:x1) 跟你通信之後, 可以直接把你 NAT 外部端點 (N:n1) 告知第三者, 第三者就能直接發送 (Y:y) 訊息給你. 只要 External Port Mapping 是 endpoint independent, 即使 Filtering 是 address port dependent, 也很容易克服, 跟你通訊的端點除了把你的外部端點告知第三者之外, 只要把第三者用來發送訊息的端點 (Y:y) 告訴你. 讓你能向那個端點發送個封包就能把 Filtering 的限制解除.

繼續閱讀 NAT Traversal, part 3 – TURN.

1. 實際上有兩種 request, 只是另一個 request 用途是認證, 與功能性無關. [↩]
2. 等一段時間的目的是讓 client 對外的 binding 超時, 否則第二輪測試完全無意義. 但要如何知道 binding 的超時為多少時間呢? 就留給你做功課吧. [↩]
COdE fr3@K » Blog Archive » NAT Traversal, part 3 – TURN
NAT Traversal, part 3 – TURN
Posted on April 14th, 2007 at 15:53 by fr3@K

續自 NAT Traversal, part 2 – STUN.

像是 MSN messenger 等的傳統 IM (Instant Message) 網路, 其 server 只負責少許的任務, 絕大部分的工作都是一個 client 節點與別的 client 節點之間的事情. 即便如此, 在這種網路之中, 每一個 client 還是從頭到尾都是與 server 溝通, 從來不會直接對另一個 client 收發訊息. Server 除了一開始對 client 認證, 後續除了 relay (轉發) 訊息與 data (例如檔案傳輸) 之外, 幾乎就沒別的任務. 對 service provider 來說, 這種架構可說是非常浪費網路資源. 每一個經過 server relay 的封包, 都代表對 service provider 頻寬與計算能力的損耗.


這種應用之所以會採用如上述對 service provider 的 core network 負擔較大的網路架構, 最主要是因為其 client 大都在 NAT 後面, client 與 client 之間無法有效建立直通的連線 (direct connectivity). 在這種網路架構之下, 由於沒有其他明顯缺點, 常會把 signal 通道與 data 通道 multiplex 在一個 connection 裡面.

若一個 application 把 signal 與 data 分開 (如 SIP + RTP), 就可以利用 TURN (STUN relay, formerly known as Traversal Using Relay NAT), 一種泛用 (generic) 的 relay protocol. 早期的 TURN 與 STUN 類似但稍微複雜的 protocol. 在 新版本的 STUN draft 中, 已經把 TURN 納入為 STUN 的一種 usage (可視為一種 extension). 說明了兩種 protocol 之間的血緣關係. 也是 protocol 作者 在發表早期 TURN draft 時, 表明希望可以大量利用 STUN 的基礎, 發揮到最大的一種表現.

TURN 的特點是 TURN client 必須知道對方 (external peer) 使用的 transport parameter (e.g. ip:port). 才能使 TURN server 開始 relay. 假設一個 client 透過某個 signal router 與 Media Server 交換 transport parameter. TURN client, TURN server 與 Media Server (此例的 external peer). 三者的網路架構與互動流程如下圖:

TURN Architecture/Flow

Click to ZOOM or open in a new window.

首先 TURN client 對 TURN server 以 Allocate Request 做 port allocation 的動作 (1~2). 得到了 TURN server 上 allocate 給 client 的 port 之後就可以開始與 Media Server 的 offer/answer (3~6). Offer/answer 完成後 client 會得到 Media Server 的 transport parameter, 然後再藉由 Set Active Destination Request 通知 TURN server 對方的 transport parameter (7~8). 之後 Media Server 發送到 TURN server 特定端口的封包 (9) 都會被 relay 到 TURN client (10).

TURN server 除了 relay 之外, 與 TURN client (建立 TURN session 的 client) 之間仍會用少數的 request/indication/response 溝通. 但對 external peer (另一邊的端點) 卻是 transparent. 換句話說, 對 external peer 來說, TURN server 上的某個特定端點的表現, 就如同是 TURN client 就跑在這個端點上. 即便如此, 一個在 TURN client, 在 NAT 後面的節點, 無法透過 TURN server 變成一個隨意接受第三方 message 的 server. 在 TURN client 還沒有經由 Send Indication 或 Set Active Destination Request 來把某個 external peer 加入 TURN session (on TURN server) 上的 permission list 之前, 這個 external peer 送到 TURN server 的封包都不會被 relay 回 TURN client (i.e. discard).

如果兩邊都使用 TURN, 則兩邊各自都是不同 TURN session 的 client, 與它們對應的 external peer 則是對方使用的 TURN server. 下圖中兩個 client 各自建立了一個 TURN session 來與對方溝通, 對於 Client A 在 TURN (server) A 建立的 session (Session A) 來說, Client A 是這個 session 的 client, TURN (server) B 是 external peer. 反之亦然:

turn-both.640.png

Click to ZOOM or open in a new windows.

這個例子還有個有趣的地方, 在 TURN A 到 Client A 與 TURN B 到 Client B 這兩段跑的是 TURN, 但在兩個 TURN server 中間跑的卻是原本的 data protocol (non-TURN’ed). TURN A 與 TURN B 都不會知道對方是個 TURN server, 它們只當 external peer 就跑在另一個 TURN server 的特定端口上.

TURN 支援在同一個 session 裡面同時對多個 external peer 溝通. 除了 active destination (preferred external peer) 之外, 與不同的 external peer 往來訊息時, 對方發給 TURN client 的封包會被包在 Data Indication 裡. 而 TURN client 則透過 Send Indication 來 encapsulate 發給非 active destination 的封包. 這兩種 indication 都包含了 REMOTE-ADDRESS 這個 attribute, 用以表示 external peer 的位址 (i.e. ip:port). 對 active destination 收發訊息時則不需要經過 encapsulation.

雖然單純採用 TURN 並沒有辦法降低對 core network 整體頻寬與計算能力的消耗, 但可以藉由把 signal routing 與 data relay 分佈在不同的 core network 節點, 達到分散 network I/O 與 computation 的效果.

預告: NAT Traversal, part 4 – ICE.

沒有留言: