NGI Assure project: Probabilistic NAT Traversal

This project was funded through the NGI Assure Fund, a fund established by NLnet.

Project motivation


The Problem


For establishing a peer to peer (p2p) network among regular internet users, unhindered connectivity is anything but self-evident. Today consumer devices are often not directly reachable via the internet but quite often are behind a so called NAT delivering only indirect internet connectivity.


NAT Traversal Methods


There are several methods to reach peers who are behind a NAT, but there are as many reasons those existing methods might fail. Manual configuration for example, as it is possible for example with home routers, often does not work for mobile devices like mobile phones. A further category of methods is subsumed under the term NAT hole punching. This exploits a behavior of the gateway that keeps the port of an outgoing packet open for a potential response. To make this port known to another peer a third peer is needed who is not behind a NAT. Using this method for a privacy preserving network like GNUnet, this could facilitate eclipse attacks (isolating a peer) which then can be used for deanonymization attacks and cencorship. Also any additional infrastructure needed to provide some kind of functionality has to be maintained by someone, becoming a target and/or point of failure. Therefore this method is not suitable. More sophisticated methods like "Autonomous NAT Traversal (pwnat)" using ICMP fake message, which do not need a third party for the initiation of the connection, are not successful in all circumstances, because this method depend on the behavior of the NAT firewall. All methods have in common that the external IP address of the peer behind the NAT must be known.


Alternative Solution


Two peers trying to connect to each other will send out a burst of connection attempts to the other peer on different ports. The sheer vast amount of connections attempts from both side will lead to a high probability that two connection attempts from both peers onto the same port will be at the same time leading to a successful connection between those peers. If two natted peers are using the method to start a burst of connection attempts, this method still needs the global IP of the other peer and a “start signal” to coordinate. In the NGI Assure project L2O we are establishing a backchannel with neighbourhood routing over an ad-hoc distance vector protocol to solve the problem of not directly connected peers. The peers serving as hops to a distant peer which are a direct neighbour of the start or end peer on that path do know the global IP address of the start or end peer. If those two peers like to use the burst method for hole punching the global IP address is known. Via the distance vector protocol we are also able to communicate the "start signal".


Usage


We we have encapsulated the functionality in a library. The library can be used under the following requirements:

  • The caller of the API has to know the external IP address of the other peer.
  • The peers trying to communicate with each other need an indirect way to exchange messages in order to synchronize with each other.
These two requirements are not covered by the library. For more details have a look here.


Milestones


The next milestone to be reached is milestone 1.


Milestone 1 Test Infrastructure


Extending the testing framework, which was already designed and implemented for the L2O project. Details

  • Enhance the testing framework with a new kind of component (NAT component).
  • Implement logic to keep ports open used during network translation.
  • Extend the test framework configuration to configure the new components.

Deliverable


Test case which tests the new testing functionality. Adding documentation.


Milestone 2 Synchronization


This task is to implement the protocol that is doing the signaling for synchronizing two peers which do like to connect to each other. Details

  • Two peers which got connected via DV signaling each other being behind a NAT.
  • Learning the external IP address+port from already connected peers, exchange with the peers that want to connect.
  • Set a common start time. One peer is selected to be leading (comparing peer ids like it is done in CADET)


Deliverable


Deliverable of this milestone is integrating the protocol implementation into the GNUnet stack, a test case which tests that two peers successfully exchange the messages of the implemented protocol until the condition is reached that both nodes are ready for the burst mode. Additionally there will be a protocol documentation.


Milestone 3 Burst Protocol


Burst to establish connectivity (IP_RAW, SYN send for TCP; normal for UDP). A burst of synchronized (same ports on each peer) connection attempts on all available ports will lead to a high probability for a successful connection.The connection in the TCP case is not final, because the TCP connection is only done in the user space.


Deliverable

The protocol implementation will be integrated into the GNUnet stack, one Test case will test two peers are finaly connected (UDP case), another test case for TCP tests if both peers end up at the same port and the protocol will be documented.


Milestone 4 TCP Repair


For the TCP case the connection was established sending packages from user space using raw sockets. To let the kernel know about the TCP connection we will use the “repair mode” of the setsockopt() system call.


Deliverable


Integration into the GNUnet stack and a test case testing two peers are finaly (kernel TCP socket) connected.


Milestone 5 Privilege Minimization


Privilege minimization, using SUID/SGID helpers with required capabilities. We need privileged access to system resources for some parts of the protocol, e.g. the TCP repair mode. This task will implement helper executables which are doing this privileged access, to be used by other components not having special privileges. (see § 2.2.1 Access Control, The GNUnet System, https://grothoff.org/christian/habil.pdf)


Deliverable


Helper executables and cli applications using the helpers. Integration into the GNUnet stack. Man pages for the cli applications. First release of all the implementation.


Milestone 6 Android Test Infrastructure


In this milestone the test framework will be enhanced to run a headless android studio emulator on a namespace node. With this emulator an android device running on that node shall be emulated. Two devices running on different nodes should reach each other via the test framework network. For doing the network connection an app should run on each device. This app should do the networking with a small c library. With this c library we like to test if networking and file access is possible with a c library running using the NDK of Android.


Deliverable


The deliverable of this milestone is twofold: the scripts for automation and the automated tests themselves, and a report on the outcome of these tests. If the test case starting an Android app on two nodes doing network communication between those two apps and each app accessing its own filesystem will not work as expected, the task includes an overview of potential approaches for achieving the desired outcomes in other ways.


Milestone 7 GNUnet event loop on Android


The c library should also start the GNUnet event loop. Therefore the library will be enhanced by a minimal part of the GNUnet stack to start the event loop. The testing code will be enhanced to use the event loop.


Deliverable


The deliverable of this milestone is twofold: the scripts for automation and the automated tests themselves, and a report on the outcome of these tests. If the test case testing the same functionality as in milestone 6, but using the GNUnet event loop, will not work as expected, the task includes an overview of potential approaches for achieving the desired outcomes in other ways.


Milestone 8 Enhance GNUnet stack on Android


The working test cases of milestone 6 and 7 are prerequisites to tackle this milestone! The library will be enhanced to incorporate the parts of the GNUnet stack necessary to run the test case implemented in the milestones 1 -4.


Deliverable


Test case testing the same functionality as in milestone 1 - 4 running on Android.