我有一些客户端连接到 NAT 设备后面的 Asterisk 服务器。使用 TCP 时一切正常。如果我将客户端和服务器配置更改为使用 UDP(从 到transport=tcp
甚至transport=udp,tcp
只是transport=udp
),手机将无法再注册,Asterisk 会将数据发送SIP: SIP/2.0 401 Unauthorized
到客户端。
据我所知,Asterisk 可以在 NAT 后面使用 UDP,但经验似乎表明并非如此。我是否错过了另一个必需步骤,还是还有其他我不知道的事情?
需要澄清的是:NAT 设备后面的是客户端;而不是服务器。
这是我的 sip.conf 的相关部分:
[general]
context=bogus
allowguest=no
allowoverlap=no
bindport=5060
bindaddr=0.0.0.0
srvlookup=no
disallow=all
allow=ulaw
alwaysauthreject=yes
videosupport=yes
canreinvite=no
nat=force_rport,comedia
session-timers=refuse
localnet=x.x.x.x/255.255.0.0 ; blanked out for serverfault
tcpenable=yes ; Enable server for incoming TCP connections (default is no)
tcpbindaddr=0.0.0.0:5060 ; IP address for TCP server to bind to (0.0.0.0 binds to all interfaces)
transport=udp,tcp
[my-codecs](!) ; a template for my preferred codecs
disallow=all
; allow=ilbc
; allow=gsm
; allow=g723
allow=alaw
allow=ulaw
; allow=g722
[basic-options](!,my-codecs) ; another template
dtmfmode=rfc2833
context=internal
type=friend
[natted-phone](!,basic-options) ; another template inheriting basic-options
directmedia=no
host=dynamic
transport=tcp,udp
[101](natted-phone)
callerid="Office"
secret=12345678901234567890
context=internal
mailbox=101@main
transport=udp,tcp
更新:经过调查,我发现这似乎只影响 Avaya 手机。连接到同一服务器的其他软件电话似乎没有遇到此问题。以下是注册和未授权数据包的示例:
asterisk*CLI> sip set debug on
SIP Debugging enabled
<--- SIP read from UDP:x.x.x.x:1032 --->
REGISTER sip:asterisk SIP/2.0
From: sip:2003@asterisk;tag=46c2abf4589053ec5895ffc0_F2003192.168.0.174
To: sip:2003@asterisk
Call-ID: [email protected]
CSeq: 1 REGISTER
Via: SIP/2.0/UDP 192.168.0.174;branch=z9hG4bK1_5a7d12149bcad5895ffc4_R2003
Content-Length: 0
Max-Forwards: 70
Contact: <sip:[email protected];avaya-sc-enabled;transport=udp>;q=1;expires=900;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-1000-8000-2cf4c54ef19b>"
Allow: INVITE,CANCEL,BYE,ACK,SUBSCRIBE,NOTIFY,MESSAGE,INFO,PUBLISH,REFER,UPDATE
User-Agent: Avaya one-X Deskphone
Supported: eventlist
<------------->
--- (12 headers 0 lines) ---
Sending to x.x.x.x:1032 (NAT)
Sending to x.x.x.x:1032 (NAT)
<--- Transmitting (NAT) to x.x.x.x:1032 --->
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.0.174;branch=z9hG4bK1_5a7d12149bcad5895ffc4_R2003;received=x.x.x.x;rport=1032
From: sip:2003@asterisk;tag=46c2abf4589053ec5895ffc0_F2003192.168.0.174
To: sip:2003@asterisk;tag=as5f37e30b
Call-ID: [email protected]
CSeq: 1 REGISTER
Server: Asterisk PBX 13.1.0~dfsg-1.1ubuntu4
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces
WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="2350c222"
Content-Length: 0
答案1
当在 NAT 后面使用 Asterisk 时,你应该始终将externip
选项与nat
选项一起添加到你的sip.conf
尝试这个
[general]
nat=force_rport,comedia
externip=<your external IP here>
... rest of your config ...
一些客户端还允许指定“代理地址“字段除了SIP 服务器地址&SIP 域。使用 NAT 时,您应该将外部 IP 放在那里。因此,这样的配置也应该能保证您的安全:
SIP Server: 192.168.1.200 (Servers internal IP)
SIP Proxy: 1.2.3.4 (Servers external IP)
SIP Domain: 192.168.1.200 (Servers internal IP)
最后,通过运行以下命令实时检查您的星号日志:
asterisk -rvvvv
会帮助您诊断很多问题,因为401 Unauthorized
可能与 ACL 问题有关(例如当对等 IP 与 sip.conf 中指定的允许/拒绝选项不匹配时)。在这种情况下,Asterisk 将给出如下错误:
SIP Peer ACL: Rejecting '1.2.3.4' due to a failure to pass ACL '(BASELINE)'
PS 这可能会帮你省去很多麻烦。一定要记住转发全部范围的 RTP 端口,这些端口/etc/asterisk/rtp.conf
在
rtpstart=50000
rtpend=60000
那么你应该无条件地将 50000-60000 个 UDP 从你的 [外部 IP] 转发到你的 asterisk,或者你将要面临很多奇怪的问题(例如无法可靠地转接电话,随机语音丢失/断开连接以及许多其他您绝对不想要的事情)......
答案2
这是正确的行为 - 您必须了解 NAT 的工作原理!NAT 只能通过保存打开的连接表(由 SYN ACK 打开,由 FIN ACK 关闭)来跟踪连接。但只有 TCP 使用连接;UDP 是无连接的。
因此,NAT 设备甚至不会尝试根据连接状态路由 UDP 数据包。如果您需要对 UDP 数据包进行 NAT 遍历,则必须根据端口范围、源 IP 等创建静态规则。