(warning, a bit long and might not be of very general interest,
but some of the points probably need getting down somewhere...)

executive summary: passing some protocols through NAT can be pretty hairy.

On 2006/06/13 16:47, Daniel Ouellet wrote:
> Stuart Henderson wrote:
> >On 2006/06/13 14:58, Daniel Ouellet wrote:
> >>That's cool! No worry, I guess your subject is way more interesting to many,
> >>or no one is using NAT traversal or have any needs for it.
> >I don't know much about H.323, but for SIP draft-biggs-sip-nat has some
> >useful information, care needs to be taken not to break other nat-
> >traversal mechanisms though (google: SIP ALG break), and there are a
> >lot of strange UAs around...
> >Another way for SIP is ser/openser and mediaproxy, but it definitely
> >needs work to configure, it's nothing like how ftp-proxy/tftp-proxy
> >work (which seems to be more the sort of thing you're looking for).
> 
> Actually I wasn't looking for ftp-proxy type, but really for SIP NAT
> traversal. Sorry if I didn't make that clear.
>
> Not going into any details, but in short, and very simplistically as well,
> connection are establish out to a phone behind NAT for example coming from
> 5060 to port 5060 on the CPE device as SIP defines it and the reply will
> be send back to port 5061 oppose to what would be expected to come back
> to 5060.

I'm trying to understand what you mean, but I don't understand about
port+1, I haven't seen anything with SIP that explicitly uses port+1.

Normally without NAT, packet from phone (UAC) to voip gw (UAS) looks like
81.168.a.b.2051 > 193.111.x.y.5060:  udp
- and a reply:
193.111.x.y.5060 > 81.168.a.b.2051:  udp

Where the phone has a private address, e.g.
10.0.0.1.2051 > 193.111.x.y.5060:  udp
- NAT rewrites,
81.168.c.d.55017 > 193.111.x.y.5060:  udp
- Reply from voip gw to NAT
193.111.x.y.5060 > 81.168.c.d254.55017:  udp
- NAT rewrites to phone
193.111.x.y.5060 > 10.0.0.1.2051:  udp

this is all ok, and as long as the UAC (phone) sends some packet
(maybe empty 'OPTIONS' packet) as a keep-alive before the NAT mapping
times-out, all is well for the actual SIP packets.

the problem requiring assistance to bypass the nat comes when you
setup the media stream because the SDP payload in the SIP INVITE includes
the private address for the returning media stream to be sent to:

Sent to udp:193.111.x.y:5060 at 13/6/2006 22:10:44:870 (1240 bytes):

INVITE sip:[EMAIL PROTECTED];user=phone SIP/2.0
Via: SIP/2.0/UDP 10.0.0.1:2051;branch=z9hG4bK-by2gzy7jgtul;rport
From: "Stuart Henderson" <sip:[EMAIL PROTECTED]>;tag=ru8z7tg2c1
To: <sip:[EMAIL PROTECTED];user=phone>
Call-ID: [EMAIL PROTECTED]
CSeq: 1 INVITE
Max-Forwards: 70
Contact: <sip:[EMAIL PROTECTED]:2051;line=aurpydus>;flow-id=1
P-Key-Flags: resolution="31x13", keys="4"
User-Agent: snom360/6.1
Accept: application/sdp
Allow: INVITE, ACK, CANCEL, BYE, REFER, OPTIONS, NOTIFY, SUBSCRIBE, PRACK, 
MESSAGE, INFO
Allow-Events: talk, hold, refer
Supported: timer, 100rel, replaces, callerid
Session-Expires: 3600;refresher=uas
Min-SE: 90
Content-Type: application/sdp
Content-Length: 477

v=0
o=root 1540178600 1540178600 IN IP4 10.0.0.1
s=call
c=IN IP4 10.0.0.1
t=0 0
m=audio 64376 RTP/AVP 0 8 9 2 3 18 4 101
a=crypto:1 AES_CM_128_HMAC_SHA1_32 
inline:TFrG383hHaidd8meTiYYe7tiO3Up+EICEEmeE/7H
a=rtpmap:0 pcmu/8000
a=rtpmap:8 pcma/8000
a=rtpmap:9 g722/8000
a=rtpmap:2 g726-32/8000
a=rtpmap:3 gsm/8000
a=rtpmap:18 g729/8000
a=rtpmap:4 g723/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=encryption:optional
a=sendrecv

Of course this is quite like active-ftp, in that local IP addresses
and ports for some remote machine to connect to are carried in the
packets themselves (not the headers).

- to get this particular packet sent so that media is directed
correctly, the NAT would have to rewrite:

Contact: <sip:[EMAIL PROTECTED]:2051;line=aurpydus>;flow-id=1
o=root 1540178600 1540178600 IN IP4 10.0.0.1
c=IN IP4 10.0.0.1
m=audio 64376 RTP/AVP 0 8 9 2 3 18 4 101

10.0.0.1 would be replaced with the NAT routers address; say 81.168.66.254
64376 would be replaced with an unused port number on the NAT router; say
for this example 50172

Packet is then sent on to the UAS; a rdr would be added on the NAT
so all incoming packets (i.e. the media stream) to 50172 get directed
to 10.0.0.1:64376

This is all rather like /usr/sbin/ftp-proxy (working with anchors so
that the data connections are handled in-kernel by PF, not like the
old /usr/libexec/ftp-proxy). Though, with FTP, you can tell when the
control connection is disconnected, but this isn't possible with SIP
so you have no sure way to know when the RDR can be removed (so at
least you need to watch the packet counter for the rdr rule and kill
the connection some time after it stops increasing).

N.B. the media-packets can come from anywhere; very often not
the same host as you're passing SIP messages to. They can even
change source mid-call. While ftp allows third-party transfers,
it's little-used, and disabling it for security reasons isn't
a big problem.  That's not really possible for SIP...

If you're following this, you'll notice that some host sending
an unauthenticated UDP packet can ask the NAT to open a UDP port
from the outside world to any host behind the same NAT...
So, I think this definitely needs to be handled outside of PF,
and accompanied by a reasonably large warning (-:

Reply via email to