n2n: connect your networks using P2P VPN

Sometimes, you need to connect two networks in some way. My usual motivation is ability to access machines behind multiple NATs for easy system administration. So far, I used combination of OpenVPN and DynamicForward in ssh with clever use of ProxyCommand and nc with a sprinkle of proxy.pac for Firefox to make everything seemingly work. However, I never successfully managed to tunnel various JavaWebStart based remote consoles which want to connect directly from your machine to remote IP using sockets (for which you have to disable all proxy settings using jcontrol and selecting direct connection).

So this got me thinking. I could configure another OpenVPN for this, but it has many steps and I was lazy. Wouldn't it be great if there is some kind of P2P network like Skype or Hamachi for Linux? Something like this:

n2n_network.png

n2n: a Layer Two Peer-to-Peer VPN is exactly what I was looking for. It allows you to construct IP network over nodes behind NAT. But is it really easier to configure for specific example of accessing private network on another LAN behind NAT? Let's find out.

Steps are simple:

  • Install n2n (you will have to do this on supernode and two nodes)
    all$ sudo apt-get install n2n
    
  • Start super node on public address with DNS name super.example.com
    internet$ supernode -l 1234
    
  • Start first client
    local# edge -c community -d community  -k secret \
      -l super.example.com:1234 -a 10.1.2.1
    
  • Start remote end-point somewhere within LAN
    remote# edge -c community -d community  -k secret \
      -l super.example.com:1234 -a 10.1.2.2 -r
    
    Note changed IP address and -r flag which will allow us to route over this node.
    remote# sysctl -w net.ipv4.ip_forward=1
    remote# iptables -t nat -A POSTROUTING -s 10.1.2.1 -o tun0 -j MASQUERADE
    
    This will turn forwarding and NAT for our packets coming from community tap interface and going out through tun0 to LAN. We also need to setup route on local side for remote LAN network:
    local# ip route add 172.18.0.0/16 via 10.1.2.2
    
And we are done. In just 6 commands we routed remote LAN 172.18.0.0/16 over our 10.1.2.0/24 n2n interface to our local machine. And you don't have to stop at that. By installing additional edge in some other local network, you can get instant connectivity to your internal administrative network. This is very useful if you want to access your private repositories on local machine or need to open arbitrary sockets between machines.