第十四章 處理NAT

        NAT(Network Address Translation,網絡地址轉換)是時代原因遺留的最大問題:它源自互聯網沒有廣泛使用,恐龍自由漫遊的年代。那時候…大約是20年前?網絡地址資源非常充足(通常分配一個C類網絡地址,有254個公共互聯網可路由地址。我個人擁有兩個C類地址,一個用於iol.it,另一個用於matrice.it),沒有人意識到IPV4地址資源池會永遠耗盡。因此,互聯網上的大部分機器都有它們自己的公網地址。此外,安全、加密等方面沒有問題。那時互聯網上沒有錢,因此沒有犯罪。

        電信上最理想的狀態是讓兩臺公網主機直接點對點連接。起初,SIP正是按這個思路設計的。因此,它完全脫離了自然環境,幾年之後,大部分使用VOIP的主機都會發現自己位於防火牆和NAT之後。你在私網內部和在互聯網一側訪問同一臺機器,你會發現用的IP地址是不同的。路由器和“貓”會在數據包的最低層(0層和1層)上對這些數據進行自動轉換。問題是,SIP需要一個文本部分(SDP),它是在數據進入互聯網之前寫入的。裏面包含了媒體流地址的文本描述。而路由器是不會轉換這些文本的(有些路由器會嘗試這個轉換,比如說ALG,但這往往帶來更大的傷害)。很多時候,你會碰到這些問題:呼叫振鈴了,你的小夥伴可以接聽,但是聽不到音頻、看不到視頻,或者是通道的,你不得不掛斷電話;或者雙向通話正常,但在大約30秒後被莫名其妙地拆線了(超時)。這類現象,極可能就是NAT在搞怪。

        這一章,我們將討論以下主題:

  • NAT的簡介,包括它的一點歷史
  • NAT的四種陷阱
  • FreeSWITCH中克服NAT的設置
  • 故障排除技巧

NAT簡介

        向一個完全不關心技術的人解釋NAT的一種好辦法是做個類比。想想一棟辦公大樓和它的收發室。10樓的一位員工把包裹放在一樓的收發室裏,然後寄給你。包裹被送到郵局,然後送到你家。包裹上的寄件人地址實際上是整個辦公樓的地址,而不是10樓辦公室的地址。現在,假設你需要退回包裹。你通過郵政系統退回包裹,郵遞員把包裹送回辦公大樓,收發室的職員必須先通過你的姓名或辦公室號碼找出分發的具體位置,最終把包裹帶給10的員工。收發室就像一個NAT路由器,因爲它在郵政系統和大樓內部之間代理郵件。辦公室位置就像是局域網地址,因爲郵件不能直接抵達這個位置。如果發送郵件的辦公室名字被弄亂或沒寫在包裹上,而且收發室的員工不知道退回的包裹要送到哪個辦公室,該怎麼辦?這將是一個NAT問題,你的包裹可能像之前的電話一樣,最終丟失了。假設你在收到包裹並決定退回時發現上面沒有聯繫人信息或辦公室信息,但是因爲這個包裹是你期待中的(你事先知道誰發給你的,譯者注),那麼你在退回包裹時,你可能會在標籤上註明退回的辦公室號碼或聯繫人?這將是你所創建的一種反向NAT功能。

        當涉及到網絡時,NAT本質上是這樣一種技術:整個局域網(即不直接接入互聯網的網絡)都連接到一臺可以訪問互聯網的設備,他們使用同一個公網IP地址(即接入互聯網那臺設備的IP),通過直接連入互聯網那臺設備爲跳板,爲整個局域網提供公網接入能力。它主要用於減少必要的公網IP地址數量,因爲它很快就會耗盡。它剛開始時有四十億,但在我寫這本書時,基本上已經用完了。

        把你的局域網放在NAT之後有另一個作用,那就是保護的你計算機和其它設備免受攻擊,因爲它們在互聯網上不可見。專家並不認爲這是安全性的最終解決方案,因爲在NAT背後仍然存在着危害設備的方法,但在與其他良好的安全實踐一起使用時,將其視爲額外保護。順便說一個,當你閱讀第15章VoIP 安全後,你會學到更多的安全相關知識。

