Poll: pfSense and VOIP

OK, so this is probably just some comic relief for me after hours spent running through tutorial after help page after religious rite to try and get audio routing from FusionPBX <-> pfSense <->internet <-> pfSense -> Yealink. To date, nothing has succeeded - SIP is fine, RTP is being lost. Is the situation best described as:

A - I'm a moron in over his head. Give up and pay someone who knows what they're doing
B - pfSense and SIP/RTP is hard. You'll get it if you keep trying, or maybe switch to {recommended} router instead
C - VOIP is just black magic and will only work during the full moon if you hold your tongue correctly.
 

DigitalDaz

Administrator
Staff member
It shouldn't be too difficult, I use pfsense without problem, pretty sure I have used this scenario before.

What I guess would be the problem is that by default pfsense is going to do PAT on the audio ports and so the SDP is essentially going to be all wrong.

Have you got a port forward for 16384-32768 UDP??

Also, because its behind NAT and not a big install, you may want to reduce that amount significantly in switch.conf.xml and adjust the forwarding accordingly.
 
I tried FusionPBX - pfSense - Internet - Fortigate - phone

using Grandstream as phone, or Jitsi, all ok
using some old Cisco 303, nothing (phone registered, but no signal for incoming call)

however, pfSense can work well. You may have only the standard trouble with NAT to solve..
 
Thanks guys, I shall persevere. Good tip Daz re reducing the RTP size, I hadn't considered that but you are correct; there is no way I need that many ports open. I've established that I have one-way audio across both firewalls (outbound fine, inbound lost) so hopefully once I figure out the issue on one it will be the same fix on both.

Cheers for the vote of confidence, I needed that...
 

DigitalDaz

Administrator
Staff member
You shouldn't need to touch the pfsense that has the Yealink behind it at all, in fact doing so will probably make things worse. Just make sure to use tcp as the transport and in the account advanced settings of the yealink, make sure rport is enabled.
 

DigitalDaz

Administrator
Staff member
TCP is generally much better at NAT handling, it keeps the tunnels open on the routers much longer than for udp. It also handles bigger packets which are getting much more common now I think at my carrier the opus codec alone adds 239 bytes to the packet, they have made a setting to make this optional as it was breaking a lot of UDP traffic.
 
Hmm, OK. TCP it is... I would assume that packet sizes are only going to get bigger rather than smaller in the near future.

Haven't had a lot of time the last couple of days to figure out the pfSense quirks, but I did have the chance to put the phone behind a Unifi stack (USG/Switch) and inbound audio traversed that just fine; I guess my option of last resort will be to swap out pfSense for a USG in front of the PBX. Not a great option, I quite like pfSense after fiddling with it for a few years.
 
You shouldn't have a problem with pfsense and Fusion. I have a very funky test setup and it works when it probably shouldn't (lots of nating, douuble nating, etc), ok so lecture over lets check a few simple things:

Check the RTP port range in the phone config to make sure it matches. For that matter double check it on the firewall and Fusion PBX as well.
Check Iptables on the fusion box to make sure the ranges match and there's nothing silly in the rules. Remember you can set up sip as TCP but I'm pretty sure RTP is always UDP.
Check your sip profile and make sure you have ext-rtp-ip set up properly (hard code it for now just for testing).
Use sngrep wherever you can to see what RTP ports are being advertised in the sip messages.
You may also want to check and see if its trying to do zrtp or something out in left field.
Make sure there's no random codec mismatch (although if you get one way audio it rules that out)

Honestly as was mentioned you shouldn't have to do anything on the phone side, so if you've been messing with rules and port forwarding get rid of it. Same on the fusion side, just SIP port forward and RTP port forward. narrowing the port range was mentioned, but you could also widen it on the firewall as well just in case one of the devices isn't respecting your port range setting (maybe 10k to 40k).

Also look at the SIP profile in the CLI when you do a reload and make sure your values for RTP are being repected in the profile.

Just my two cents
 
I have this exact setup without any issues. I believe what you are missing is your outbound NAT configuration on pfsense.

Do the following on the pfsense on the fusionpbx side
Go to Firewall, NAT, Outbound
Change the Outbound NAT Mode to Hybrid
Add a Mapping
Interface should be your WAN interface
For source select Network and enter the internal IP of the fusionpbx server / 32 (Leave Port or Range blank)
Under the Translation Section the Address should be your public IP dedicated to fusionpbx (See notes below)
check the Static Port box

