On Fri, Jan 12, 2007 at 05:48:57PM -0800, David Newman wrote: > > I use VOIP behind NAT (Sipura and Grandstream phones talking to an > > off-site Asterisk server) without any problems. I was using an OBSD PF > > firewall. It's booted into Linux right now due to driver problems with > > my ADSL NIC, but it the VOIP part worked fine under either OS/firewall. > > > > What, specifically is your issue? > > > > One huge issue has to do with pf and SIP protocol design. SIP signaling > messages go over a well-known port (5060/tcp), but the media traffic > (the actual voice packets) go over some random port negotiated during > call setup. > > The pf+voip documents I've seen give config examples that just open up a > large range of ports [0]. Yikes. > > What's really needed is either: > > a. ditch SIP and use IAX instead since at least signaling and media both > run over a well known port (and thus it's much easier to firewall and > NAT); or > > b. create a pf proxy that understands SIP.
(i.e. run siproxd on your firewall). c. Turn on NAT workarounds on your upstream softswitch. Consider the following scenario: private public phone 1 --------- NAT FW 1 ----------. softswitch phone 2 --------- NAT FW 2 ----------' private public Both NAT FW's are just "bog standard" NAT, with a policy of permit all UDP outbound (of course, the source port is usually changed). These firewalls have no SIP awareness. No inbound traffic is permitted, apart from responses to outbound UDP packets. VOIP with SIP+RTP *can* work in this scenario. In order for it to do so: (1) the phones must announce the 'rport' extension in their SIP messages. This is bog standard and pretty much everyone does. What this means is: if the softswitch receives a SIP message from UDP port 12345, then it may send the SIP response to UDP port 12345, not to the port number which is embedded within in the SIP message itself. (2) the softswitch must be configured to ignore the IP address in SIP messages it sees, but to use the source IP address of packets it sees from the phone. For example, in Asterisk, this option is "nat=yes" in sip.conf. This is essentially for source IP addresses what (1) was for source ports. (3) either the phone or the softswitch must send periodic null SIP packets, say every 15 or 20 seconds, to keep the firewall state open. If you want to do this on the phone end, you set it to re-register every 15-20 seconds. If the softswitch supports it, you can make it send a null SIP packet every 15-20 seconds to every currently registered device. The latter case is what sipgate.co.uk implements. (4) the softswitch must act as a media proxy and a dynamic 'rendezvous' for the RTP streams. For example, the body of the SIP invite from phone 1 may say that its media stream will originate packets on 192.168.0.1 port 8004. In fact, the firewall will NAT both the IP address and port to something else (indeterminate). So, the softswitch must wait until it actually sees RTP packets from this host, and enable its media proxy for whatever source port those packets came from. This rendezvous is possible because the softswitch knows what the *destination* IP and UDP port will be for these packets, since it chose this itself in the SIP response, and so listens waiting for the first packet in the stream. I believe Asterisk does this with nat=yes; if using a pure SIP proxy solution, like SER/OpenSER, then a NAT-aware media proxy will do it for you. e.g. http://www.voip-info.org/tiki-index.php?page=Portaone%20rtpproxy http://www.voip-info.org/wiki-MediaProxy An example of a complete implementation of the above suite of workarounds is sipgate.co.uk. You can point phones at it behind NAT firewalls, and It Just Works [TM] Whilst the above workarounds are arguably just workarounds, they do have the advantage that VOIP works with standard firewalls, and you don't have to have any more permissive policies than a reasonable "permit all UDP outbound". siproxd is arguably a cleaner solution, especially as it doesn't rely on keepalives. It does work well, but beware that it's a stateless proxy. This means, in particular, that it does not support multiple registration (i.e. more than one phone registering to the same outside provider using the *same* SIP username). > A SIP proxy would need to do the following: > > - - look into the SIP's SDP sublayer to grok the port number that media > traffic will use on a call > > - - dynamically create a pass rule allowing access on that port number > > - - dynamically tear down access on that port when the call terminates That's basically what siproxd does, although instead of messing with pf rules, it runs a simple RTP proxy in userland. The SIP messages and responses are modified to put in the appropriate IP address. That is, the phone sends its RTP streams to/from the firewall's "inside" IP address, and the softswitch sends its RTP streams to/from the firewall's "outside" IP address. (I believe siproxd used to have the ability to mess with Linux iptables rules, but that functionality was stripped out) Regards, Brian.