瞭解NAT的演變

        這些年來,因爲互聯網的發展,對IPv4地址的需求一直在增長。隨着需求的增長,可用地址池已經枯竭,可用IPv4地址已經嚴重不足。隨着時間的推移,處理這種形勢的兩種主要嘗試變得流行起來:NAT和IPv6。

        NAT已經成爲一種相當流行的方式,它佔用少量的公網IP地址並服務於大量的網絡設備。NAT在20世紀90年代作爲一種緩解IP飢餓問題的方法出現,直到IPv6出現,但現在它如此流行,以至於很多人不想放棄它。同時,系統管理員不得不接受NAT遺留的問題,因爲它的流行,必須確保我們的軟件和設備能夠兼容它。

        一種叫IPv6的新的IP地址標準可以解決IP地址飢餓問題,它添加了海量的公網IP地址,足夠我們爲地球表面的每平方英寸上分配數萬億個IP地址。以我們現在所知道的整個互聯網的大小,我們可以給地球上的每一個生物一個IP塊,即使這樣也不會對IPv6地址的可用池造成影響。IPv6規範於1998年發佈,並一直在緩慢地發展。如今IPv6仍然只是IPv4的後盾,後者從20世紀70年代開始發展,擁有着廣泛的使用場景。最有可能的是,即使我們完全採用了IPv6,NAT在一段時間內仍然不會消失。

        我們面臨的主要問題是:當我們嘗試解決VoIP相關的NAT問題時,這些設備是在NAT之後的,從互聯網一側根本不能訪問,當你想要呼叫它時,很難聯繫上它。下一個大問題是協議問題,比如說SIP,在NAT下可能會中斷。

 

