下面對SIP協議產生NAT穿透問題,作一些解釋;及提出解決的辦法。
1、大致有4種類型的NAT。
a) Full Cone 完全圓錐體
b) restricted cone 受限制的圓錐體
c) port restricted 連接埠受限制的圓錐體
d) symmetric 對稱的
其中a,b,c 也稱作非對稱的NAT。
2、SIP終端在NAT後面,其工作有可能出現問題。原因是SIP信令走的路徑,和媒體流走的路徑不一樣。
3、Full Cone 完全圓錐體NAT
網際網路上的任何PC,可以發送資料包到IP:port對;而NAT將這個IP:port對(公網上的)映射到內網的IP:port對(私人網路的)。
4、restricted cone 受限制的圓錐體NAT
NAT外面的PC,只有那些內網中已有PC與之聯絡過的PC,才能通過這個映射進來。例如,我通過內網的一台機器,IP 位址是
10.1.1.1:123,與PC(a)聯絡,則PC(a)也可以通過這個NAT的映射,聯絡到我。而PC(b)則不行。
10.1.1.1:123 ---NAT ---> 202.70.65.78:10000 ------pc(a)
如果pc(b)也發送資料到202.70.65.78:10000,則不會有資料送到10.1.1.1:123。
補充說明:
如果我也聯絡過pc(b),則pc(b)也可以進來了。
10.1.1.1:123 ---NAT ---> 202.70.65.78:10000 ------pc(b)
如果pc(b)也發送資料到202.70.65.78:10000,則資料送到10.1.1.1:123。
5、port restricted 連接埠受限制的圓錐體NAT
除了4的條件外,即不但要檢測pc(a)的源IP地址,還要檢測其連接埠是否與前面也一樣。
10.1.1.1:123 --->NAT---->202.70.65.78:10000 -----> pc(a)[213.123.324.34:8000]
這個NAT只會接收從IP地址 213.123.324.34 且連接埠為 8000來的資料,讓進入到10.1.1.1:123。
6、對稱的NAT 這是關係描述最簡單的一個
10.1.1.1:1000 ----NAT -----> 200.123.123.34:1234 ----pc(a)
10.1.1.1:1000 ----NAT -----> 200.123.123.34:2222----pc(b)
這種NAT的IP:port對,對每個外部的程式,都是不同的。因而每一個外部的程式,都有自己的映射(NAT分配的IP:port對)。而前面的三種,多個外部程式,可能共用一個NAT的IP:port對。
7、RTP的問題
在RTP的訊息本文內,有UA能夠成功通訊所需要的一些資訊。這種訊息本文,就叫做SDP訊息。
問題在於,SIP終端(UA)可能對NAT一無所知。因而在SDP中包含的IP地址,通常使用內部的IP地址,也就是SIP終端知道的IP。這樣,當通訊的對方想與SIP終端通訊時,就查看SDP訊息中的IP地址,但是什麼也沒有得到,因為這裡使用的是內部IP地址。
下面舉個例子說明:
INVITE sip:040600@192.168.20.2:5060 SIP/2.0.
Record-Route: <sip:143.248.130.35;ftag=3a7ceb24a6ac50c4;lr=on>.
Via: SIP/2.0/UDP 143.248.130.35;branch=z9hG4bK758e.976609c7.0.
Via: SIP/2.0/UDP
192.168.20.3;rport=1024;received=223.178.140.109;branch=z9hG4bK34efcab2403aa20d.
From: "Iqbal" <sip:040618@sip.dom.com>;tag=3a7ceb24a6ac50c4.
To: <sip:040600@sip.dom.com>.
Contact: <sip:040618@223.178.140.109:1024>.
Supported: replaces.
Call-ID: 7f2c327896a5b0e1@192.168.20.3.
CSeq: 8717 INVITE.
User-Agent: Grandstream HT487 1.0.5.18.
Max-Forwards: 16.
Allow: INVITE,ACK,CANCEL,BYE,NOTIFY,REFER,OPTIONS,INFO,SUBSCRIBE.
Content-Type: application/sdp.
Content-Length: 343.
.
v=0.
o=040618 8000 1 IN IP4 192.168.20.3.
s=SIP Call.
c=IN IP4 192.168.20.3.
t=0 0.
m=audio 38660 RTP/AVP 0 8 4 18 2 15 99.
a=sendrecv.
a=rtpmap:0 PCMU/8000/3.
a=rtpmap:8 PCMA/8000/3.
SIP訊息的標題頭,類似於郵件的標題頭。從後往前看,從From行開始,看到第一個Via行,這是SIP終端自己認為的IP地址,例如192.168.20.3。但是SIPProxy 伺服器是聰明的,它知道這個訊息是從哪裡發過來的,它添加了rport和接收到的標誌:
Via: SIP/2.0/UDP
192.168.20.3;rport=1024;received=223.178.140.109;branch=z9hG4bK34efcab2403aa20d.
也就是說,SIPProxy 伺服器,知道發訊息的SIP終端的公網地址是223.178.140.109:1024。
這樣,SIPProxy 伺服器是可以與SIP終端通訊的,因為它知道SIP終端的公網地址。
但是,可憐的老式的RTP被阻塞了,因為它的標題頭如下:
v=0.
o=040618 8000 1 IN IP4 192.168.20.3.
s=SIP Call.
c=IN IP4 192.168.20.3.
t=0 0.
m=audio 38660 RTP/AVP 0 8 4 18 2 15 99.
a=sendrecv.
a=rtpmap:0 PCMU/8000/3.
a=rtpmap:8 PCMA/8000/3.
SIP終端期望從連接埠 port m=38660 且IP地址IP c= 192.168.20.3來接收RTP資料,而這個192.168.20.3:38660,就是通訊的對方試圖發RTP資料的目的地址。
這就是SIP電話響鈴總是能夠聽到,而接起來卻沒有聲音的原因。
8 解決辦法 告訴SIP終端,不要如此傻地工作,而要想辦法知道NAT分配給自己的連接埠映射。
並將公網的IP地址:連接埠放到SDP訊息中。這樣,SIP終端就問NAT....。或者是問公網的某個伺服器,NAT分配給自己的映射是什麼。
9 問NAT。 這種辦法就是使用UPnP協議,另外去參見UPnP的資料。
10 問公網上的某個伺服器。 如STUN伺服器。
SIP終端發送一個探測資料包,到公網上的伺服器。公網上的伺服器會發回資料包,會包含有關NAT的詳細資料。有了這些資訊,SIP終端就會知道它是否在NAT後面。這種探測方法,可以用於上面4種NAT,都有效。例如SIP終端從10.1.1.1:1000發送一個資料包,則SDP訊息中包含的是m=1000 and c=10.1.1.1。但是,如果SIP終端先進行NAT探測,則會知道NAT會分配公網的IP:連接埠是212.134.123.23:12345。則 SIP終端直接在SDP訊息寫m=12345,c=212.134.123.23。
產生的問題 因為NAT的連接埠分配是動態,因而有可能會改變。這樣,在發送了NAT探測訊息後,要很快地發送出SIP訊息。而且,SIP終端發送資料的連接埠和接收資料的連接埠要是一樣的。
注意受限制的圓錐體(包括連接埠受限制的圓錐體)NAT,它不讓回來的訊息進來,除非SIP終端先發了一個資料包給它。因而,SIP終端需要先發一個資料包給對方。這樣以後對方來的資料,就可以進入NAT內部了(不過,不需要為這個操作擔心,有辦法的)。
上面的辦法在對稱的NAT後面,不能夠工作。因為,對稱的NAT,它在分配給SIP終端外部的IP:port時,每次都變化(不同的對方不一樣)。也就是SIP終端在探測NAT時,得到的IP:port,與它後來發SIP訊息時,分配的IP:port不一樣。這樣,對方來的語音資料就進不來,因為對方得不到正確的IP:port。
11、上面描述的過程,其實就是採用STUN協議時,解決問題的過程。就是SIP終端向STUN伺服器發探測NAT的資料包。
12、對稱的NAT 解決辦法 就是在公網上放一個中轉語音流的伺服器。這個中轉語音流的伺服器有時就是一個Out Bound proxy。注意,這個中轉語音流的伺服器,可能會成為瓶頸。由於語音要經過中轉語音流的伺服器,所以路徑增長了,音質會變差。所以,對稱的NAT,要SIP能夠工作,總之是個麻煩。
不過,目前大多數的NAT,都可以做“虛擬伺服器的連接埠轉寄”,即將SIP工作需要的連接埠轉寄到SIP終端上去。如果在NAT裝置上,做了“虛擬伺服器的連接埠轉寄”,則NAT會保留SIP工作需要的連接埠,專用於SIP終端,這樣SIP終端就相當於是在一個Full Cone完全圓錐體的NAT後面,SIP用STUN工作沒有問題。SIP終端需要的連接埠數是這樣確定的,一個連接埠用於SIP信令,比如5060。RTP連接埠的數量,取決於通話的路數。一路通話需要2個RTP連接埠。每增加一路通話,則需要多2個連接埠。只支援一路通話的SIP話機,需要NAT映射3個連接埠。前面三種的NAT,可統稱為非對稱的NAT。非對稱的NAT,都可以用STUN協議穿過NAT。
將對稱的NAT,通過連接埠轉寄的方式,變為完全圓錐體的NAT,是解決NAT問題的最好辦法。首先應當用這種辦法來解決。沒有辦法映射連接埠,再想其它的辦法。當然,建議大家不要買那種不能夠映射連接埠的寬頻路由器,那樣的路由器太差了。