UDP, TCP, and NAT (was...)

Ben Scott dragonhawk at gmail.com
Fri Jul 13 18:55:28 EDT 2007


On 7/13/07, Thomas Charron <twaffle at gmail.com> wrote:
>   I know that's the case, however, PAT can often cause UDP based
> protocols to break, as opposed to TCP protocols, where doing PAT is
> much easier.

  The thing you seem to be missing is that it's not so much a UDP vs
TCP distinction, but an application protocol thing.

  It is true that UDP is inherently connectionless and one-way, while
TCP is inherently connection-oriented and two-way.  At the same time,
almost any application protocol is bi-directional by nature (how often
do you really only want to talk one way?).  So there's pretty much
always going to be a two-way conversion.

  Now, if you're a programmer or protocol designer, are you going to
go to the trouble of rolling your own mechanism for negotiating the
port numbers for the return traffic (or using portmapper or some other
thing), and making multiple sockets, or are you just going to use the
port number and socket which are already there?

  Most use the later approach, and thus we end up with many
application protocols (TCP and UDP) which work just fine over a simple
address/port translation which assumes incoming and outgoing are
symetrical.

  There are exceptions in all cases.  Most of them arise not because
of the use of UDP, but because the application protocol expects to
send additional packets to *different* port numbers on the way back
in.

  The classic example is FTP.  The server listens on TCP/21.  The
client picks an ephemeral port and connects to that.  This is the
"command channel".  When data transfer needs to happen, the client
listens on an ephemeral port, and tells the server about this port in
the command it sends.  The *server* then initiates a connection to the
*client*.  This is called the "data channel".  With a dumb NAT
implementation, the server's connection will bounce off the NAT
boundary, and fail.  The solution is a NAT implementation which
monitors the FTP command traffic, and dynamically adds the ephemeral
ports.

  (This is all in "active mode" FTP.  In passive mode, the roles are
reversed, but you still have the same problem and solution if the
server is behind a NAT boundary.)

  BitTorrent works similarly.  Swarm members register the pieces they
have with the tracker by making an outgoing TCP connection.  Swarm
members *also* make TCP connections to peers which have pieces they
need.  With a dumb NAT, those will fail.  (There is a mechanism to
have peers request reverse connections through the tracker, but it can
get overloaded, and it's worthless if both peers are behind dumb NAT.)

  I understand VoIP works similarly, but happens to use UDP rather than TCP.

  Linux's NetFilter state module calls packets which are part of the
same TCP connection or UDP session "ESTABLISHED", and packets for
things like the FTP data channel "RELATED".  That's why the firewall
rules need to allow both ESTABLISHED and RELATED for FTP to work.  You
also need to load a "conntrack" (connection tracking) module specific
to each application protocol.  There's one for FTP, for example.

> But your right, I suppose I presented it as 'This sux0rs!' as opposed to
> 'It will rarely, however, not work depending on the protocol'.

  Sure.  But the same can be said for TCP applications.  See above.

> You are correct, Linux NetFilter *does* operate in the case of DNS
> as you say.  But others do not, and will actually maintain state
> information based on the serial number of the DNS request contained
> inside the UDP packet.

  That sounds more like a firewall thing than a NAT thing, although I
readily admit the line between the two is rather blurry in many cases.
 In any event, though, the point was that you don't *need* to do that
kind of thing for UDP to work through a NAT boundary -- but you may
well need it for specific application protocols, on either TCP or UDP.

-- Ben


More information about the gnhlug-discuss mailing list