NAT的四個陷阱

        NAT有四個基本陷阱,每個人都應該學習。瞭解這些陷阱,你就能很好地處理NAT場景,你無疑會面臨:

  • 即使你不知道,NAT也可能存在。互聯網不必參與其中。
  • 任何兩種抵禦NAT的技術一起混用,都可能彼此相互抵消。
  • 有些設備使用SIP ALG(Application Layer Gateway,應用層網關)來抵禦NAT。它們甚至沒有告訴你就直接做了。
  • NAT校正技術(比如ALG)可能錯誤識別具體情況,實際上把事情弄得更糟糕。

 

        熟悉這些陷阱。它們在本章中經常被引用。讓我們更詳細地討論每一個問題:

  • 即使你不知道,NAT也可能存在。互聯網不必參與其中。如果你使用的是有線或電話公司的家庭互聯網服務,甚至有些商務級服務,他們有時會使用NAT將所有客戶置於一個單獨的網絡中,然後將該網絡轉換爲基礎設施中的其他部分。在你的設備到目標設備之間,這種事情不會只出現一次,而會是多次出現,而你沒有任何控制手段。這會給試圖使用VoIP的人帶來實質性的問題。大多數VoIP協議只有處理NAT的基本規定,並且經常出現不足。這可能是大多數家庭用戶在家中使用VoIP時遇到的第一個問題。在一個局域網內部也可以使用NAT方式連接多個局域網,而不需要真正連接到互聯網。連接互聯網只是NAT的最常見的用法而已,但它也可以在內部做網絡隔離用。如果你正在向你友好、鄰居、網絡電話專家尋求幫助,而他提出了一個NAT問題,不要僅僅因爲你沒有使用互聯網,或者你不知道NAT在哪裏就把它排除在外。
  • 任何兩種抵禦NAT的技術一起混用,都可能彼此相互抵消。這是一個棘手的問題,在VoIP用戶中很常見。把它形象化的最好方法就是想象一場奧賽羅的比賽。每當你移動一步去阻擋NAT時,它都會翻轉周圍的一切。如果你做一個反向移動,所有東西又將翻轉回來。實際發生的甚至比你想像的多(看一下第一個陷阱)。只要嘗試的次數是奇數,並且開始時是不工作狀態,那麼你應該結束,但你應該注意只做儘可能小的修改,以免混淆和痛苦。如果你的話機上支持NAT功能,你在話機側啓用了它,並且在FreeSWITCH側同時啓用,你可能會碰到單向通話或沒有聲音的問題。更令人困惑的是,有很多方法可以取消NAT。有些只需要在NAT後面的話機上進行更改;有些只需要在FreeSwitch上進行更改;有些則需要在兩端進行更改。
  • 有些設備使用SIP ALG來抵禦NAT。“哼,該死的SIP ALG”。我們已經無數次在IRC或社區會議中聽到這樣的抱怨了。ALG的本意是好的,但它通常好心幹壞事。它們就像前兩種陷阱的組合,因爲它們通常是你的網絡路由器內部實現的,並且在你不知道的情況下默認開啓。在所有反向NAT技術中,它們做得最差,即在SIP包經過路由器時修改SIP的文本。這會導致錯誤的行爲和錯誤的路由導向,呈現在你眼前的完全是一個謎。注意我的話。如果你發現自己說出了“這完全沒有意義”這句話,你首先要檢查的是,你是否被邪惡的SIP ALG所迷惑。很多時候,禁用SIP ALG就能解決NAT相關的問題。
  • NAT校正技術可能錯誤識別具體情況,實際上把事情弄得更糟糕。它有助於瞭解你的環境,至少足以知道你是否真的需要啓用反NAT功能。一些SIP代理利用了SIP的一些更神祕的東西,並對(SIP)包中的網絡地址做了一些非常奇妙的事情。對於那些不熟悉SIP的人來說,是的,我知道這很神祕,但我們需要洞察事物的本質。所以問題是,完全合法的數據包以一種類似於NAT的方式進行操作,可以觸發我們用來檢測NAT的一些特性。所以你需要小心,尤其是思科的話機,因爲它的NAT性能很差,同時還容易被誤檢。

 

