李筱楠 劉 洋 鄭 華
(石家莊鐵路職業(yè)技術(shù)學(xué)院 河北石家莊 050041)
近年來,基于P2P 技術(shù)的網(wǎng)絡(luò)應(yīng)用發(fā)展迅速,P2P 通信極高的帶寬利用率給用戶帶來了巨大的便利。而目前被大量部署使用在IPV4 網(wǎng)絡(luò)中的NAT 設(shè)備卻嚴(yán)重阻礙了P2P 應(yīng)用的發(fā)展。NAT 本身的工作特性,導(dǎo)致處于不同網(wǎng)絡(luò)環(huán)境中的主機無法建立有效的對等連接,主機之間的點對點通信變得很困難,也就意味著大部分P2P 應(yīng)用將無法運行在部署了NAT 網(wǎng)關(guān)的內(nèi)部網(wǎng)絡(luò)中。為了保證P2P連接在各種網(wǎng)絡(luò)環(huán)境的有效性,需要有一套行之有效的NAT 穿越方案。
NAT[1](Network Address Translation,網(wǎng)絡(luò)地址轉(zhuǎn)換)是一種在IP 數(shù)據(jù)包通過網(wǎng)關(guān)時重寫其源地址、目的地址的技術(shù)。這種技術(shù)被廣泛應(yīng)用于局域網(wǎng)中,供多臺主機共享一個公網(wǎng)IP 訪問Internet時用。NAT 不僅緩解了IPv4 地址緊缺的問題,而且能夠有效隱藏并保護內(nèi)部網(wǎng)絡(luò),使內(nèi)網(wǎng)主機免遭來自Internet 的掃描和攻擊。
NAT 的工作原理[2]如圖1 所示:內(nèi)網(wǎng)主機Client 通過NAT 向Internet 主機Server 發(fā)送數(shù)據(jù),當(dāng)數(shù)據(jù)經(jīng)過網(wǎng)關(guān)時,NAT 會自動修改該IP 報文頭部的源IP 和源端口,并在本地NAT 映射表中添加一條相對應(yīng)的映射關(guān)系,然后再將修改過的報文發(fā)送給Server。Server 回應(yīng)給Client 的數(shù)據(jù)同樣需要經(jīng)過網(wǎng)關(guān)的修改和轉(zhuǎn)發(fā),但是網(wǎng)關(guān)在轉(zhuǎn)發(fā)來自Internet 的數(shù)據(jù)時,會首先檢測NAT 映射表中有沒有與目標(biāo)地址相對應(yīng)的映射關(guān)系,如果有,則修改報文頭部并轉(zhuǎn)發(fā);如果沒有,則將報文丟棄。
NAT 的映射關(guān)系具有時效性。如果通信雙方采用TCP 連接,當(dāng)TCP 連接斷開時(網(wǎng)關(guān)收到Fin包),NAT 就會將該連接的映射關(guān)系從映射表中刪除;如果雙方采用UDP 通信,網(wǎng)關(guān)則會根據(jù)設(shè)置在一定時間后自動將NAT 映射關(guān)系刪除。
由于NAT 只對內(nèi)部網(wǎng)絡(luò)透明,導(dǎo)致通信雙方的連接建立過程只能從內(nèi)向外單方向發(fā)起,內(nèi)網(wǎng)主機能訪問Internet,卻不能作為服務(wù)器向Internet 提供服務(wù)。其原因在于:
圖1 NAT 工作原理
(1)內(nèi)網(wǎng)主機的IP 是私有IP,在Internet 上無效,這代表內(nèi)網(wǎng)主機對于Internet 來說是不可見的。
(2)即使內(nèi)網(wǎng)主機的公網(wǎng)地址已被其它主機獲知,但由于網(wǎng)關(guān)的NAT 映射表中沒有相應(yīng)映射關(guān)系存在, Internet 向內(nèi)部網(wǎng)絡(luò)發(fā)起的連接數(shù)據(jù)依舊會被NAT 丟棄。
因為同樣的原因,分屬不同局域網(wǎng)的主機若要實現(xiàn)互訪就更加困難,P2P 通信在建立連接的階段就被NAT 所阻斷。
目前,大多數(shù)的NAT 穿越方案都需要對現(xiàn)有網(wǎng)絡(luò)設(shè)備進行改造或升級,而且運行效率不高,對網(wǎng)絡(luò)傳輸速度的影響也比較大。相對較成熟的NAT 穿越方案有以下幾種:
ALG[3] (Application Level Gate,應(yīng)用層網(wǎng)關(guān))作為最早的NAT 穿越方案,ALG 是對NAT 技術(shù)的一種升級。NAT 只轉(zhuǎn)換IP 報文頭部的地址信息,而對報文數(shù)據(jù)中記錄的IP 和端口則不加處理。這就可能會導(dǎo)致一些需要在數(shù)據(jù)中發(fā)送連接消息的應(yīng)用層協(xié)議,如FTP、SIP、H.323 等,其地址信息在經(jīng)過NAT 轉(zhuǎn)發(fā)后變成了錯誤數(shù)據(jù)。而ALG 實現(xiàn)了對應(yīng)用層協(xié)議的識別,以及對報文內(nèi)部IP 地址、端口信息的轉(zhuǎn)換,在ALG 的作用下,各種應(yīng)用層協(xié)議數(shù)據(jù)可以正確地通過轉(zhuǎn)發(fā)。
ALG 方案實現(xiàn)簡單,缺點也非常明顯。其工作原理使得每次有新應(yīng)用層協(xié)議出現(xiàn),都需要對所有ALG 設(shè)備進行升級,以保證ALG 對該協(xié)議的識別和轉(zhuǎn)換。另外,ALG 轉(zhuǎn)換過程中需要分析數(shù)據(jù)包內(nèi)容,所以數(shù)據(jù)不能加密傳輸,傳送必須采用明文,安全性較差。而且,ALG 的處理速度緩慢,可能導(dǎo)致整個網(wǎng)絡(luò)堵塞。
MIDCOM[4](Middle-Box Communications)是由IETF 制定的一種NAT 穿越方案,該方案解決了ALG 可擴展性弱及轉(zhuǎn)發(fā)效率低的問題。MIDCOM 由兩部分組成:部署于網(wǎng)關(guān)的Middle-Box 和部署于可信第三方的MIDCOM Agent。MIDCOM 的基本思想是:通過MIDCOM 協(xié)議連接Middle-Box和MIDCOM Agent,應(yīng)用層協(xié)議的識別和地址信息的轉(zhuǎn)換由MIDCOM Agent 完成,Middle-Box 只需要接受MIDCOM Agent 的控制打開或關(guān)閉端口即可。
數(shù)據(jù)的集中化處理增強了MIDCOM 方案的可擴展性,如果有新的協(xié)議出現(xiàn),僅需要對MIDCOM Agent 進行升級即可。另外,MIDCOM Agent 支持對控制報文和媒體流的加密識別,數(shù)據(jù)傳輸可以加密,傳輸安全性高。但是,部署MIDCOM 方案要求改造本地NAT 設(shè)備使其支持MIDCOM 協(xié)議,以目前的網(wǎng)絡(luò)覆蓋程度來說,為了實施一種NAT 穿越方案大規(guī)模而更新網(wǎng)絡(luò)設(shè)備顯然并不現(xiàn)實。
實現(xiàn)NAT穿越的另一途徑是從客戶端進行:如果P2P連接建立前客戶端已經(jīng)得知自身的公網(wǎng)IP,并通過某種方法預(yù)先在網(wǎng)關(guān)上建立了一條指向自己的NAT 映射關(guān)系;那么通信時客戶端就可以將自身公網(wǎng)IP 作為源IP,已建立NAT 映射的端口作為源端口寫入報文內(nèi)容中。報文內(nèi)容無需再次轉(zhuǎn)換,經(jīng)過NAT 時也就不會出錯了。以這種方式穿越NAT 無需對網(wǎng)絡(luò)設(shè)備進行更新,只需要在Internet中建立一個或多個特殊的服務(wù)器,供內(nèi)網(wǎng)主機獲取自身公網(wǎng)IP,相對基于網(wǎng)絡(luò)設(shè)備的方案來說,成本較低。但是部署過程中,所有的客戶端到要安裝相應(yīng)的程序,因此普及難度也很大。
目前,基于客戶端的NAT 穿越方案已經(jīng)出現(xiàn),但是因為各種方案使用的協(xié)議無法統(tǒng)一,而且該方式并不是對所有的NAT 系統(tǒng)都有效,所以沒有得到普及,其中比較成熟的方案有TURN、STUN 等。
STUN[5](Session Traversal Utilities for NAT,NAT 會話傳輸應(yīng)用程序)是一個簡單的客戶端、服務(wù)器協(xié)議。在STUN系統(tǒng)中定義了兩類不同的實體——位于內(nèi)部網(wǎng)絡(luò)的STUN Client和位于Internet中的STUN Server。其穿越過程如下:Client 通過NAT 向Server 發(fā)送請求,Server 收到后,將以Client的地址信息為內(nèi)容產(chǎn)生回饋消息,Client 通過消息內(nèi)容即可得知自身的公網(wǎng)IP 和NAT 為自己打開的端口號。由于Client 和Server 通信時網(wǎng)關(guān)已經(jīng)為其建立了NAT 映射關(guān)系,以后的數(shù)據(jù)連接直接利用這條記錄就可順利穿越NAT。
在P2P 網(wǎng)絡(luò)中,兩臺主機ClientA 和ClientB 可以通過STUN 穿越NAT 建立直接連接,其過程如下:
(1)ClientA 向STUN Server 發(fā)送消息,請求STUN Server 幫助建立與ClientB 的連接。
(2)STUN Server 收到請求后,將ClientB 的Transport Address(包含客戶端的內(nèi)網(wǎng)和公網(wǎng)IP、端口)發(fā)給ClientA,同時將ClientA 的Transport Address 發(fā)給ClientB。
(3)ClientA 收到ClientB 的Transport Address 信息后,開始向Transport Address 中的兩個IP(ClientB 的公網(wǎng)IP 和內(nèi)網(wǎng)IP)發(fā)送數(shù)據(jù)包,并自動鎖定相應(yīng)較快的那個作為通信IP。
(4)ClientB 收到STUN Server 發(fā)來的Transport Address 信息后,也會試圖向ClientA 的發(fā)送數(shù)據(jù),以便雙方建立連接。
ClientA 和ClientB 發(fā)送數(shù)據(jù)的時間沒有先后要求,只要雙方都能夠和STUN Server 正常通信,一般都能建立P2P 連接,但是在不同的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)中,連接建立流程也有所不同。
如果客戶端屬于相同局域網(wǎng),位于同一NAT 之后,其拓?fù)淙鐖D2 所示,其連接過程如下:
(1)ClientA 登錄STUN Server。NAT 為這次會話分配的端口是5678,Server 記錄ClientA 的公網(wǎng)地址是222.30.160.1:5678,內(nèi)部地址是:192.168.18.35:1234。
(2)ClientB 登錄STUN Server。NAT 為這次會話分配的端口是5679,Server 記錄ClientB 的公網(wǎng)地址是222.30.160.1:5679,內(nèi)部地址是:192.168.18.37:1234。
圖2 客戶端位于單個NAT 之后
(3)ClientA 通過STUN Server 向ClientB 發(fā)起連接,Server 告知通信雙方,對方的公網(wǎng)地址和內(nèi)部地址。
(4)ClientA 和ClientB 分別向?qū)Ψ降墓W(wǎng)地址和內(nèi)部地址發(fā)送數(shù)據(jù)包。對于發(fā)向公網(wǎng)地址的數(shù)據(jù)包,由于ClientA 和ClientB 位于同一NAT 后,只有在NAT 支持hairpin 轉(zhuǎn)換,也就是同一IP 不同端口之間的數(shù)據(jù)轉(zhuǎn)發(fā)時,數(shù)據(jù)包才能到達;對于發(fā)向內(nèi)部地址的數(shù)據(jù),由于ClientA 和ClientB 屬于同一局域網(wǎng),那么數(shù)據(jù)也會到達,并且更快。因此,ClientA 和ClientB 將會選擇后一種方式進行后續(xù)的數(shù)據(jù)發(fā)送。
如果客戶端分屬不同局域網(wǎng),位于多個NAT 之后,其拓?fù)淙鐖D3 所示,其連接過程如下:
圖3 客戶端位于多個NAT 之后
(1)ClientA 登錄STUN Server。NATA 為這次會話分配的端口是5678,Server 記錄ClientA 的公網(wǎng)地址是222.30.160.1:5678,內(nèi)部地址是:192.168.18.35:1234。
(2)ClientB 登錄STUN Server。NATB 為這次會話分配的端口是5678,Server 記錄ClientB 的公網(wǎng)地址是124.236.200.98:5678,內(nèi)部地址是:10.10.10.10:1234。
(3)ClientA 通過STUN Server 向ClientB 發(fā)起連接,Server 告知通信雙方,對方的Transport Address。
(4)ClientA 和ClientB 分別向?qū)Ψ降腡ransport Address 發(fā)送數(shù)據(jù)包。由于ClientA 和ClientB 屬于不同局域網(wǎng),發(fā)往內(nèi)部地址的數(shù)據(jù)無法到達,ClientA 和ClientB 只能通過公網(wǎng)地址建立連接。
(5)ClientA 向124.236.200.98:5678 發(fā)送數(shù)據(jù),但由于NAT 映射關(guān)系的時效性,數(shù)據(jù)經(jīng)過NATB時會可能會被丟棄,連接暫時無法建立,這時ClientA 只能等待。
(6)直到ClientB 向222.30.160.1︰5678 發(fā)送數(shù)據(jù)后,NATB 中才能建立映射關(guān)系,這時ClientA再向ClientB 發(fā)送數(shù)據(jù),就不會被丟棄了。
(7)ClientA 和ClientB 之間通過公網(wǎng)地址建立P2P 連接。
如果ClientA 和ClientB 所在的網(wǎng)絡(luò)環(huán)境更加復(fù)雜,使用STUN 建立P2P 連接的成功率,以及最后的連接效果可能會有所下降,但是與基于硬件的NAT 穿越方式相比,利用STUN 穿越NAT 無疑是一種更加方便有效的手段。
本文提出了一種利用STUN 協(xié)議穿越NAT 建立P2P 連接的方案,在不需要更新網(wǎng)絡(luò)設(shè)備和修改現(xiàn)有NAT 規(guī)則的前提下,實現(xiàn)了大多數(shù)網(wǎng)絡(luò)環(huán)境中的NAT 穿越,與以往的NAT 穿越方案相比,其效率以及穿越成功率都有提升。雖然目前IPV6 網(wǎng)絡(luò)已經(jīng)逐漸普及,但是在未來很長時間內(nèi),IPV4網(wǎng)絡(luò)還會繼續(xù)存在,NAT 依舊有其無可替代的作用,因此,本文提出的NAT 穿越方法對于未來的網(wǎng)絡(luò)應(yīng)用也有一定的借鑒價值。
[1]K. Egevang, P Francis The IP Network Address Translator (NAT) RFC 1631 Network Working Group May 1994
[2]W. Richard Stevens TCP/IP 協(xié)議詳解(卷 I): 范建華,晉光輝,張濤等譯.北京機械工業(yè)出版社,2000.24~243
[3]P.Srisuresh, M.Holdrege IP Network Address Translator (NAT) Terminology and Considerations RFC2663 Network Working Group August 1999
[4]Bryan Ford. NatCheck: Hosted by the MIDCOM-P2P project on SourceForge.
[5]J. Rosenberg, R. Mahy Session Traversal Utilities for NAT (STUN) RFC5389 Network Working Group October 2008