With these setting in place, pfsense will not PAT or port translate your packets from the fusionpbx server. This means the ports that fusionpbx creates will be the same source port numbers use when the packets leave the WAN interface. If you only have 1 public IP from your ISP and fusionpbx is not the only device attached to pfsense, it is possible that the ports fusionpbx creates may already be used for other outbound traffic from another device. To prevent this from ever happening, you would want a second IP from your ISP dedicated to fusionpbx.
 
OK, so I got this working, but I'm unsure as to why. On a hunch, I changed the sip-ip and rtp-ip on the Fusion internal profile to track the external IP address. This got the phones outside the firewall working, but broke the ones inside the firewall (SIP was OK, RTP was not).

I then changed sip-ip and rtp-ip back again to get the main office back online, but the remote phones have continued to work correctly. I'm at a loss to explain why... but loving that they are working, and I can keep pfSense as my primary firewall. Thanks all!
 
Correction... softphones (X-Lite) are working, the Yealinks are still not.

- I've set the static port setting on the NAT table for the PBX, seemingly without effect
- iptables firewall rules appear to be correct, they are out of the box default I believe

Looking at a wireshark of the X-lite call vs the yealink one, it seems like the pbx is sending the RTP back to the wrong place (a LAN IP rather than the public WAN IP). Is this a setting in the phone that I need to deal with somewhere?
 
Last edited:
Try creating a different profile just for the remote phones using your hard coded ext-sip and ext-rtp settings. You'll most likely need to use a different SIP port but that should straighten things out for you.

However are you sure your setting ext-sip and ext-rtp properly in your profile?
 
Thanks for following up... to be honest, I have no idea about ext-sip and ext-rtp; they are currently just set at defaults for the install I believe. I got all excited at the suggestion of a separate profile thinking that had to fix my problem, but after configuring that the symptoms are the same - X-Lite works and Yealinks don't.

I've done a side-by-side comparison of the INVITE packets sent by simultaneous calls, one from the Yealink and one from X-Lite, both on the same remote network. There are quite a few variations, not entirely sure what I'm looking for but the most significant difference seems to be this:

X-lite (working):
Code:
Contact: <sip:S1101@{remote wan IP}:35299;rinstance=cb992b528295391c;transport=tcp>
    Contact URI: sip:S1101@{remote wan IP}:35299;rinstance=cb992b528295391c;transport=tcp
        Contact URI User Part: {user id}
        Contact URI Host Part: {remote wan ip}
        Contact URI Host Port: 35299
        Contact URI parameter: rinstance=cb992b528295391c
        Contact URI parameter: transport=tcp
Yealink (not working):
Code:
Contact: <sip:S1010@{private lan ip}:12748;transport=TCP>
    Contact URI: sip:S1010@{private lan ip}:12748;transport=TCP
        Contact URI User Part: {user id}
        Contact URI Host Part: {private lan ip}
        Contact URI Host Port: 12748
        Contact URI parameter: transport=TCP
After that, both calls negotiate to the g722 codec, and the wireshark flow shows RTP being sent back to the private LAN address of both devices, using different port numbers than the contact host port above.

Sorry I really have no idea what I'm looking for once it gets to this level... any tips on what to look for?
 
Possibly relevant, I've been reviewing the call logs in Fusion, and noted the following difference between the two calls:

X-Lite (working):
Code:
remote_audio_ip     {remote wan ip}
remote_media_ip     {remote lan ip} 
remote_audio_port 53406
remote_media_port 53406
Yealink (not working):
Code:
remote_media_ip     {remote lan ip}
remote_media_port 12690
I would assume that the Yealink not having a remote audio ip/port in the call detail records would be part of the problem?
 
Last edited:
Thanks, don't mind a bit of spaghetti, things usually have to get messier before they get better.

RPort was already enabled, but I tired the other options (disabled, enable direct process) without success - all calls go past the imaginary 32 second boundary but with no audio. Didn't have time to run a trace on them but will try that later tonight.

I read on the 3CX forums that sometimes the Yealink firmware was the culprit, but I've tried a few versions going back and that doesn't seem to change the behaviour either. Thinking the next step might be to try and source a Polycom or Snom and give that a whirl, see if it is a Yealink specific issue or whether X-Lite is doing something special.