解密FreeSWITCH的NAT設置

        既然我們已經瞭解了NAT的常見缺陷,那麼我們可以仔細檢查可能遇到的各種類型的NAT。基本上,你可能會遇到這樣的情況:你的話機或PBX在NAT之後,與不在NAT之後的SIP終端通信(或者相反)。更糟糕的是,你可能最終會遇到可怕的雙向NAT情況,在這種情況下,連接雙方同時獨立存在於各自的NAT路由器之後。

       雙向NAT的情景,網絡結構看起來是這樣的:


        讓我們從一個理智但充滿挑戰的場景開始:你家裏有一部話機,NAT情況未知,而你希望把它註冊到公網上的FreeSWITCH服務器。好消息是,FreeSwitch演示配置示例已經涵蓋了這種情況。FreeSWITCH內核有一個特性叫ACL(Access Control Lists,訪問控制列表)。ACL允許您創建網絡地址列表,並根據特定設備是否源自由ACL定義的地址來控制訪問權限。確定一個地址是否與列表元素匹配,在此基礎上確定清單上的內容是好是壞,是否繼續保留(或不保留)在列表中,值是對等的。

        這個特性允許某些設備根據其IP地址進行身份驗證,或者你可以列出敵人設備的列表,以便完全阻止列表中的任何人。在本案例中,我們將用ACL來確定一臺設備是否在NAT之後,並決定如何處理。

        NAT背後的設備很可能擁有一個特殊範圍內的IP地址,這由RFC-1918定義。對此最簡單的解釋是,有一組特殊的IP地址段永遠不會連接到互聯網,因爲它們保留在局域網內私有使用。這基本上是以192.168.x.x、172.16.x.x到172.31.x.x或10.x.x.x開頭的任何IP地址。從現在起我們就叫他們局域網地址。人們也會根據RFC來稱呼它們,例如“RFC1918地址”。

        因爲這些地址是私有的,所以可能有無數個網絡中使用完全相同的IP地址,但它們永遠不能直接相連。現在,當你把這些網絡連接到一臺NAT路由器之後,所有這些私網中的話機就都能夠訪問你的FreeSWITCH服務器了。路由器的工作原理是跟蹤來自LAN地址的所有流量,並將其發送到互聯網,就像它來自路由器上的公網 IP一樣。然後,當互聯網上的目標網元把應答消息回給NAT路由器時,它根據映射關係把數據包傳遞給原始的發送方。FreeSWITCH看到的源地址可能永遠不會相同,這使得向話機發送來電變得困難。這就是ACL大顯身手的時候了。

        FreeSWITCH的mod_sofia profile有一個配置參數叫apply-nat-acl。這個參數可以在同一個profile內多次使用,並且需要ACL列表的名稱。當mod_sofia收到SIP REGISTER或INVITE時,它查看聯繫人地址,並根據指定的ACL檢查Contact報頭中引用的IP。如果有匹配,則得出結論,設備位於NAT之後。很難說哪一個IP代表了NAT背後的設備,但我們有一些線索。還記得我們說過的RFC-1918或局域網地址嗎?因爲它是一個定義的IP地址範圍,所以我們可以得出這樣的結論:如果你來自這些地址中的一個,那麼你是從NAT後面發起呼叫的。

        小心!別忘記第四個陷阱,假設每個來自局域網地址的設備都在NAT之後,這並不是百分之百的安全。事情並不總是如此,但肯定的時候居多。保持警惕是件好事。有一種情況可能不是這樣,那就是FreeSWITCH也部署在NAT後,擁有同樣的私網地址。好吧,我們有一個特殊的ACL,在FreeSwitch啓動時創建,稱爲nat.auto。這個特殊的acl已經包含了整個RFC-1918地址空間,它同時檢查了機器的本地網絡地址,並排除了該地址空間,這樣當它接到與FreeSWITCH在同一局域網上的電話的呼叫時,就不會有任何誤判。同時,這個ACL可以檢測到一部話機實際上位於NAT後面的遠程位置。FreeSWITCH通過apply-nat-acl指向nat.auto預先設置,能夠糾正FreeSWITCH部署在公網環境中的大部分NAT背後的典型設備。

        我們如何解決這個問題呢?基本上,當檢測到話機從NAT後面註冊時,我們把我們見到的源IP和端口(網絡層的源地址)保存下來,並把它與我們不可訪問的局域網地址一併存儲在內部數據庫中,毫無疑問,這個局域網地址是話機註冊信令中提供給我們的。當我們需要聯繫這部話機時,我們檢查數據庫並確定消息應該發送的IP:port。在SIP報頭中,依然填寫遠程話機所期望的內網IP:port。我們同時告訴話機提高註冊頻率以保證映射的開放狀態,因爲大部分NAT路由器只在短時間內找開轉換路徑。這項技術有效地避開了第四種陷阱的風險,因爲我們從來沒有像邪惡的ALG那樣篡改預期的地址。

        這裏給出一個FreeSWITCH  CLI上的輸出示例。客戶端是一個NAT後面的軟電話,註冊到一個運行在公網上的FreeSWITCH實例。注意Contact字段用的IP  10.0.1.85是一個局域網地址。Status字段顯示:由於nat.auto ACL列表的存在,檢測到UDP-NAT。技巧體現在Contact的結尾之外。在話機註冊的Contact地址之後,追加了fs_nat和fs_path參數,指出如何繞過NAT。考慮以下內容:

fs_nat=yes fs_path=sip%3A1006%40206.22.109.244%3A43425%3Brinstance%3Db67dbafc

