Re: Linux NATting does not support NAT hole punching?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 23 Jul 2018, Dima Kogan wrote:
On 19/07/2018 20:27, Adel Belhouanez wrote:
 What is very important: the router/NAT system should *drop* unknown
 outside incoming packets (thus not generate TCP RST or ICMP
 unreachable errors). If it doesn't drop packets before conntrack
 allow reverse-SNATing them because of the internal outgoing flow,
 then the internal system will give up early and attemps will fail.

I've been experimenting with traversing Linux NAT as well, so wanted
to chime in on this.

I can confirm that setting the NAT system to DROP unsolicited
incoming packets is crucial for the NAT traversal to work. I
suspect that the reason is a bit different from what is suggested
above. (For simplicity I'll focus on the UDP case, which I think
is what WebRTC uses.)

IIUC when an unsolicited incoming datagram arrives at port P of the
NAT box, in the absence of a DROP rule the NAT assumes that the packet
is targeted to a local process on the NAT system itself (rather than
to some host on the internal network). It thus allocates the local
port P to a session between the sender and the local host (the NAT
system itself). From what I've seen in some netfilter documentation,
this is sometimes referred to as a "null binding".  Subsequently, when
a host on the internal network sends a datagram from the same internal
port number P, the NAT maps it to a different external port number P',
since port P is already allocated by this "null binding" to the local
host. When this datagram reaches the other party, it will most often
fail to traverse the NAT on the remote side, since it is now coming
from an unexpected port number.

I think this is reasonable behaviour, but it is somewhat unfortunate
that the default NAT configuration (just adding a MASQUERADE rule but
not the DROP rule) does not work with the standardized ICE hole
punching technique (https://tools.ietf.org/html/rfc5245), which is
what WebRTC uses. 

Hey Dima,

Thank you for this explanation. It makes sense.
I do not know Netfilter that much. Could you give an example of a working NAT configuration, ie. with the Masquerade (this one I think I understand), and with the Drop (I'm not too sure where to put this one)?
FWIW, I am using nftables, but an iptables example would be fine too :-)

Cheers

There is a (hackish) workaround on the hole
punching end, which is to have each party send the first hole punching
datagram with a short TTL, which would punch the hole in its local
NAT, but not reach the other side's NAT, and would thus prevent this
"null binding" from being created. But this of course could also be
brittle (e.g., double NAT etc.).

[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux