NAT Traversal

From FreeSWITCH Wiki
Jump to: navigation, search

Superseded by Confluence


Some difficulties have been encountered with devices that have poor NAT support.

In order to aid FreeSWITCH in traversing NAT please see the External profile page.

Some routers perform ALG (Application Layer Gateway) which can prevent NAT traversal from working, see that page for more information including how to disable it.



Enable STUN settings on your phone in order to correctly report you phone's contact information to FreeSWITCH when registering. Unfortunately, not all phones have a STUN client.

STUN support by phone manufacturer

  • Snom: Yes
  • Sipura: Yes
  • Cisco: No
  • Polycom: No ('planned future support')

STUN servers

This site contains a list of STUN servers:
Note: is gone; also is never guaranteed to be up and running so use it in production at your own risk.


You can add the apply-nat-acl param to your profile to always force NAT behavior when matching a certain access list

<param name="apply-nat-acl" value="rfc1918"/>

Possible values of apply-nat-acl using access list:


<action application="set" data="sip_sticky_contact=true"/>


sip_nat_detected is set to true when NAT is detected. Use it in your dialplan to handle NATted devices differently.

<condition field="${sip_nat_detected}" expression="true">


The sip-force-contact variable can be used to activate NATHACK / TLSHACK registration (rewrite contact IP/port).


<user id="100" mailbox="100">
      <param name="password" value="1234"/>
      <param name="vm-password" value="4321"/>
       <variable name="sip-force-contact" value="NDLB-connectile-dysfunction"/>


Rewrites contact IP and port to that of the NAT device by looking at IP address/port info from the packets reaching FreeSWITCH. This is similar to the way Asterisk tries to deal with NAT traversal.


Rewrites contact port


Needs documentation; apparently rewrites IP and port and adds a `fs_path` parameter in the Contact header.

Phone NAT Settings

Your phone may allow you to specify an IP to use when registering.


<nat nat.ip="" nat.signalPort="" nat.mediaPortStart="" nat.keepalive.interval=""/>

FreeSWITCH behind NAT

With FreeSWITCH behind NAT, FreeSWITCH can only bind its ports to a local IP. However when connecting to FreeSWITCH from an external network, the external IP is needed.

With the standard setup users may be able to register phones correctly, however the phones may not be reached and you may encounter no audio or one way audio when a call is set up.

This is one working example for FreeSWITCH behind NAT:


<X-PRE-PROCESS cmd="set" data=""/>
<X-PRE-PROCESS cmd="set" data=""/>
<X-PRE-PROCESS cmd="set" data=""/> is another possible value; however this will not toggle the autonat flags. If you are behind NAT, with dynamic DNS (and stun doesn't work) you should write a script that determines your public IP address, makes the change and calls reloadxml. This also holds true for the external profile. No special processing happens to determine the IP address before the variable gets passed to the external profile. may be used in places "where you have two interfaces in a box and one is public facing and one isn't, so one never has to tell the lies."

  • source bwk on irc.


<param name="ext-rtp-ip" value="$${external_rtp_ip}"/>


<param name="ext-sip-ip" value="$${external_sip_ip}"/>
<param name="ext-rtp-ip" value="$${external_rtp_ip}"/>

Do not set ext-rtp-ip to a domain name instead of an IP or STUN entry; you will encounter a "SIP/2.0 500 Cannot Get IP Address for Media" error.

By default external_sip_ip and external_rtp_ip are set in vars.conf.xml to use the FreeSWITCH STUN server.

Limited port forwarding

Some firewall providers provide limited support for port forwarding or virtual servers or whatever they are called by the provider. To help, FreeSWITCH can limit the ports it will use for RTP streams, so you don't have to forward 16,000 ports. You will need enough to handle all media channels coming across the firewall. Keep that in mind.

In conf/autoload_configs/switch.conf.xml you can use the following variables:

<param name="rtp-start-port" value="16384"/>
<param name="rtp-end-port" value="16389"/>

In the example above, you only need to forward 6 ports, but it will also only allow up to 6 audio channels across that connection, and depending on networking configurations, maybe not even that. Be very careful with your expectation level here.

Distilled Wisdom

Archived for posterity from: [[1]]

Kristian Kielhofner <kris at> Wed Nov 21 07:49:52 MSK 2012

You can rewrite the SDP to anything you want but that doesn't mean you'll get media.

I suggest you do some research on the two main schools for SIP NAT traversal (far end and near end). In a nutshell, far end NAT traversal is implemented by the server. This is the FreeSWITCH default. The SDPs are rewritten to the address of the FreeSWITCH server and passed to the remote endpoint. This causes the media to be relayed at the server between the endpoints. This has the advantage of being universally compatible - regardless of how dumb the endpoint(s) is/are. Disadvantages are many - increased sever load, bandwidth, latency, etc. However, with many endpoints this is the only choice.

Near end NAT traversal relies on advances technologies such as STUN, TURN, and ICE to be supported by the client (and the servers to enable them configured and available). TURN actually blurs the lines between these two strategies, as do various hybrid approaches using local proxies, etc but that's for another day.

Bypass media is incompatible with NAT unless you're using STUN/TURN/ICE in your clients and even then I'm not sure FreeSWITCH will completely and cleanly handle the various ICE/SIP/SDP interactions.

Related Pages