9baa9465%3Btransport%3Dudp.

 

        其中fs_path字段是一個SIP URI (Uniform Resource Identifier,統一資源標識符),它是繞過NAT聯繫話機的實際地址。這個URL是經過編碼的,因此URI中的特殊字符不會與實際聯繫地址衝突。這個字段解碼後的版本是這樣的:

sip:[email protected]:43425;rinstance=b67dbafc9baa9465;transport=udp

 

          因此,當我們向這部話機發起呼叫時,INVITE消息會發到206.22.109.244:43425,但信令中我們會保留它原來的地址10.0.1.85:5060(信令中的文本),這正是對端路由器NAT轉換前的地址,它負責把INVITE信令轉遞給話機終端。通過”sofia status profile internal reg”命令,你可以看到完整的註冊信息。下面是具體輸出實例:

 

freeswitch@myhost> sofia status profile internal reg Registrations:

================================================================ Call-ID:                                      ZWU1MjdiZTI2MTg2MmVhNTc5NTk3MDY5YjFmOTVkMTU.

User:                           [email protected] Contact:

"TEST"<sip:[email protected]:10118;rinstance=b67dbafc9baa9465;transport=udp;fs

_nat=yes;fs_path=sip%3A1006%40184.58.189.244%3A43425%3Brinstance%3Db67dbafc 9baa9465%3Btransport%3Dudp>

Agent:                        eyeBeam release 1104g stamp 54685

Status:                      Registered(UDP-NAT)(unknown) EXP(2012-12-09 10:18:07) EXPSECS(88)

Host:                           myhost

IP:                                206.22.109.244

Port:                           43425

Auth-User:               1006

Auth-Realm:             myhost.freeswitch.org

MWI-Account:          [email protected] Total items returned: 1

================================================================

 

        注意裏面的Contact內容,包含了fs_nat和fs_path兩個參數。FreeSwitch發送給用戶1006的任何SIP通信都將使用fs_path參數中指定的URI。

         下面我們給出另一個示例,使用一種更現代的客戶端,處理客戶端和服務器處理不同NAT後面的普遍場景。在這個案例中,客戶端能夠利用FreeSWITCH發給它的數據糾正自己的地址。

        我們的Linphone第一次發發的SIP 註冊包是這樣的:

 

REGISTER sip:lab.opentelecomsolutions.com SIP/2.0

Via: SIP/2.0/UDP 192.168.1.200:5060;branch=z9hG4bK.znT45Avvt;rport From: "Sara"<sip:[email protected]>;tag=cfurzFSzg To: "Sara"<sip:[email protected]>

CSeq: 20 REGISTER

Call-ID: kMq3GlIAVx Max-Forwards: 70

Supported: replaces, outbound Accept: application/sdp Accept: text/plain

Accept: application/vnd.gsma.rcs-ft-http+xml Contact:

<sip:[email protected];transport=udp>;+sip.instance="<urn:uuid:ba010749-62 14-4a35-bfb1-ac9c9181c24d>"

Expires: 3600

User-Agent: Linphone/3.9.1 (belle-sip/1.4.2)

 

        你可以看到,原始的"Contact"報頭中,攜帶的地址是“192.168.1.200”,局域網私網地址。但是,經過完成註冊所需要的幾次數據交換之後,Linphone會向FreeSWITCH發送正確的“聯繫地址”,而我們最終得到:

 

