Demystifying NAT settings in FreeSWITCH

Now that we have reviewed the common pitfalls of NAT, we can go over the various types of NAT situations that you may encounter. Basically you will probably be in a situation where either your phone or PBX is behind NAT talking to a SIP endpoint that is not behind NAT (or vice versa). Even worse, you might end up in the dreaded double-NAT situation where both sides of a connection are independently behind their own individual NAT routers at the same time.

A double-NAT scenario looks like the following diagram:

Let's start with a sane, yet challenging situation where you have a phone at your house that can't understand NAT and you want to register to your FreeSWITCH server that is on the public Internet. The good news is that this situation is already covered for you by the example FreeSWITCH demo configuration. The core of FreeSWITCH has a feature called ACL (Access Control Lists). An ACL lets you create lists of network addresses and control access to things depending on whether or not a particular device is originating from an address defined by the ACL. There is equal value in determining if an address matches or does not match a list and from there deciding if being (or not being) on the list is a good or bad thing.

This feature makes it possible to allow certain devices to authenticate based on their IP address or you can make a list of enemy devices so you can completely block anyone who is on the list. In this case we will use the ACL to determine if a device is behind NAT or not and decide what to do from there.

A device behind NAT is likely to have an IP address within a special range called RFC-1918. The easiest explanation for this is that there is a special set of IP addresses that never lead to the Internet because they are reserved for private use on LANs. This is basically any IP address that starts with 192.168.x.x, 172.16.x.x through 172.31.x.x, or 10.x.x.x. We'll just call them LAN addresses from now on. People call them also as per the RFC, eg "rfc1918 addresses".

Because these addresses are private, there can be endless networks using the same exact IP addresses internally but they can never connect to each other. Now when you connect these networks to a NAT router, all the phones on these private networks will be able to reach your FreeSWITCH server. The routers work by keeping track of all the traffic coming from the LAN addresses and sending it to the Internet as if it was coming from the public Internet IP on the router. Then, when the destination on the Internet sends a response to the NAT router, it uses the mapping to deliver the packet back to the sender. The source address that FreeSWITCH sees the traffic originating from may never be the same and this makes it very difficult to send an incoming call to the phone. This is where the ACL comes in handy.

FreeSWITCH has a configuration parameter for mod_sofia profiles called apply-nat-acl. This parameter can be used more than once in the same profile and expects the name of an ACL list. When mod_sofia gets SIP REGISTER or INVITE packets, it looks at the contact address and checks the IP referenced in the Contact header against the specified ACL. If there is a match, it concludes that the device must be behind NAT. It's difficult to tell which IPs represent devices behind NAT but we have a bit of a clue. Remember RFC-1918 or LAN addresses as we called them? Since it's a defined range of IP addresses, we can conclude that if you are coming from one of these addresses then you are calling from behind NAT.

Be careful! Don't forget the fourth pitfall, it's not 100 percent safe to assume every device coming from a LAN address is behind NAT. This may not always be the case but more times than not it is. It's just good to be wary. One case where it may not be true is when FreeSWITCH also has a LAN address because it's behind NAT too. Well, we have a special ACL that is created for you when FreeSWITCH starts, called nat.auto. This special ACL already contains the entire RFC-1918 address space but it also checks the machine's local network address and excludes that address space so you won't get any false positives when it gets calls from phones on the same LAN as FreeSWITCH. At the same time this ACL can detect a phone that is actually in a remote location behind NAT. FreeSWITCH comes pre-configured with apply-nat-acl set to nat.auto and can correct most typical device behind NAT versus FreeSWITCH on the public Internet situations.

How do we solve the problem? Basically, when the phone registers from behind NAT and it's detected, we save the IP and port that we saw the register originate from and store it in the internal database alongside the unreachable LAN address that the unsuspecting phone has provided us. When we need to contact this phone, we consult our database and determine the external IP:port to which the message should be sent. The SIP headers will still have the internal IP:port values that the remote phone is expecting to see. We also tell the phone to register more frequently so that the mapping stays open, since most NAT routers only hold a translation path open for a short period of time. This technique is especially effective in avoiding the other part of the fourth pitfall because we never modified the intended address at all like the evil ALG.

