
圖片來自于互聯(lián)網(wǎng)
我們一說到NAT問題,讀者馬上就會聯(lián)想到路由器配置或者路由器的地址轉(zhuǎn)換方面的內(nèi)容。今天,我們針對應(yīng)用層的NAT-ALG進行一個比較完整的詳解介紹,幫助讀者進一步加深對SIP中的ALG配置,和其帶來的影響。
1、ALG背景介紹
大部分的讀者可能已經(jīng)了解了網(wǎng)絡(luò)OSI的架構(gòu),這里不再做過多介紹。ALG全稱是Application-level gateway。其應(yīng)用包括很多。我們使用的SIP是其中一種。

圖片來自于互聯(lián)網(wǎng)
ALG支持4種功能,其中一個比較重要的功能就是“防火墻”功能。注意,這里的防火墻是加了引號的,因為在當(dāng)前針對SIP的部署環(huán)境中,SBC承擔(dān)了SIP防火墻的功能。關(guān)于SBC的完整的介紹,讀者可以查閱筆者的歷史文檔,筆者對SBC部署發(fā)布了大量的技術(shù)資料,因此,這里不再重復(fù)。
如何搭建一個完整免費的邊界會話控制器(SBC)測試場景
ALG可以把網(wǎng)絡(luò)層的地址公網(wǎng)地址和內(nèi)網(wǎng)地址進行NAT處理轉(zhuǎn)換,實現(xiàn)內(nèi)外網(wǎng)進行互聯(lián)互通。在具體的實際應(yīng)用中,ALG會重寫一些SIP修改的消息內(nèi)容來保證SIP服務(wù)器端和SIP終端之間地址的統(tǒng)一,保證其連接正常。這里,讀者一定要注意幾個需要注意到提示:
- ALG僅對應(yīng)用層(SIP/SDP)的消息進行重寫
- ALG僅針對NAT規(guī)則進行處理,如果沒有NAT問題,無需ALG
- 在NAT后面的SIP設(shè)備不會感覺ALG的存在
因為大部分的SIP網(wǎng)絡(luò)應(yīng)用基本上都涉及了外網(wǎng)用戶注冊的問題,設(shè)備在NAT后,或者SIP服務(wù)器是公網(wǎng)部署。所以部署方案會帶來很多潛在的問題。很多時候,在一些中小型企業(yè)通信的部署環(huán)境中,通過修改路由器的ALG配置可以解決一定的問題。但是,隨著部署環(huán)境越來越復(fù)雜,客戶對網(wǎng)絡(luò)使用的靈活性要求越來越高,因此VOIP解決方案部署和NAT問題一直處于一種并存狀態(tài),這種狀態(tài)給客戶帶來很多呼叫問題,包括單通,呼叫掉線,呼叫后無語音等問題。通過ALG開啟或者關(guān)閉的設(shè)置,一些簡單的問題都可以被輕松處理。接下來,我們具體介紹一下ALG針對SIP和SDP到底做了哪些處理。
2、ALG到底做了哪些處理
首先說明,ALG可以做NAT轉(zhuǎn)換同樣的工作,但是,ALG僅在第七層中進行處理。因為ALG是路由器的內(nèi)置功能,因此,ALG主要做以下幾個方面的工作:
- ALG是在消息離開路由器之前修改SIP/SDP應(yīng)用的必要的消息
- ALG替換使用公網(wǎng)地址和端口替換SIP設(shè)備的內(nèi)網(wǎng)地址和端口
簡單示例說明,如果一個在內(nèi)網(wǎng)的SIP終端需要和公網(wǎng)的SIP服務(wù)器連接,它首先需要通過路由器出局,并且告訴公網(wǎng)SIP服務(wù)器其SIP終端的公網(wǎng)地址。否則,SIP公網(wǎng)服務(wù)器不能和一個私人網(wǎng)IP的終端進行通信。那怎么辦呢?只能通過路由器的ALG轉(zhuǎn)換一個公網(wǎng)地址,然后和SIP服務(wù)器連接互通,返回時,路由器再通過這個綁定消息返回到內(nèi)網(wǎng)SIP終端。這就是ALG簡單的工作原理。在ALG處理中,SIP和SDP都需要進行修改處理:
- IP地址和端口修改
- 超時設(shè)置,媒體轉(zhuǎn)發(fā)設(shè)置
- ALG修改SIP頭中的Via和Contact,有的路由器也可能修改Route和Record- Route頭。
- ALG修改SDP消息體中的m=,c=和o=,有時也修改a=。這些參數(shù)的具體內(nèi)容,參考RFC4566-5章節(jié)
注意,在七層協(xié)議中,ALG和proxy服務(wù)器的地址轉(zhuǎn)換有所不同。ALG設(shè)置無需SIP用戶端進行配置,而proxy則需要用戶端或者SIP服務(wù)器進行適當(dāng)配置。以下示例就是一個典型的在路由器上開啟ALG功能設(shè)置以后,SIP內(nèi)網(wǎng)終端連接外網(wǎng)SIP服務(wù)器時的一個呼叫請求,在這個呼叫請求,SIP終端的Via,Contact發(fā)生轉(zhuǎn)換的流程,ALG把Via和Contact通過公網(wǎng)地址進行了修改,替換為路由器公網(wǎng)地址,然后發(fā)送到SIP服務(wù)器。