生成媒體流

        既然SIP消息可以正常地從FreeSWITCH傳輸到話機,那麼媒體呢?如果你連對方的聲音都聽不能,那麼能不能看到對方的視頻就不重要了,對吧?我們碰到過許多問題,呼叫可以正常建立,直到NAT擊中呼叫中實際提供媒體的RTP包,最後呈現的是單向音頻或者乾脆雙向沒有音頻,才意識到問題的存在。鑑於這種不公平現象,我們創建了一種單獨的特性,它總是啓用的,只有在極少數情況下會手動禁用,這些情況都是由第四種陷阱引發的。這個特性叫RTP自動調整(auto-adjust)。我們需要它的原因是,當話機試圖從NAT後面給我們打電話時,它會天真地向FreeSWITCH宣告它(FreeSWITCH)無法到達的LAN私有地址,告訴我們向哪裏發送媒體流(如SDP文本中所寫的地址)。

        我們可以合理地猜測:既然設備處理NAT之後,那麼我們應該把音頻包發給處理SIP消息時保存的同一地址。但情況並非總是如此,因爲各種類型的NAT都有限制,端口映射有時需要NAT背後的設備實際發送了一個數據包之後才能建立。因此,現實中,我們可能完全沒辦法知道怎樣才能把音頻流成功地發給話機。由於有自動調整功能,我們還有一絲戰鬥的機會。只要我們給話機的地址是有效的,它就可以向我們發音頻,我們可以等到對方向我們發幾個包之後,通過RTP的起始地址來決定向哪裏回送RTP包。這種方式並不保證100%有效,據我們所知,在其它方式無望的情況下,這種方式還是非常有效的。爲了安全起見,我們只允許這種神奇的調整發生在通話剛開始的時候,否則壞人可能會試圖竊取人們的音頻流。

        如前所述,RTP自動調整在默認情況下幾乎是啓用的,並且會自動打開。你可以通過查找下面這樣的日誌消息來判斷它是否正常工作。該消息顯示原始媒體目的地和檢測到的新媒體目的地。這個日誌在任何觸發自動調整的話務的開始處打印。

        這個特性有大約2%的機率觸發第四個陷阱,如果你萬幸碰到了,而且它實質上破壞你的工作了,你所需要做的只是在你的SIP profile中添加這麼一個參數設置:

<param name="disable-rtp-auto-adjust" value="true"/>

 

        此外,你還可以通過設置通道變量rtp_auto_adjust=false來爲單路呼叫禁用這個特性。唯一需要注意的是變量必須在媒體流開始前設置。

 

高級選項和設置

        現在我們已經瞭解了它是如何工作的,我們可以看看其他觸發NAT檢測的方法。有些情況下,ACL是不夠的,因爲可能是鬼鬼祟祟的ALG弄亂了數據包,也可能是流量需要經過代理中轉,也可能是話機終端自認爲能夠處理NAT但它做得並不正確。

        我們有另一個默認禁用的選項,因爲它面對第四個陷阱時笑了,基本上認爲任何稍微不尋常的東西都是NAT。這個參數是危險的,但當你束手無策時,它或許是一個有效的選擇。這個參數的名字是aggressive-nat-detection在你的SIP profile中把它設置爲true就能啓用它,並對所有呼叫生效。基本上,它查看SIP數據包,如果在不同的頭中看到不同的IP地址,則使用邏輯推導來確定哪個是源地址。從這裏開始,它執行ACL相同的操作,只是它可能沒能把源地址寫入數據庫。

<param name="aggressive-nat-detection" value="true"/>

 

下圖說明了這種場景:


        FreeSWITCH有一系列參數,我們稱之爲"No Device Left Behind"NDLB。這些參數表示這樣的情況:我們完全模擬或接受設備中的缺陷假裝一切都很好,或爲設備做準備,這樣它仍然可以工作,儘管事實上我們完全被冒犯了,因爲我們必須通過修改代碼使其工作。這些在處理不完全符合SIP規範的老式客戶端時特別有用。

        在與NAT鬥爭的過程中,有一個參數特別有效,它就是force- rport。SIP協議中,rport屬性的目的是在請求消息中添加;rport,以此來克服NAT的最小嚐試。當FreeSWITCH見到這個屬性時,會在應答消息中添加rport=host:ip,以便終端話機意識到自己處於NAT之後。有趣的是,有些話機在收到應答消息時能夠正確處理rport屬性,但它自己從不在請求消息中使用它。force-rport參數告訴FreeSWITCH,假裝與我們交互的設備都提供了rport參數,因爲我們應答時,就按有rport參數的邏輯處理,因此解鎖了原本無法獲得的功能。

        和其它大部分NDLB選項一樣,這個參數缺省是不啓用的。它同時打開了第四個陷阱的漏洞,因爲它會破壞許多設備。你可以將其設置爲true以始終假定rport;也可以將其設置爲safe,僅對我們知道需要使其正常工作的設備啓用rport。你還可以把它設置與client-only或server-only,即根據呼叫方向進行設置,幸運的是,你將永遠不需要這些選項。

 

