Getting SIP (session initiation protocol) traffic through NAT (network address translation) firewalls is a beastly problem, and Siproxd is a good, easy-to-use SIP proxy that conquers the beast. There are many SIP proxies, but these tend to be complex and rather beastly to administer. You can use Siproxd in front of VoIP servers, such as Asterisk, and also standalone IP phones that use outside service providers. Currently it runs on Linux, FreeBSD, OpenBSD, SunOS, and Mac OS X.
Let’s take a quick tour to learn why SIP and NAT are in a chronic state of
conflict.
SIP negotiates a connection between two endpoints. This negotiation determines
what codecs and transport are going to be used. The transport for VoIP calls
is usually RTP (real-time transport protocol). Once the connection is established,
RTP moves the media stream between the two endpoints. SIP then has nothing more
to do until it is time to signal disconnection.
SIP and RTP use different ports, and can even follow different routes. This
is not an insurmountable problem for NAT—it requires a bit of connection-tracking,
plus configuring a restricted port range so you don’t have to shred your firewall
just to pass VoIP traffic.
The real showstopper is that RTP embeds the port numbers, IP addresses, and
codecs within the message body. Iptables firewalls only read packet headers,
and there is a good reason for this—so they can handle encrypted packets.
Encrypted packets do not have encrypted headers (obviously, or they would not
be routable).
An additional problem is that what we call NAT (Network Address
Translation) is most often port masquerading, or Port Address Translation (PAT).
This diagram shows a LAN of three PCs using private non-routable IP addresses,
and a firewall using PAT to share a single public routable IP address:
---------------- | 192.168.1.10 | ---------------- ---------------- -------- ---------------- | 192.168.1.11 |----|switch|---|NAT firewall |---Internet ---------------- /-------- |208.201.239.37| / ---------------- ---------------- / | 192.168.1.12 |/ ----------------
Suppose host 192.168.1.11 wants to visit Enterprise
VoIP Planet. When source packets from 192.168.1.11 hit the NAT firewall, they
are re-written as 208.201.239.37. When Enterprise
VoIP Planet responds to the connection request, it speaks to 208.201.239.37.
Then NAT rewrites the destination addresses to the original sender, 192.168.1.11.
Just to compound the fun, all connections must be initiated from behind the
firewall to build the NAT tables. SIP requires that both endpoints be capable
of initiating connections, which is usually not something we allow LAN PCs to
do. This is where one-way VoIP calls come from—one endpoint can send and
receive, but the other endpoint can only send.
NAT really needs to go away for good, or at least become an option rather
than a requirement. It is a useful hack that has extended the lifespan of IPv4,
but its many disadvantages outweigh its benefits. It’s a chokepoint that forces
every packet entering or leaving your network to be altered. It forces all services
to become NAT-aware and adopt nasty hacks and kludges. However, as we shall
be dealing with it for the foreseeable future, here is how to set up Siproxd.
Configuring Siproxd
The first and most important rule is do not mix Siproxd with any other NAT-traversal tools. Don’t use the iptables SIP connection tracker, don’t use a STUN server, don’t use another local proxy. Keep it simple.
Next, download and install Siproxd on the same box as your NAT firewall. Debian and Ubuntu include it, so a simple aptitude install siproxd takes care of it. For other Linux distributions you’ll probably have to build it from source code. Just follow the good instructions, and don’t forget to compare the MD5sum, which is in the release notes.
After installation you’ll be editing siproxd.conf. First define your LAN and WAN interfaces. if_inbound is the LAN interface, and if_outbound is the WAN interface:
if_inbound = eth0 if_outbound = eth1
And that’s all you need to change.
If you have a firewall policy that denies incoming connections, you’ll need a couple of rules in your iptables script to allow incoming SIP and RTP traffic:
iptables -A INPUT -m udp -p udp -i eth1 --dport 5060 -j ACCEPT iptables -A INPUT -m udp -p udp -i eth1 --dport 7070:7089 -j ACCEPT
The defaults in siproxd.conf limit RTP to the 7070:7089 port range. You can easily adjust this to suit. Now you have a working configuration and can start Siproxd:
$ siproxd
Finally, configure your IP phone to use the proxy. If you’re not running your own server, but have a Free World Dialup or Sipgate account or something similar, all you do is enter the LAN address of your Siproxd server as your SIP proxy in your phone’s configuration. And that’s all there is to it.
Siproxd stores all registrations in /tmp/siproxd_registrations. When you want to make changes and start clean, delete this file and then restart Siproxd.
Running an Asterisk server behind Siproxd is a bit more complex. The Siproxd configuration doesn’t change, but you do have to make some changes to /etc/asterisk/sip.conf. Siproxd comes with some good example configuration files, including one for Asterisk. Be sure to also consult the FAQ, README, and other good documentation.