圖片來自于互聯(lián)網(wǎng)
我們討論了關(guān)于ALG處理的一些參數(shù)。為了解決NAT問題,其實很多終端或者服務(wù)器端已經(jīng)增加了針對NAT的功能支持,可以非常友好地解決NAT問題。但是,還有一部分產(chǎn)品沒有支持NAT檢測功能。因此,有時需要ALG開啟,有時又需要ALG關(guān)閉。接下來,我們將討論開啟或者關(guān)閉ALG的必要性。
3、開啟ALG功能設(shè)置
現(xiàn)在NAT問題非常普遍,很多SIP終端設(shè)備已經(jīng)具備了NAT檢測功能。但是市場上一些SIP終端(可能思科話機和比較老的品牌的話機有一部分不支持NAT檢測)仍然沒有支持NAT檢測。不支持NAT檢測功能的SIP終端對七層應(yīng)用中消息寫入一個私網(wǎng)IP地址。遠端SIP服務(wù)器就會根據(jù)這個私網(wǎng)地址返回SIP響應(yīng)。因為這個SIP終端是在NAT背后的私網(wǎng)地址,所以,SIP服務(wù)器端返回的消息永遠不會抵達SIP終端。這樣的話,類似這樣的SIP終端就需要路由器開啟ALG支持,通過ALG來修正到正確的IP地址上。如果SIP終端是在NAT背后的話,并且此SIP終端沒有支持NAT檢測,那么,這些設(shè)備就需要開啟路由器的ALG功能設(shè)置。過路由器以后,沒有開啟ALG功能。路由器出局的IP地址仍然是一個私網(wǎng)地址。如下示例:

開啟路由器的ALG功能以后,SIP服務(wù)器/IPPBX收到的SIP和SDP地址則修改為其公網(wǎng)地址,包括SIP header和SDP消息體內(nèi)容。在下面的示例中,我們在路由器開啟了ALG設(shè)置,SIP服務(wù)器可以收到其帶公網(wǎng)地址的SIP/SDP消息。這樣的話,不支持NAT檢測的SIP終端如果路由器開啟了ALG設(shè)置的話,則可以成功修改相關(guān)IP地址,可以保證和外網(wǎng)SIP服務(wù)器進行正常互通。

因此,如果是不帶NAT檢測功能的終端,如果在NAT環(huán)境下,大部分情況下需要開啟ALG功能。
4、關(guān)閉ALG的設(shè)置
前面我們討論了在一些必要的SIP終端缺乏支持NAT檢測功能的時候,需要開啟ALG功能來解決公網(wǎng)IP地址的問題。但是,在很多場景中,SIP呼叫業(yè)務(wù)又不需要開啟ALG功能。很多時候,我們經(jīng)常聽到技術(shù)人員說“檢測路由器,關(guān)閉ALG設(shè)置”。確實,關(guān)閉ALG設(shè)置可以解決很多問題。但是,我們在什么時候需要關(guān)閉ALG呢?通常情況下,有幾種情況需要讀者考慮關(guān)閉ALG功能:
- SIP設(shè)備支持NAT檢測功能
- SIP服務(wù)器是在NAT背后的網(wǎng)絡(luò)環(huán)境中, SIP終端通過外網(wǎng)呼叫內(nèi)網(wǎng)SIP服務(wù)器
- SIP服務(wù)器部署在公網(wǎng)環(huán)境,SIP終端在帶NAT的環(huán)境中
在當(dāng)前的部署環(huán)境中,我們看到的環(huán)境大部分是SIP服務(wù)器端支持NAT檢測,SIP終端很少需要NAT檢測的設(shè)置。所以,很多廠家,包括一些開源的SIP軟交換或媒體服務(wù)器都能夠支持NAT檢測設(shè)置。如果是一個能夠檢測NAT的SIP服務(wù)器,它可以檢測到自己的公網(wǎng)IP地址,并且發(fā)送SIP消息之前,會把自己的公網(wǎng)地址寫入到SIP和SDP消息中。NAT檢測可以綁定某些外網(wǎng)的分機,通過修改地址的方式發(fā)送到NAT環(huán)境以外的SIP終端,F(xiàn)在,我們討論兩個基本點使用場景。一種是SIP服務(wù)器或者IPPBX在NAT背后場景。如果此SIP服務(wù)器在NAT背后的話是這樣處理的,ALG關(guān)閉以后,在內(nèi)網(wǎng)的SIP服務(wù)器或者IPPBX會自動檢測NAT設(shè)置,在發(fā)送SIP消息前修改SIP/SDP中的內(nèi)網(wǎng)地址為公網(wǎng)地址,然后發(fā)送到外網(wǎng)的SIP終端,SIP終端就會收到一個帶公網(wǎng)地址的SIP服務(wù)器的SIP/SDP消息,這樣就會保證其互通成功。如果這種環(huán)境下開啟ALG設(shè)置的話,可能會干擾SIP/SDP地址的發(fā)送。

另外一種情況是SIP服務(wù)器或者IPPBX部署在公網(wǎng)環(huán)境或者云平臺,SIP分機在帶NAT的內(nèi)網(wǎng)環(huán)境中。通常的處理方式可以是這樣的:在SIP 服務(wù)器創(chuàng)建分機時,其分機屬性設(shè)置支持NAT=yes以后,內(nèi)網(wǎng)的SIP終端對SIP服務(wù)器端發(fā)送消息,路由器的ALG是關(guān)閉狀態(tài),SIP服務(wù)器收到SIP終端的消息后,包括其SIP終端的內(nèi)網(wǎng)地址和SDP消息,看到分機設(shè)置為NAT=yes的設(shè)置,SIP服務(wù)器就會意識到有一個來自帶NAT處理請求的SIP終端,這個終端要求修改SIP/SDP的內(nèi)網(wǎng)地址為發(fā)送消息的公網(wǎng)地址。外網(wǎng)的SIP 服務(wù)器或者IPPBX就會替換掉Via中的SIP內(nèi)網(wǎng)地址為一個Receivedd IP地址。SIP服務(wù)器通過這個Via 中的IP地址返回到公網(wǎng)地址和SIP終端。以下是一個FreePBX中關(guān)于NAT=yes的設(shè)置策略,這個參數(shù)設(shè)置比較智能地解決了NAT問題,同時也不需要開啟路由器的ALG設(shè)置。
這里,路由器的ALG是關(guān)閉狀態(tài),因此SIP終端的內(nèi)網(wǎng)IP地址就會發(fā)送到SIP服務(wù)器端,根據(jù)NAT=yes的設(shè)置選項,SIP服務(wù)器端修改了Via此SIP的公網(wǎng)地址,然后返回到此公網(wǎng)。這樣的設(shè)置可以解決大部分的NAT問題。注意,有一些路由器也會干擾消息的處理,如果關(guān)閉ALG不能工作的話,技術(shù)人員需要開啟ALG設(shè)置做進一步的測試。