FreeSWITCH部署在NAT後

        我們已經介紹了一些常用的場景:你的話機在NAT之後,與公網上的FreeSWITCH對接。現在繼續討論下一種場景:你本地的FreeSWITCH副本部署在NAT之後,它連接公網上的SIP供應商或另外一臺FreeSWITCH服務器。幸運的是,我們已經設計好示例配置,以便在這些NAT環境中有最好的工作體驗。我們建議你每隔一段時間在FreeSwitch測試一下未更改的示例配置,以查看可能遺漏的默認行爲。

Freeswitch與路由器對話

        FreeSWITCH默認支持兩種NAT協議的客戶端:NAT-PMP和UPnP。這兩種協議使用的方法略有不同,但基本要點是相同的。這兩種方法都使用網絡協議來發現你的NAT路由器,並與之通信。因此,它不是在運行中進行NAT映射,而是請求路由器打開一個端口,並實際瞭解端口映射的詳細信息,因此當FreeSwitch與另一臺服務器進行對話時,它完全能夠在SIP和媒體數據包中攜帶正確的信息。太酷了!不過要小心,我們正在打開通往第二、第三和第四個陷阱的大門。

        我們現在已經掩蓋了我們在Nat後面的事實,這樣對方就無法檢測到它。我們之間可能隱藏着一個ALG,現在我們不需要它,但它依然自以爲是地幫我們替換地址。對端可能使用類似的NAT檢測方法,從而觸發一個雙反NAT陷阱。最重要的是,如果您有一個非常嚴格的NAT路由器或防火牆,這個功能不僅可以解決地址映射的難題,而且還可以解鎖防火牆上原本阻塞的端口。

FreeSWITCH部署在NAT後,單獨運行路由器

        SIP profile有一組參數,它們是ext-sip-ip和ext-rtp-ip。這些參數用於提供外部IP地址信息。缺省配置文件中,這兩個參數都配置爲auto-nat。這與我們剛纔討論的NAT路由器控制功能一起使用,讓事情走上正軌。有時候,我們所使用的路由器並不支持NAT-PMP或UpnP,或者更糟糕的是它聲稱支持其中的一種或兩種,但因爲固有的破壞,或某些致命的陷阱組合,實際上根本不起作用。

        FreeSWITCH啓動時,可以加上-nonat選項來禁用這個功能。當這個功能被禁用時,我們仍然有些技巧可用。如果你已經知道公網使用的靜態IP,可以把它設置給上面描述的兩個參數。更好的是,你可以將其設置爲autonat:x.x.x.x(其中x.x.x.x應替換爲你的公共IP),這樣它使用您已知的外部IP,並且仍然具有一些動態魔力。

ext-sip-ip="auto-nat:194.20.24.1" ext-rtp-ip="auto-nat:194.20.24.1"

 

設置外部地址的其它方法

        你可以使用動態DNS或STUN服務,指向host:my.domain.com或stun:stun.myhost.com (其中 my.domain.com 或 stun.myhost.com 分別對應你自己的動態域名或STUN服務器),按需查詢。這個方案也有缺點,它會降低處理速度甚至停止工作。和往常一樣,我們已經默認提供了最好的選項,但是你仍然應該瞭解其他選項。如果你能夠控制路由器,那麼你可以建立持久的NAT映射,把特定的流量直接路由給FreeSWITCH或話機,這時ext-sip-ip 和 ext-rtp-ip就可以派上用場。此外,如果你有辦法,可以使用VPN來路由兩個彼此獨立的網絡,假設你可以控制兩端的網絡,那麼你可以把它們都放到NAT之後。

 

在NAT環境中的其它創造性用法

可以把FreeSWITCH部署在設備之間,利用它解決NAT問題。你可以配置一臺本地的FreeSWITCH,並讓所有內部話機向它註冊,然後把這個FreeSWITCH實例註冊到SIP運營商那裏,把它作爲所有內部話機的跳板,利用它在NAT上開個洞,讓所有人都開心。此外,你也可以把FreeSWITCH部署在公網上,然後讓所有內部話機或分佈式的其它FreeSWITCH實例向它註冊,這樣,即使所有局部平臺都部署在NAT之後,它們間依然能夠暢快自由地通信。

 

NAT 與 WebRTC (解決方案)

        WebRTC昨天才剛剛更新定義,實際上現在正在定義。它完全不受遺留缺陷的影響,特別是在處理NAT時。所以我們說用WebRTC傳輸解決了所有的NAT問題。

你在SIP profile中定義了ext-rtp-ip和ext-sip-ip,然後在verto.conf.xml中定義ext-rtp-ip,然後準備開始了。

        默認情況下,所有WebRTC客戶端都使用ICE的魔力來確定如何連接,FreeSWITCH端也實現了這一點,它幾乎可以確保信令和媒體的完美流通。

        如果您有一個非常奇怪的場景,例如您想在LAN內部使用WebRTC而不使用公網地址或DNS,那麼你將需要實現自己的ICE/STUN服務器,並讓WebRTC客戶使用這些服務器。如果你有這樣的項目經歷,你可能已經知道你所需要的ICE基礎設施了。

 

結論

        我們祝願你在NAT世界的旅途一切順利! 希望這一章能在你遇到困難或者準備與ALG戰鬥時派上用場。那真是太糟糕了!如果你記住了這一章中的所有內容,但仍然有問題,你可以隨時上網向其他FreeSWITCH社區成員尋求幫助。最後一句能讓你看起來很聰明的話是:如果下次有人抱怨他們的電話在開始30秒後被莫名其妙地掛斷,那麼是的,這就是一個NAT問題。如下圖所示:


      在某些情況下,FreeSwitch無法解決這個問題,你需要修復或更換NAT設備。

 

總結

        這一章,我們識別了NAT的陷阱。哪怕只有一個讀者能倖免於第一次遇到ALG或NAT路由器所帶來的灼痛,那麼我們的瘋狂之旅就沒有白費。

        我們還闡述了FreeSWITCH中用於緩解NAT相關問題的大部分選項。在我們繼續討論VoIP安全之前,我將爲你留下更多的錦囊妙計,希望你能在NAT出現問題時正常工作。以下是你應該記住的小貼士:

  • 研究NAT的四個陷阱,並時刻關注它們
  • 很容易分心,成爲其中一個陷阱的犧牲品。如果你發現花的時間太長了,重新開始,確保沒有在某個地方犯錯誤,導致你誤入歧途。
  • 試着做最少的必要改動讓NAT工作
  • 你的NAT配置越混亂,就越容易出錯或不兼容。在第二個陷阱的擺佈下,很容易出現一端正常,另一端瘋狂,來回往復的局面
  • 如果你有權限訪問路由器,請將其配置爲儘可能有利於NAT的設置
  • 讓事情簡化的最好方法就是調整環境,這樣你就有了一個理想的環境。選擇基本的NAT設置,並堅持默認設置,這些設置通常被調優爲大多數情況下都是最佳的。

 

        下一章,我們將轉移焦點,從克服NAT問題,轉向改善VoIP安全的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章