VoIP behind NAT

More and more phone lines are being switched to VoIP, especially where FTTH is being deployed. When using the ISP modem/router it usually performs the ATA (Analog Telephone Adapter) role too, and it is already configured for VoIP – just plug the telephone in one of its PHONE/TEL ports (technically – FXS ports), or connect them to the old phone cables, and everything works – as long as the router is powered, of course.

It could become more complex if one wishes to use their own router but one without VoIP, and using separated ATA or VoIP PBX in the LAN, or even a router with VoIP but connected downstream to the ISP router.

Without additional configurations VoIP may not work correctly. The reason is it uses protocols like SIP that requires externally initiated connections too, and NAT doesn’t allow them by default. Moreover NAT masks the external VoIP endpoint address, and LAN devices know only their LAN addresses.

For example, when a call is incoming, the remote VoIP server needs to contact our VoIP system. The VoIP system would have sent its IP address and ports in its registration message, but by default, without knowledge of its external, public IP address and ports (which are managed by NAT), it can only send its private LAN address and ports. But even if it knew the external IP and ports, after the NAT mappings expires, the external VoIP system has no way to send a message to the local one, as packets will be dropped. These issues usually lead to one-way calls, and systems that cease to work after some time.

So what is needed to make VoIP work behind NAT is:

  • A way to tell which is the external IP and ports to be contacted to, especially when the public IP is dynamic.
  • A way to let the external-initiated traffic to reach the local VoIP system every time is needed.

There are three main ways to achieve that – each one has its pros and cons:

  • Use an Application Layer Gateway (ALG) on the WAN router
  • Open all the required ports (for SIP and RTP/RTPC protocols) on the WAN router
  • Rely on keep-alive packets to keep NAT mappings open on the WAN router, and use STUN or UPnP to learn the outside IP address and port mappings.
Application Layer Gateway – ALG

When it is available and works, this is the simplest solution that requires less work. An Application Layer Gateway is a process running on a router that intercept specific types of traffic and modify them to work behind NAT, and is not limited to VoIP, there are ALGs that can support different types of protocols that aren’t NAT-friendly, for example FTP, VPNs, etc. Sometimes they are called “<protocol> passthrough”, i.e. VoIP passthrough or SIP passthrough.

An ALG will try to modify the traffic packets as they flow through the router, identifying which parts need changes, and replacing local data (i.e. IP and ports) with external ones. It will also configure all the ports forwarding required to forward traffic to the local VoIP system. To perform that without issues, an ALG needs to be able to parse and the change the protocol data properly, on-the-fly. But SIP is a complex protocol, and different systems can use slightly different implementation, all valid, but that can confuse some ALGs, which won’t work properly.

Still, because of its simplicity – one needs to know nothing about how VoIP works – just enable it for VoIP on the WAN router, and see if it works. It’s worth a try. If it doesn’t work properly, it’s better to switch to a different setup.

Open and forward VoIP required ports

This the usual port forwarding setup, with just a little difference to take care of – the SIP protocol passes inside the message body the IP and ports it is going to use. This setup works well when the router has a static public IP address, and that address can be set in the local VoIP system to be used directly in SIP messages instead of the LAN one.

VoIP uses several ports to work. There is the SIP protocol port – usually 5060 (but can be changed as needed, one port is required for each different VoIP trunk), and several ports for RTP and RTCP traffic (two ports for each active call).

SIP is used for call control (making and receving calls, and managing active calls), and can be used on TCP or UDP, the latter being usually more common. RTP works over UDP and carries the audio packets (and could carry also some specific call events as well, i.e. DTMF tones). while RTCP (RTP Control Protocol) carries statistical and control data for the RTP stream, used to manage the call quality. RTP always uses even-numbered ports, while RTCP will automatically use the next odd-numbered ports. We need to remember this when opening ports for VoIP. Different systems may use different default settings for their RTP ports. Check the system documentation, to know which ports needs to be configured.

Because ports are written inside SIP messages, the ports set on the local VoIP system needs to be the same set in the port forwarding configuration. For example, if the local system is set to listen to SIP messages on 5061 (and not the more common 5060), a forwarding rule like <WAN IP>:5060 → <LAN IP>:5061 might not work, because the SIP messages will tell to be contacted on 5061. This is required for RTP/RTPC ports as well. Actually, the rport parameter in the VIA field of SIP messages could be used to tell the actual external ports – but that field needs to be present and configured correctly, for example by the external SIP proxy receiving the message (which sees the port the packets come from). Still, using the same port may be useful to avoid issues due to missing “rport” support.

The WAN public IP needs to be known as well. If static, it is usually possible to set up the local VoIP system to use it in its messages (see its documentation). If it is dynamic, it is possibile to use specific functions to discover it – see the next section. The VIA field again can contain this information – if the received parameter is set correctly by the SIP proxy receiving the packets.

This method has a little security issue – when the VoIP system is open to the whole internet, it will be quickly discovered, and attempts to exploit it will begin soon. If you know the remote IPs it needs to use, setup firewall rules to accept traffic from them only. Some VoIP systems have a configuration that allows to accept traffic only from the remote VoIP system IP they registered with. Enable it to drop any other unwanted traffic.

NAT keep-alive, with STUN or UPnP.

Especially useful with dynamic IP addresses, we can let the local VoIP system open required connections through NAT, and keep them open sending keep-alive messages at regular intervals to refresh the router NAT mappings table. Just, we need a way to know which external IP:ports are mapped by NAT to internal IP:ports – STUN or UPnP may come to the rescue.

STUN (Session Traversal Utilities for NAT) is a protocol that allows a system behind NAT to discover which IP:ports are being used on the WAN facing side, by using an external server. There are several STUN servers available on the Internet, and they are usually free to use. Which STUN server to use has to be set in the VoIP system configuration. STUN has a limitation – it can’t work with symmetric NAT, because it means NAT will use a different mapping for each destination IP, so what is discovered through STUN won’t be valid with the remote VoIP server IP. Asus router are known for example to use symmetric NAT by default, because it is more secure. To use STUN it has to be changed to “full cone” NAT.

UPnP may offer the same features interrogating the router directly, but its support is less widespread. UPnP can also be used to open ports directly when needed. Grandstream ATAs have UPnP support, for example. Of course, UPnP needs to be active on the router as well.

Once STUN (or UPnP) has been configured, NAT keep-alive needs to be enabled on the VoIP system, and the interval of keep-alive messages set at a value short enough to refresh the router NAT mappings before they expire, but not so short that the ISP VoIP system thinks they are some kind of DoS attack and closes the connection forcibly.

Full-cone NAT has the same drawbacks of explicitly open ports – any outside system can try to initiate a connection. The only little advantage is the external ports are not usually the standard ones, so it is necessary a service discovery to understand there’s a VoIP system listening there, but that is very little protection. As said in the previous section, it is necessary to configure the firewall and/or the VoIP system to accept traffic only from the ISP VoIP servers.

How to setup keep-alive depends on the local VoIP system – some have some simple settings to enable it – set the STUN server and enable keep-alive -, other may require some more complex setup – i.e. to manage the SIP message “VIA” parameters – but there are too many different systems to list their settings here. See your VoIP system documentation.

Note: if the VoIP system is also behind a Carrier-Grade NAT (CG-NAT), a STUN server will discover the CG-NAT mappings, not the local router ones, and thereby this system won’t work.

IPv6 note: of course IPv6 would make everything much simpler – none of this would be needed – since the local VoIP system would have a routable public IP to be contacted to. Security considerations still stand – it has to be protected from unwanted traffic at the firewall/VoIP system level.