如何让 Kamailio 将 `Record-Route` header 设置为内部 IP 以进行内部呼叫?

How to get Kamailio to set `Record-Route` header to internal IP for internal leg of call?

我在内部服务器上安装了 Kamailio 5.4.1(和 RTPEngine)运行,具有私有 IP 地址 172.31.7.96 和 One-to-one NAT 到外部 IP 地址。外部 IP 为 192.0.2.100。 (注意:内部 IP 地址都是未经编辑的,但是 public IP 已替换为 TEST-NET-1TEST-NET-2 示例地址。)我最终会使用 RTPEngine 进行转码,但现在这是一个简单的 SIP 代理。

我有一个 Java 应用程序,它在具有私有 IP 地址 172.31.7.171 的内部服务器上设置 SIP 呼叫 运行。 Java 应用程序已将 properties.setProperty("javax.sip.OUTBOUND_PROXY", "172.31.7.96"); 设置为使用 Kamailio 作为出站 SIP 代理。

Kamailio 服务器是标准的 Kamailio 示例配置,具有以下更改:

#!define WITH_NAT
#!define WITH_RTPENGINE
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_IPAUTH

#!define WITH_DEBUG

listen=udp:0.0.0.0:5060 advertise 192.0.2.100:5060

#!define DBURL "mysql://kamailio:REAL_PASSWORD_HERE@127.0.0.1/kamailio"

我已经使用 kamctl address add 172.31.7.171 32 5060.

将我的 Java 服务器的 IP 添加到 Kamailio 数据库作为允许的服务器

我正在尝试通过位于 198.51.100.200 的 SIP 服务器呼叫分机 2003

我的 Java 服务器遵循 OUTBOUND_PROXY 设置并向 Kamailio 发送以下请求:

INVITE sip:2003@198.51.100.200:5060 SIP/2.0
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 INVITE
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>
Max-Forwards: 70
Contact: <sip:+18005551234@172.31.6.171:5060;lr>
Content-Type: application/sdp
Via: SIP/2.0/UDP 172.31.6.171:5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Content-Length: 788

v=0
o=- 3808349342 3808349342 IN IP4 172.31.6.171
s=Kurento Media Server
c=IN IP4 172.31.6.171
t=0 0
m=audio 29134 RTP/AVPF 96 0 97
a=setup:actpass
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=rtpmap:96 opus/48000/2
a=rtpmap:97 AMR/8000
a=rtcp:29135
a=sendrecv
a=mid:audio0
a=ssrc:3129303479 cname:user3476653135@host-5072a15e
m=video 15672 RTP/AVPF 102 103
a=setup:actpass
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=rtpmap:102 VP8/90000
a=rtpmap:103 H264/90000
a=rtcp:15673
a=sendrecv
a=mid:video0
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 ccm fir
a=rtcp-fb:103 nack
a=rtcp-fb:103 nack pli
a=rtcp-fb:103 ccm fir
a=ssrc:1221454331 cname:user3476653135@host-5072a15e

Kamailio 正确修改并转发此请求到 SIP 服务器:

INVITE sip:2003@198.51.100.200:5060 SIP/2.0
Record-Route: <sip:192.0.2.100;lr;nat=yes>
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 INVITE
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>
Max-Forwards: 69
Contact: <sip:+18005551234@172.31.6.171:5060;lr;alias=172.31.6.171~5060~1>
Content-Type: application/sdp
Via: SIP/2.0/UDP 192.0.2.100:5060;branch=z9hG4bK9466.896020178e132b7f5da3e990cd54fe55.0
Via: SIP/2.0/UDP 172.31.6.171:5060;rport=5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Content-Length: 1048
P-Hint: outbound

