Как вы делаете NAT обход для RTP медиа, используя Kamailio для сигнализации?

Есть три устройства под вопросом.

  1. VoIP телефон за NAT
  2. Мой собственный сервер Kamailio на экземпляре EC2.
  3. Приложение Linphone для Android на моем телефоне.

Мой телефон использует мобильные данные, и, поскольку у меня есть MVNO, он также выглядит как NAT (частный IP, например, 192.0.0.X).

Моя проблема заключается в том, что, хотя сигнализация SIP работает нормально, я не могу заставить ни одно устройство получать потоки RTP другого.

Я определил WITH_NAT в kamailio.cfg, но, похоже, он не помогает в сборе кандидатов. Вот приглашение до и после прохождения через Kamailio.

До:

Via: SIP/2.0/UDP 192.0.0.4:46244;branch=z9hG4bK.bLB4chm4B;rport.
From: "the app" <sip:105@<SERVERDOMAIN>>;tag=EHCGj~8d5.
To: sip:104@<SERVERDOMAIN>.
CSeq: 20 INVITE.
Call-ID: SyOH-iCt1A.
Max-Forwards: 70.
Supported: replaces, outbound, gruu.
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE.
Content-Type: application/sdp.
Content-Length: 721.
Contact: <sip:105@172.56.20.144:43565;transport=udp>;expires=3600;received="sip:172.56.20.144:43565";+sip.instance="<urn:uuid:f102067f-da3a-00f6-9530-ee66544ec6b4>".
User-Agent: <USERAGENT>/0.2.1-debug (Mobile Dev Environment 1) LinphoneSDK/4.1-366-g1b22291 (master) (belle-sip/1.6.3).
.
v=0.
o=105 911 2837 IN IP4 192.0.0.4.
s=Talk.
c=IN IP4 192.0.0.4.
t=0 0.
a=ice-pwd:42da1553a4faaaf4b57c93f2.
a=ice-ufrag:894dda61.
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics.
m=audio 7078 RTP/AVP 0 8 101.
a=rtpmap:101 telephone-event/8000.
a=candidate:1 1 UDP 2130706303 192.0.0.4 7078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 7079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
m=video 9078 RTP/AVP 96.
a=rtpmap:96 H264/90000.
a=fmtp:96 profile-level-id=42801F.
a=candidate:1 1 UDP 2130706303 192.0.0.4 9078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 9079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
a=rtcp-fb:96 nack pli.
a=rtcp-fb:96 ccm fir.

После:

Record-Route: <sip:<SERVERDOMAIN>:<PORT>;lr;nat=yes>.
Via: SIP/2.0/UDP <SERVERDOMAIN>:<PORT>;branch=z9hG4bKdd88.20b5965a3ea168d68a6b0603ebaa6c80.0.
Via: SIP/2.0/UDP 192.0.0.4:46244;received=172.56.20.144;branch=z9hG4bK.bLB4chm4B;rport=43565.
From: "the app" <sip:105@<SERVERDOMAIN>>;tag=EHCGj~8d5.
To: sip:104@<SERVERDOMAIN>.
CSeq: 20 INVITE.
Call-ID: SyOH-iCt1A.
Max-Forwards: 69.
Supported: replaces, outbound, gruu.
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE.
Content-Type: application/sdp.
Content-Length: 721.
Contact: <sip:105@172.56.20.144:43565;transport=udp;alias=172.56.20.144~43565~1>;expires=3600;received="sip:172.56.20.144:43565";+sip.instance="<urn:uuid:f102067f-da3a-00f6-9530-ee66544ec6b4>".
User-Agent: <USERAGENT>/0.2.1-debug (Mobile Dev Environment 1) LinphoneSDK/4.1-366-g1b22291 (master) (belle-sip/1.6.3).
.
v=0.
o=105 911 2837 IN IP4 192.0.0.4.
s=Talk.
c=IN IP4 192.0.0.4.
t=0 0.
a=ice-pwd:42da1553a4faaaf4b57c93f2.
a=ice-ufrag:894dda61.
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics.
m=audio 7078 RTP/AVP 0 8 101.
a=rtpmap:101 telephone-event/8000.
a=candidate:1 1 UDP 2130706303 192.0.0.4 7078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 7079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
m=video 9078 RTP/AVP 96.
a=rtpmap:96 H264/90000.
a=fmtp:96 profile-level-id=42801F.
a=candidate:1 1 UDP 2130706303 192.0.0.4 9078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 9079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
a=rtcp-fb:96 nack pli.
a=rtcp-fb:96 ccm fir.

Это та же история для входящих звонков.

Я ожидал, что модуль nathelper добавит что-то вроде

a=candidate:2 1 UDP 1694498815 <SOME_PUBLIC_IP> <SOME_PUBLIC_PORT> typ srflx raddr
192.0.0.4 rport 7078

но явно это не так. Я могу изменить o= а также c= в заголовках использовать IP-адрес, с которого сервер получил приглашение, но как сервер должен знать, на какие порты должен быть отправлен носитель RTP? Единственные порты, которые мог знать сервер

  1. Порт, с которого было отправлено приглашение (частная и публичная сторона)
  2. Порты предоставлены в sdp. Но это на частной стороне. Конечно, они будут другими на публике?

Любая помощь в этом будет оценена.

0 ответов

Вам нужно будет установить rtpproxy или rtpengine.

Вот простейшая процедура установки и настройки rtpproxy с Kamailio:

1- установить rtpproxy

apt install rtpproxy

2- Введите эти 2 строки в файл конфигурации rtpproxy (/ etc / default / rtpproxy):

CONTROL_SOCK=udp:127.0.0.1:7722
EXTRA_OPTS="-l IP-address"

IP-адрес - это внешний IP-адрес вашего хоста.

3- Введите это определение в верхней части файла конфигурации Kamailio (/etc/kamailio/kamailio.cfg):

#!define WITH_NAT

4- Перезапустите rtpproxy

systemctl restart rtpproxy

5- Перезапустить Камайлио

systemctl restart kamailio

В этом случае для сообщений INVITE и 200 OK, переданных Kamailio, их контактные IP-адреса и порты SDP должны быть заменены на соответствующие для rtpproxy.

Примечание. Я заметил, что по крайней мере один из UAC должен использовать TCP Transport, чтобы все вышесказанное работало.

Другие вопросы по тегам