因此,如果SIP服務(wù)器/IPPBX那個智能支持一個NAT=yes的選項,SIP服務(wù)器端自己首先進行NAT處理,無需開啟路由器的ALG,可以幫助用戶能夠快速智能地解決大部分的問題。
提醒讀者,開源Asterisk或者FreeSWITCH都能非常智能地支持類似的功能,具體的設(shè)置語法包括:
FreeSWITCH撥號規(guī)則中使用 <condition field="${sip_nat_detected}" expression="true">
Asterisk中的PJSIP配置文件中的local_net 和external_media_address等參數(shù)
如果通過FreePBX界面配置的話,參考www.freepbx.org.cn 的技術(shù)資料
5、ALG超時設(shè)置和媒體轉(zhuǎn)發(fā)討論
除了我們剛才討論的是否開啟ALG NAT功能以外,關(guān)于ALG設(shè)置還有兩個比較重要的功能,它們分別是ALG超時設(shè)置和ALG媒體轉(zhuǎn)發(fā)功能(sip-direct-media)。相對ALG地址的轉(zhuǎn)換以外,這兩個功能使用的場景可能相對比較少,但是它們有時仍然可能對呼叫產(chǎn)生一定的影響。在SIP會話處理過程中,一個呼叫可能涉及了多個定時器,包括最底層的路由器的UDP超時設(shè)置和SIP服務(wù)器/IPPBX端的SIP終端的會話的超時設(shè)置。但是,這些超時設(shè)置取值的大小會引起相互之間的沖突。例如,如果路由器的UDP超時設(shè)置是60秒的話,SIP服務(wù)器的SIP終端超時設(shè)置為120秒,那么,路由器中ALG的這個UDP超時會首先啟動,超時后,UDP端口可能就會關(guān)閉,SIP服務(wù)器仍然多關(guān)閉的端口發(fā)送SIP呼叫的話,最終呼叫就會失敗。因此,路由器的ALG超時設(shè)置一定要高于SIP服務(wù)器的各種會話超時設(shè)置-keepalive(注冊超時,option超時,呼叫超時設(shè)置)的最低值,這樣可以保證SIP服務(wù)器端的SIP終端可能始終獲得開放的UDP端口。
在一些特殊情況下或者SIP服務(wù)提供商為了節(jié)省帶寬費用,SIP呼叫需要支持媒體轉(zhuǎn)發(fā)功能,繞過了SIP服務(wù)器的媒體處理能力支持,直接轉(zhuǎn)發(fā)到其他媒體服務(wù)器。通常情況下,如果需要支持類似的功能的話,技術(shù)人員需要在SIP服務(wù)器/IPPBX端進行設(shè)置,現(xiàn)在的PBX都有類似的功能支持。這樣的可以降低直接對接的SIP媒體服務(wù)器的負載,降低了帶寬資源的耗費,提高了點對點呼叫的效率提高,但是會導(dǎo)致SIP服務(wù)器錄音丟失,CDR記錄缺乏,缺乏呼叫控制等其他問題。路由器的ALG也可以支持類似的功能(sip-direct-media),如果用戶在路由器端的ALG上設(shè)置了類似的功能,那么,呼叫的媒體轉(zhuǎn)發(fā)就會直接在ALG上進行處理。

6、ALG相關(guān)工具
目前很多工具可以排查ALG的問題。Wireshark是首選的排查工具,用戶可以通過對路由器抓包來觀察進入路由器和離開路由器期間地址的變化。路由器開啟ALG以后,抓包測試SIP服務(wù)器地址,或者終端地址的變化。有時,一些用戶如果不能直接訪問路由器的設(shè)置的話,也可以下載測試工具來檢查自己的路由器是否開啟或者關(guān)閉了ALG設(shè)置。如下示例,如果筆者的網(wǎng)絡(luò)中支持了ALG開關(guān),ALG檢測工具可以檢測到true或者false的設(shè)置。

測試結(jié)果可以參照此說明來對照檢查:
- If the results = False then a SIP ALG was not detected by the client.
- If the results = True then a SIP ALG is active and must be turned off.
ruby sip-alg-detector-daemon.rb -i 99.88.77.66
具體使用方式參考:
sip-alg-detector
https://github.com/ibc/sip-alg-detector
7、路由器ALG功能的局限性
當(dāng)前的SIP呼叫業(yè)務(wù)的要求越來越復(fù)雜,本身路由器針對ALG功能支持相對比較簡單,它天生具有一定的局限性。所以,如果使用SIP呼叫時,很多用戶一般都關(guān)閉了ALG功能,通過SBC來處理SIP呼叫業(yè)務(wù),F(xiàn)在,我們討論幾個關(guān)于ALG功能局限性話題:
根據(jù)目前市場上,用戶對ALG的反饋,一些路由器廠家針對ALG或者SIP設(shè)置功能的支持不友好,帶來一些不穩(wěn)定的因素,所以很多用戶一般選擇關(guān)閉ALG功能。
ALG在NAT處理過程中替換一些必要的地址,有可能會替換掉SIP消息中的Call-ID的IP地址參數(shù)。如果修改了call-id的話,就會導(dǎo)致整個SIP會話管理出現(xiàn)問題,同一呼叫中系統(tǒng)出現(xiàn)了不同的會話消息,呼叫就會失敗。
一些兼容性不好的路由器針對ALG的語法構(gòu)建支持不好,很多時候在重寫SIP消息時,可能會出現(xiàn)一些非法的字符,ALG處理以后的SIP內(nèi)容格式破壞了SIP語法格式,SIP服務(wù)器端解析消息出現(xiàn)問題。
ALG僅支持了SDP的Payload,缺少針對SIP的其他支持,例如加密的SDP,TLS,F(xiàn)QDN解析處理,SIP認證處理機制,IPv6環(huán)境中對SIP的支持比較弱等問題。
針對SIP終端支持的BLF功能,其ALG兼容性相對比較弱(ALG僅支持3000-byte SIP 消息數(shù)據(jù))。因為BLF需要產(chǎn)生大量的Notify消息,這些消息數(shù)據(jù)會超過ALG所限定的數(shù)據(jù)量。大家可以想象一下,如果幾百臺SIP話機都開啟了BLF功能的話,都需要經(jīng)過ALG處理的話,它們之間相互交互交互就會導(dǎo)致路由器負載很高。如果因為大量數(shù)據(jù)交換引起系統(tǒng)的穩(wěn)定性問題,也可能最終導(dǎo)致其他的消息格式錯誤。因為UDP數(shù)據(jù)損壞導(dǎo)致的問題已經(jīng)是SIP呼叫的一個大的問題。UDP Fragmentation Breaks SIP in Today's IP-PBXs
http://blog.tmcnet.com/third-screen/2009/03/udp_fragmentation_breaks_sip_in_todays_ip-pbxs.html
ALG缺少針對SIP methods和安全,其他SIP拓展的支持。市場上,大部分的路由器缺少專門針對SIP應(yīng)用等功能比較完善的支持,一些廠家也針對ALG增加了一些針對SIP協(xié)議場景的拓展功能,因此,ALG功能得到了一定的提升。但是,其功能仍然很難完全滿足運營級SIP呼叫的業(yè)務(wù)需求。畢竟,路由器的產(chǎn)品定位和會話邊界控制器(SBC)的定位是不一樣的。因此,如果需要非常專業(yè)的專門針對SIP和媒體處理的業(yè)務(wù)需求,強烈建議用戶使用SBC來管理SIP呼叫和其他相關(guān)的業(yè)務(wù)功能。

