FreeSwitch and NAT problems

Anyone who's played with SIP knows that the nutters who designed that protocol (in the late 1990s; RFC 2543 was published in 1999) totally failed to learn from the problems with FTP from the early 1970s and Network Address Translation, by burying IP addresses inside the layer 7 protocol and hence causing all sort of problems when either your telephone (most commonly) or your PBX (less often) or even both (a terrible combination to get working) is behind a NAT router (such as nearly everyone has both at home and in offices these days).

However, the world has worked out ways around this (note for the inexperienced: if you ever come across a router with a feature called SIP ALG (Application Layer Gateway) or SIP Helper then TURN IT OFF. It does not help, and it positively causes problems), and if you're using Asterisk as your PBX you basically don't have to bother about it - it just works.

On the other hand, the FreeSwitch developers have come up with a new (and in my opinion quite creative) way of turning NAT into a problem for you.

Assuming you start out by installing FreeSwitch on a machine inside your own network, and you simply plan to play with it with a couple of telephones on the same network, until you feel you know what you're doing, you might think there is no NAT involved, because everything is on a single, simple, flat network.

Not with FreeSwitch, it isn't.

As soon as you start FreeSwitch (on a machine on your own internal network) it will attempt to discover what the external (public) IP address of your Internet router is, an then it will start using that public address when communicating with the telephones you have sitting next to it, also on your own internal network!

Quoting from /etc/freeswitch/README_IMPORTANT.txt:

By default, FreeSWITCH starts up and does a NATPMP and UPnP request to your router.
If your router supports either of these protocols then FreeSWITCH does two things:
#1 - It gets the external IP address, which it uses for SIP communications

(The second thing isn't important for this diatribe right now, but you should read that file very carefully for yourself.)

It goes on to say "The way to disable the auto-nat (that is, UPnP/NATPMP) checking is to start FreeSWITCH with the "-nonat" flag. Easy enough."

Easy enough??? Where am I supposed to put this "-nonat" flag?

  • /etc/init.d/freeswitch start -nonat
    • makes no difference - it starts up and tells your internal phone to talk to your external address
  • /etc/init.d/freeswitch -nonat start
    • "Usage: /etc/init.d/freeswitch {start|stop|status|restart|force-reload}"
  • There is no file /etc/default/freeswitch, where most other applications would allow you to put special startup flags
  • It isn't mentioned anywhere in /etc/init.d/freeswitch
  • It doesn't exist anywhere in the configuration tree /etc/freeswitch and downwards

I looked in more detail at /etc/init.d/freeswitch and noticed that it does attempt to include the (non-existent, unless you think to create it yourself) file /etc/default/freeswitch, and it also appends whatever is in the (undefined) variable $DAEMON_OPTS to the command-line when it starts FreeSwitch.

So, I created /etc/default/freeswitch and entered DAEMON_OPTS="-nonat", then restarted FreeSwitch and even checked the process command line to see whether it had taken effect:

ps ax | grep freeswitch
 3678 ?        S<Lsl   0:02 /usr/bin/freeswitch -u freeswitch -ncwait -nonat

Yay! The option is there.

Bah! It doesn't work.

Placing a call from one internal extension to the other still presents the public IP address of the outside of my router to the other telephone in the SDP packet as where it should send its audio to. This is also confirmed by the command sofia status profile internal - you'll see seven instances of your internal IP address and four instances of your external address.

So, for the time being I'm unimpressed but I'll persevere until I work out how to tell FreeSwitch I just want it to work on the local network and ignore the rest of the world.

You don't get this sort of thing with Asterisk.

Aside: for some reason, the -nonat flag shows up by default if you install FreeSwitch under Debian with systemd, because it's included in /usr/lib/systemd/system/freeswitch.service

Update: it occurred to me that a workaround (not an ideal solution, but a way to make some progress) would be to simply remove the default route (to the Internet) from the FreeSwitch server, so that it can't find out what the external router's public IP address is.

That stops FreeSwitch from working at all. It'll start, but a phone on the local network can't even register.


Go up
Return to main index.