0

To all the iptables gurus out there: I'm doing a little research on the viability of doing UDP hole punching to achieve NAT traversal in my network - I'm trying to figure out which UDP ports EXACTLY can be used for P2P connections between two peers behind a NAT (imagine two gamers trying to play online game that uses P2P networking model). I have observed that my ISP allows NAT traversal on certain ranges of ports (e.g. probably 9000-29999)

To find out these favorable ports is quite doable - all one needs to do is expose a central UDP server on a publicly accessible IP address (A) and port (P) to which you connect from your computer. The central server will then send you back (or you read it from its logs, whatever) the IP address and port from which you have connected - to achieve P2P connection, you want this discovered port to be used by your ISP's NAT also for your next connection to some other peer (I'm not going into details here, it's just the general idea).

So to test if the port stays the same, you connect to another port on the host and if the returned address and port is the same, there is some chance that the p2p connection is possible (I should try also different host - alright - but I'm doing this on a budget, so same host, different port it is).

Now I know that what I have just described is in essence the idea behind STUN servers, please don't recommend to look into it in the answers, I'm not interested in STUN servers in this question.

To find another favorable port, you just connect to another port on the server and see if the returned port is still the same. To find ALL OF THE PORTS you simply scan the whole damn spectrum of ports and find out which ports work (on which ports your public ports stays the same) and which do not work.

So for example if I started the server on port 3478 and 3479 (default STUN ports) and port 5000, I have observed that my public ports stays the same for ports 3478 and 3479 but is totally different for the port 5000. Why ? I don't know.

To test more of these ports I need to start the server on multiple ports (or open multitple UDP sockets on more ports, I think it doesn't matter)... So I thought I could do a little workaround and simply start the server side on one port and set up some clever redirecting rule in iptables (e.g. redirect ports 1024~65535 to the port where the UDP server is running):

overview:

------------------                        --------------------------
 Public Internet                         Your normal home computer behind your ISP's NAT
  System A                                System B
  L = local IP address 10.0.0.1 
  A = some public IP address                             
  UDP Server, port P=6000  <------------> UDP Client (running on some constant local port Z)
                                          trying to connect to range of ports [1025 ~ 65535]
------------------                        ----------------------------

iptables rule used to redirect connections to ports 1024~65535 to port 6000:

-A PREROUTING -i ens3 -p udp -m udp --dport 1024:65535 -j REDIRECT --to-ports 6000

After setting up this rule, I was able to use any of the redirected ports to connect to the server, BUT: one aspect of my flow dramatically changed - the source ports reported by the server have now started to change all the time even for ports that I have previously identified as favorable (e.g. 3478, 3479). As if the redirecting not only redirects the UDP packet to the destination port, but also changes its source port.

I understand that this might be a well documented behavior of iptables (netfilter?) and nothing could be done about it.

But maybe there is some other iptables magic that I don't know of yet which would achieve the desired behavior - i.e. not messing with the source port in the UDP packets.

Does anybody know?

Fanick
  • 101
  • 1
    conntrack is doing clash resolution. Its only option is to change the source port since you fix the destination port to a *single* value, and all other values of the 5uple (protocol, src ip, dst ip) stay the same – A.B Sep 26 '20 at 16:06
  • so it would not be able to pair together response from my single port with the original destination port, I see..., thx. – Fanick Sep 26 '20 at 16:16
  • 1
    You can run `conntrack -E -p udp` during your tests to see what's going on. – A.B Sep 26 '20 at 16:19

0 Answers0