Friday, January 16, 2015

VPN from a misconfigured cafe using NAT and Linux network namespaces (netns)

Recently I found myself at a cafe that had a wifi connection that was using the whole 10.0.0.0/8 subnet, meaning all addresses from 10.0.0.1-10.255.255.254. This was set up by a professional networking company. In my opinion, someone needs to re-do their CCNA.

So what this means is that if your corporate network is, say, on 10.34.0.0, you will be unable to route traffic easily over the VPN.

I am told there are 2 ways of getting around this

  1. Use network namespaces and NAT'ing to run your chosen applications in their own namespace that is NAT'ed through your real connection
  2. Use iptables prerouting if you know which subnets you are trying to get to on the other side of the VPN.
  3. Convince your coffee shop to use a sane network architecture
I chose #1 for now, and this guide goes over that.

Let's Get Started

Add the network namespace and confirm that it was created:

# ip netns add vpn_nat
# ip netns list

Add virtual ethernet interfaces (peers)
# ip link add name veth0 type veth peer name veth1

Move one of those peers into the vpn_nat namespace
# ip link set veth1 netns vpn_nat

In the namespace context, set up the network
# ip netns exec vpn_nat ifconfig lo up
# ip netns exec vpn_nat ifconfig veth1 192.168.148.2/24 up
# ip netns exec vpn_nat route add default gw 192.168.148.1

The eagle-eyed reader will notice that I am pointing to a gateway that doesn't exist! We fix that like so:
# ifconfig veth0 192.168.148.1/24 up

Test that the vpn_nat namespace can reach veth0

Execute ping in the namespace context vpn_nat:
# ip netns exec vpn_nat ping 192.168.148.1
PING 192.168.148.1 (192.168.148.1) 56(84) bytes of data.
64 bytes from 192.168.148.1: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 192.168.148.1: icmp_seq=2 ttl=64 time=0.041 ms

The next step is to connect the veth0 to your physical network either using NAT or bridging. This requires the masquerading kernel module, but I believe it gets loaded automatically.
# sysctl net.ipv4.ip_forward=1
# iptables -t nat -A POSTROUTING -s 192.168.148/24 -d 0.0.0.0/0 -j MASQUERADE

Verify the routing tables

# iptables -t nat -L -n

Ping a google address in the namespace context

#  ip netns exec vpn_nat ping www.google.com

Verify the routing table in the netns

# ip netns exec vpn_natroute

Run your application in the namespace

I am running as an unprivileged user
$  ip netns exec vpn_nat firefox

Undoing

# iptables -t nat -D POSTROUTING 1

References

http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/
http://how-to.wikia.com/wiki/How_to_set_up_a_NAT_router_on_a_Linux-based_computer
http://www.opencloudblog.com/?p=66

No comments:

Post a Comment