通過SBC實現(xiàn)SIP分機的外網(wǎng)注冊功能
8、總結(jié)
路由器的ALG配置一直是用戶非常關(guān)心的話題。筆者認為,通過本文章完整的介紹,讀者可以基本上了解了關(guān)于ALG的功能,啟用/關(guān)閉ALG的條件場景,以及ALG目前的局限性。
首先,筆者介紹了ALG的使用背景和技術(shù)特點,然后筆者針對具體的場景分別做了不同的說明。用戶需要在什么時候開啟ALG功能,什么時候關(guān)閉ALG功能。通過非常細節(jié)的拓撲圖示例說明了工作的流程。然后,筆者介紹了幾款關(guān)于ALG檢測的實用工具,用戶可以直接通過本地根據(jù)來檢查路由器開啟狀態(tài)。最后,筆者討論了ALG的一些局限性,幫助讀者能夠?qū)LG有一個完整專業(yè)的認識,也幫助用戶能夠了解針對SIP的部署的解決方案-SBC。通過SBC部署滿足越來越復(fù)雜的SIP相關(guān)技術(shù)需求。
最后,筆者這里再次說明,本人沒有可能耗費太多精力去測試多臺路由器的ALG功能,因此不會針對每一款產(chǎn)品做出非常準確的評價,因此,在文章編寫過程中可能出現(xiàn)一些錯誤的表述,望讀者諒解。因為路由器廠家對ALG功能支持的力度有所不同,可能導(dǎo)致不同的設(shè)置結(jié)果。因此,強烈建議讀者自己親自在自己的環(huán)境中,通過不同配置,然后使用排查工具來進行實驗驗證。
參考資料:
https://tools.ietf.org/html/rfc2663
https://github.com/ibc/sip-alg-detector
https://tools.ietf.org/html/rfc4566#section-5
https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipaddr_nat/configuration/xe-3s/nat-xe-3s-book/iadnat-fw-sip-alg-hardng.html
https://wiki.asterisk.org/wiki/display/AST/Configuring+res_pjsip+to+work+through+NAT
https://www.researchgate.net/publication/291299719_Firewall-friendly_VoIP_secure_gateway_and_VoIP_security_issues/link/56c54e3a08ae736e704719a1/download
https://support.ringlogix.com/index.php?/Knowledgebase/Article/View/167/38/sip-alg-detector
https://fortinetweb.s3.amazonaws.com/docs.fortinet.com/v2/attachments/01b12c6d-1a17-11e9-9685-f8bc1258b856/fortigate-sip-60.pdf
https://www.juniper.net/documentation/en_US/junos/topics/topic-map/security-sip-alg.html
https://www.ecg.co/blog/125-sip-and-fragments-together-forever


關(guān)注微信公眾號:asterisk-cn,獲得有價值的Asterisk/SIP技術(shù)和行業(yè)分享
權(quán)威Asterisk freepbx FreeSBC技術(shù)文檔: www.freepbx.org.cn
完整企業(yè)融合通信商業(yè)解決方案:www.hiastar.com
如何使用FreeSBC+FreeSWITCH/Asterisk,qq技術(shù)分享群:334023047