Here is an example of output from the FreeSWITCH CLI (Command Line Interface). The client is a softphone behind NAT registering to an instance of FreeSWITCH running on a public IP. Notice the Contact field is using the IP 10.0.1.85 that is a LAN address. The status shows that UDP-NAT was detected thanks to the nat.auto ACL list. The trick comes in at the end of the Contact. The extra parameters fs_nat and fs_path are appended to the Contact address of the phone registration so we can figure out how to circumnavigate the NAT. Consider the following:

fs_nat=yes 
fs_path=sip%3A1006%40206.22.109.244%3A43425%3Brinstance%3Db67dbafc
9baa9465%3Btransport%3Dudp.

The fs_path field is a SIP URI (Uniform Resource Identifier) that actually will lead back to the phone through NAT. It's URL-encoded, so special characters in the URI do not conflict with the real contact. The decoded version of this field is:

sip:[email protected]:43425;rinstance=b67dbafc9baa9465;transport=udp 

So even though when we call the phone we will send the INVITE network packet to 206.22.109.244:43425, we will keep it addressed (in the text of the packet) to 10.0.1.85:5060 and that is exactly where it will end up once the NAT translation takes place and the remote router delivers it to the phone. You can see the complete set of registration information using the sofia status profile internal reg command. The following is an example:

freeswitch@myhost> sofia status profile internal reg 
Registrations: 
================================================================ 
Call-ID:        ZWU1MjdiZTI2MTg2MmVhNTc5NTk3MDY5YjFmOTVkMTU. 
User:           [email protected] 
Contact:        "TEST"<sip:[email protected]:10118;rinstance=b67dbafc9baa9465;transport=udp;fs_nat=yes;fs_path=sip%3A1006%40184.58.189.244%3A43425%3Brinstance%3Db67dbafc9baa9465%3Btransport%3Dudp> 
Agent:          eyeBeam release 1104g stamp 54685 
Status:         Registered(UDP-NAT)(unknown) EXP(2012-12-09 10:18:07) EXPSECS(88) 
Host:           myhost 
IP:             206.22.109.244 
Port:           43425 
Auth-User:      1006 
Auth-Realm:     myhost.freeswitch.org 
MWI-Account:    [email protected] 
Total items returned: 1 
================================================================ 

Notice that the Contact: header contains both the fs_nat and fs_path parameters. Any SIP traffic that FreeSWITCH needs to send to user 1006 will use the URI specified in the fs_path parameter.

Following we have another example, with a more modern client and in the popular situation where both the client and the server are behind different NATs. In this case the client is able to correct its own address using the data sent to him by FreeSWITCH.

Our Linphone send the following as first REGISTER SIP packet:

REGISTER sip:lab.opentelecomsolutions.com SIP/2.0 
Via: SIP/2.0/UDP 192.168.1.200:5060;branch=z9hG4bK.znT45Avvt;rport 
From: "Sara"<sip:[email protected]>;tag=cfurzFSzg 
To: "Sara"<sip:[email protected]> 
CSeq: 20 REGISTER 
Call-ID: kMq3GlIAVx 
Max-Forwards: 70 
Supported: replaces, outbound 
Accept: application/sdp 
Accept: text/plain 
Accept: application/vnd.gsma.rcs-ft-http+xml 
Contact: <sip:[email protected];transport=udp>;+sip.instance="<urn:uuid:ba010749-6214-4a35-bfb1-ac9c9181c24d>" 
Expires: 3600 
User-Agent: Linphone/3.9.1 (belle-sip/1.4.2) 

You see in the original "Contact" header the address is 192.168.1.200, the private LAN address. But then, after some packet exchanges needed to complete the SIP registration, Linphone sends FreeSWITCH the right "Contact", and we end up with:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset