docker-freepbx
docker-freepbx copied to clipboard
wrong IP set in SIP/SDP Header on opensuse Leap 15.1
Hi, first of all thanks for this awesome image! We've been using it for quite some time now in different versions and scenarios. It's really great!
On a recent deployment of freepbx-14-latest however, I noticed something odd. Maybe it's OS related, but I'm putting this up here and try to investigate the issue and hopefully report back with more info so others can find it. I start by describing the problem followed by how I've set everything up.
Problem
When deployed to a fresh OpenSuse Leap 15.1 host with 1 NIC attached to the local network of 192.168.35.0/24, outgoing SIP/SDP headers have the docker virtual network IP address set (look image down below) instead of the host IP which has SIP & RTP ports published to the network. This leads to no audio in both ways when calling one extension to another as no RTP packets can "reach" the PBX due to wrong headers being set in subsequential requests. So this is not really a NAT issue as both extensions are on the same subnet.
Setup
Network
- Range: 192.168.35.0/24
- Gateway IP: 192.168.35.1
- FreePBX Host IP: 192.168.35.2 / Published Ports 5060/udp, 18000-19000/udp
- Extension 1 IP: 192.168.35.4
- Extension 2 IP: 192.168.35.7
FreePBX / Asterisk Configuration
General SIP Settings -->NAT Settings External Address is set Local Network = 192.168.35.0/24
This config leads to the following packet flow:
Now, if I edit the asterisk config files and set local_net=192.168.35.0/24 external_media_address=192.168.35.2 external_signal_address=192.168.35.2 SDP headers are set correctly. Allthough this doesn't help much as I have no place to put the "real" external IP for NAT'ng to the trunk left. Different variant of local_net=192.168.35.0/24 media_address=192.168.35.2 external_media_address=EXTERNALIP external_signal_address=EXTERNALIP doesn't do the trick ether. In this configuration the SIP/SDP address is overwritten and set to the external IP.
Theory
I do have the suspicion that this is OS related. I have the same setup up and running in another location allthough the FreePBX host OS is CentOS there. Maybe there is problem with the docker bridge or virtual network interface.
If anyone has an any idea on how this is possible or how to fix it, feel free to hit those keyboard buttons.
I had a similar issue, managed to get audio to work by removing my local network from NAT Settings, Local Network. It's just the docker network in there now and audio works (172.18.0.0/16).
I haven't been able to figure out a way to get the SDP address to be correct for internal calls. It is always the docker address.
I tried to keep my scenario a bit pure by disabling direct-media. Meaning that all RTP flows must go through the FreePBX Server. With this configuration there seems no way to do any local NAT (container -> Network) manipulation of the SDP address.
@RowanTaubitz did you verify your SDP did not have the 172.18.0.x address? When direct-media is enabled it will probably work, but for example if you want to do call recording you always have to shift the stream back to the FreePBX server.
Ok. I found a way to do this, but I personally still have an issue with the contact header host part being the containers IP.
To solve the sdp issue though:
/etc/asterisk/pjsip.endpoint_custom_post.conf
[101](+)
media_address=192.168.253.4
You can add a media_address
per extension. In this case my extension is 101
It seems there is an identical issue with SIP traffic. I have seen my extension also try to connect to the docker IP with port 5060. But not in general.
At the moment incoming calls are working will with the provided workaround. But with outgoing calls is a hangup after 32 seconds.
16237[2022-10-29 22:22:36] VERBOSE[470388][C-00000017] bridge_channel.c: Channel PJSIP/36-00000029 left 'simple_bridge' basic-bridge <4a18f0df-3dd3-4354-b757-2fa6ed76aac4>
16238[2022-10-29 22:22:36] VERBOSE[470436][C-00000017] bridge_channel.c: Channel PJSIP/External-0000002a left 'simple_bridge' basic-bridge <4a18f0df-3dd3-4354-b757-2fa6ed76aac4>
16239[2022-10-29 22:22:36] VERBOSE[470388][C-00000017] app_macro.c: Spawn extension (macro-dialout-trunk, s, 27) exited non-zero on 'PJSIP/36-00000029' in macro 'dialout-trunk'
16240[2022-10-29 22:22:36] VERBOSE[470388][C-00000017] pbx.c: Spawn extension (from-internal, 01xxxxxxxx, 10) exited non-zero on 'PJSIP/36-00000029'
16241[2022-10-29 22:22:36] VERBOSE[470388][C-00000017] pbx.c: Executing [h@from-internal:1] Macro("PJSIP/36-00000029", "hangupcall") in new stack
This issue with NAT and docker can be solved using the network type macvlan instead of bridge and using an IP address without any NAT.
Create docker network
# docker network create -d macvlan -o parent=eth1 --subnet 192.168.1.0/24 --gateway 192.168.1.1 --ip-range=192.168.1.128/26 VoIP
docker-compose.yaml
services:
freepbx-app:
.........
networks:
default:
ipv4_address: 192.168.1.128
networks:
default:
external: bridge
name: VoIP
Make sure to keep the "internal" network (e.g., proxy-tier); remove "bridge" from external: bridge. This yaml-cutout works for me:
services:
freepbx-app:
[...]
networks:
VoIP:
ipv4_address: XXX.XXX.XXX.XXX
proxy-tier:
[...]
networks:
proxy-tier:
external:
name: net-nginx-proxy
VoIP:
external:
name: VoIP