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.

Reply via email to