v=0
o=- 3808349342 3808349342 IN IP4 172.31.7.96
s=Kurento Media Server
c=IN IP4 172.31.7.96
t=0 0
m=audio 50062 RTP/AVPF 96 0 97
a=ssrc:3129303479 cname:user3476653135@host-5072a15e
a=mid:audio0
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:97 AMR/8000
a=sendrecv
a=rtcp:50063
a=ice-ufrag:jd1CMyb6
a=ice-pwd:nOhBs6gMNStuK301ELxdXtu0qB
a=candidate:nA5nzY4ckB4NyJQB 1 UDP 2130706431 172.31.7.96 50062 typ host
a=candidate:nA5nzY4ckB4NyJQB 2 UDP 2130706430 172.31.7.96 50063 typ host
m=video 50094 RTP/AVPF 102 103
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 ccm fir
a=rtcp-fb:103 nack
a=rtcp-fb:103 nack pli
a=rtcp-fb:103 ccm fir
a=ssrc:1221454331 cname:user3476653135@host-5072a15ea=mid:video0
a=rtpmap:102 VP8/90000
a=rtpmap:103 H264/90000
a=sendrecv
a=rtcp:50095
a=ice-ufrag:k5OhtdDn
a=ice-pwd:R8U3hA1ocUe1ln1F5rpgyHRK98
a=candidate:nA5nzY4ckB4NyJQB 1 UDP 2130706431 172.31.7.96 50094 typ host
a=candidate:nA5nzY4ckB4NyJQB 2 UDP 2130706430 172.31.7.96 50095 typ host

在预期的 100 Trying180 Ringing 数据包之后,SIP 服务器发回一个 200 OK 数据包:

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.0.2.100:5060;branch=z9hG4bK9466.896020178e132b7f5da3e990cd54fe55.0;received=192.0.2.100;rport=5060
Via: SIP/2.0/UDP 172.31.6.171:5060;rport=5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Record-Route: <sip:192.0.2.100;lr;nat=yes>
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>;tag=as7825a958
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 INVITE
Server: FPBX-13.0.197.22(13.28.1)
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Contact: <sip:2003@198.51.100.200:5060>
Content-Type: application/sdp
Content-Length: 311

v=0
o=root 2047371680 2047371680 IN IP4 198.51.100.200
s=Asterisk PBX 13.28.1
c=IN IP4 198.51.100.200
b=CT:384
t=0 0
m=audio 14980 RTP/AVPF 0
a=rtpmap:0 PCMU/8000
a=maxptime:150
a=sendrecv
m=video 12536 RTP/AVPF 103 102
a=rtpmap:103 H264/90000
a=rtpmap:102 VP8/90000
a=rtcp-fb:* ccm fir
a=sendrecv

Kamailio 翻译并发回我的 Java 应用程序:

SIP/2.0 200 OK
Via: SIP/2.0/UDP 172.31.6.171:5060;rport=5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Record-Route: <sip:192.0.2.100;lr;nat=yes>
From: <tel:+16676664567>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>;tag=as7825a958
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 INVITE
Server: FPBX-13.0.197.22(13.28.1)
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Contact: <sip:2003@198.51.100.200:5060>
Content-Type: application/sdp
Content-Length: 363

v=0
o=root 2047371680 2047371680 IN IP4 172.31.7.96
s=Asterisk PBX 13.28.1
c=IN IP4 172.31.7.96
b=CT:384
t=0 0
m=audio 50076 RTP/AVPF 0
a=maxptime:150
a=mid:audio0
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:50077
m=video 50116 RTP/AVPF 103 102
a=rtcp-fb:* ccm fir
a=mid:video0
a=rtpmap:103 H264/90000
a=rtpmap:102 VP8/90000
a=sendrecv
a=rtcp:50117

这就是问题所在。我的 Java 应用程序看到 Record-Route header 显示 192.0.2.100 并尝试将 ACK 响应发送到该地址,并将其包含在 Route header:

ACK sip:2003@198.51.100.200:5060 SIP/2.0
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 ACK
Via: SIP/2.0/UDP 172.31.6.171:5060;branch=z9hG4bK-343236-57a2ec825886f425ef0b9f8cf2034887
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>;tag=as7825a958
Max-Forwards: 70
Route: <sip:192.0.2.100;lr;nat=yes>
Record-Route: <sip:192.0.2.100;lr;nat=yes>
Content-Length: 0

这里的问题是我的内部服务器实际上无法将流量路由到 Kamailio 服务器的 public IP,因此 ACK 永远不会到达那里。

我尝试像这样向 Kamailio 添加第二个 listen 指令,然后将 OUTBOUND_PROXY 设置为使用端口 5061,但随后 Kamailio 尝试将 172.31.7.96:5061 放入出站 SIP 消息也是:

listen=udp:0.0.0.0:5060 advertise 192.0.2.100:5060
listen=udp:172.31.7.96:5061

如何配置 Kamailio 在与内部服务器通信时使用其私有 IP,在与外部服务器通信时使用其 public IP?

为了解决这个问题,我转而在内部 SIP 服务器上使用 IPv6 发送信号,在 RTP 媒体上使用 IPv4。