I spent rather a lot of time digging through both Google and packet dumps, and in the efforts of possibly helping somebody out who's trying to figure out the same stuff, I'll put this page out here for Google to find.
This page currently discusses (at least briefly) the following:
SIP doesn't work very well behind NAT for two reasons. First, because the IP address of your hardphone or softphone is actually embedded inside the NAT packets. Secondly, because SIP generally just opens up any ol' random port it feels like when it needs to listen for a new connection, and this means that you'd have to punch rather wide holes in your firewall to get it to work properly. Theoretically some connection tracking would be able to do the job here, but currently there's not ip_conntrack_sip for iptables, nor is there likely to be for awhile, anyway.
All is not lost though, because the two concerns are fairly easily dealt with. All that's needed for the first part is some software which *is* capable of putting something other than the internal NAT IP into the SIP packets, and all that's needed for the second problem is software which has configurable ports, so you've got a tightly-defined range of ports which have to be forwarded.
It's also worth noting that all of the ports you'll have to open up on your firewall will be UDP, not TCP, at least for all the software that I've tried.
The simplest way to use a publicly-available SIP address from behind a NAT is to simply use a phone which both understands NAT and is able to restrict its port range. So far I've found one softphone which does this, called Twinkle. There's a config option to specify the IP address to send along with the SIP packets:
Twinkle then has other options for which five ports it listens on, and those are the only five you need to plug through your firewall. There's one port (5060 historically) for SIP itself, and then two for each "line" that Twinkle supports. If you only care about one line, you can probably get away with just poking three holes.
Twinkle's the only one I'm aware of which works this easily, but I've only tried a couple of softphones, so hopefully there are more out there. I'll update this when I find some more.
If your phone doesn't actually understand NAT itself, it's still possible to use it inside a NAT. I had done some research online and it had looked like PartySIP was the best way to go about doing this kind of proxying, but after some discussion on the email@example.com list, the maintainer mentioned that PartySIP really wasn't the best software for what I wanted to do. Here's the relevant thread.
Instead, I ended up trying Siproxd, which did the trick quite nicely. There's some pretty good documentation available at its homepage, which was available for a time as siproxd.pdf somewhere. I've seen some dead links to siproxd.pdf scattered about, but the only "live" version was Google's "view as HTML," which I've saved here: siproxd-pdf.html. It's worth noting that the PDF was just a version of the official docs, which are available here at siproxd.sf.net.)
Once siproxd has been set up, you've got to poke a few holes in your firewall to go to the box running siproxd. By default the main SIP port is 5060, so you've got to do that. The other range of IPs to use for the actual data transfer is defineable by the attributes rtp_port_low and rtp_port_high in siproxd.conf. By default these are 7070 and 7079, so you've got to send those ten ports through to the siproxd box.
For configuration, it's important to note that siproxd does not have to be running on the same host as the firewall/NAT box. The information about NAT in the FAQ Section on the website appears to be outdated with respect to this. On my system, the relevant bits in the siproxd.conf file are:
if_inbound = eth0 if_outbound = eth0 host_outbound = (external IP) rtp_proxy_enable = 1
The simplest way to use siproxd with your phone is to make sure that your phone supports the use of an "Outbound Proxy" setting. So far I've only tried one phone which does this, kphone, but I'm sure that there are many others which support doing so. Basically you just configure the phone as if it were sitting on a public IP address but specify your siproxd host as the Outbound Proxy. From that point on, everything Just Works.
If the phone you want to use doesn't have an Outbound Proxy setting, though, you've got to jump through a couple more hoops to get it to work properly. Essentially you've just got to use iptables or some other similar method to capture outgoing SIP packets from the phone and redirect them into siproxd instead. If you've got siproxd running on your firewall box, this can be accomplished in iptables with the following:
iptables -t nat -A PREROUTING -m udp -p udp -i eth0 --dport 5060 -j REDIRECTYou'll want to make sure you specify the correct interface, of course. If siproxd is running on a host other than the firewall box, you could probably send the packets over like so:
iptables -t nat -A PREROUTING -m udp -p udp -i eth0 -s (phone) --dport 5060 -j DNAT --to (siproxd)...replacing (phone) and (siproxy) with the appropriate IP addresses. I haven't actually tried that out, so your mileage may vary there.
I've actually got temporary posession of a Pannaway Personal Branch Gateway (PBG) which I've been trying to get working behind my NAT, and since the phone doesn't understand either NAT or Outgoing Proxies, I've been using methods such as these to get the unit to talk to the outside world. I've actually had some success with setting the gateway on the unit to my box running siproxd and having siproxd pick up the SIP packets that way (that requires having the REDIRECT iptables on the siproxd box, but it also negates having to do the DNAT rule on the firewall itself, which I'd like to avoid). I've gotten outgoing calls working properly, and I can receive incoming calls, but right now for whatever reason I don't actually get any sound during the call itself. I'm still working on that, and when I figure it out I'll update this page.
Last updated Thursday, June 30th, 2005