Matt-J.co.uk : Ramblings

Life, Tech and intravenous caffeine.

IP Routing, Rules and Redirects!

Hello again my minions!

Randomly started an interesting project last night, while thinking about wanting access to my NAS and network via wifi (but secure) and also better, more reliable remote access to my pc’s even when they are behind a nat or two.

My Current Layout Involves a Custom WRT54G Router performing NAT onto the 200.x subnet, and then connected to my multi-homed linux server/router that routes and firewall’s between the 200.x subnet for internet, my personal 1.x subnet, and the rest of my houses 2.x subnet (martin’s NAS, Sams server etc) (My server also serves apache, samba etc etc but that dosnt matter here)

I decided the way to go was OpenVPN, as I am very comfortable with its configuration, and prefer a fully routed vpn over port by port client less ssl (web based) access solutions.

I Set up a PKI based openvpn system. allowing a client to logon with the correctly signed certificate and private key pair, instead of a username/password combination.

The wifi point is built into my nat router, and so by default, wireless clients get assigned an IP in the ‘internet only’ 200.x range with access to the web via NAT but on the wrong side of the linux firewall to gain access to the network. (It’s still WPA2 -PSK Protected, but I guess thats just my paranoia :P)

After setting up my laptop with a client configuration which tries to establish a tunnel to 192.168.200.2 (linux server from 200.x subnet.. only openvpn allowed through firewall) first, and an internet route able IP if that should be unreachable (I’ll explain that in a mo)

I also configured openvpn to push route information for my subnets to clients at logon, minimizing configuration.

I started the openvpn server and connected my client. Everything worked first time. I am still using 192.168.200.1 as my default gateway, (as i dont want internet traffic having to route in and out of my net again) however trying to connect to my webserver or file shares on any of my pc’s works perfectly, and speedy enough over 54Mbps WIFI.

With all this working, My plan was then to purchase another fixed IP address on my dedicated server (this webserver) and use IPTables to route all traffic to that destination IP to my Linux Firewall/Router down a Static p2pVPN tunnel between the webserver and my linux server.

Then I had a better idea, as forwarding everything (especially UDP) in IPtables was a horrible way to do things as i’d most probably have to use NAT, which seemed to lack elegance somewhat.

I created the p2p Openvpn tunnel as planned, but instead of adding the new internet ip address to my webservers network card (ip addr add blah.blah.blah.blah dev eth0) and then IPtables-ing the traffic down the tunnel. I instead added the ip address to the p2p VPN tunnels tun interface on my (local.. in my room) side, then added a static route to my webserver informing it that the new internet IP address i had purhased was reachable at 10.0.0.2 (the linux server side of the p2p vpn tunnel) and finally enabled IP forwarding on my webserver.

So Far so good! I had an actual internet IP available to me in my room now, behind university’s NAT, properly routed back to the web! I opened a UMTS connection to the internet through my phone + bluetooth + laptop, and tried pinging my new IP, I did not get replies, But loading wireshark on my linux server did show the ping requests were getting to me down the tunnel!

However (And I should have seen this coming.. but I was tired as it was now about 5am) my server replied.. to an internet  IP… and so of course… it routed via the default route.. which was my local NATed internet connection, so no wonder the replies did not get through. I still had a bit to go before getting a full TCP session to occur!

So now I needed a way to change the default route depending on where the traffic was going to / coming from.

A quick refresher on ‘ip rule’ toolset within iproute2 software and I was able to create a separate routing table called table_tunnel. In it I placed the single route ‘ip route add default via 10.0.0.1 tun1′. I then Created a rule that told the system that any IP Data with a source address of  my new internet IP. Should traverse the ‘table_tunnel’ routing table to find out where to go, and so consequently, all data coming in to my new internet IP, also leaves via the tunnel, allowing proper TCP communication, while allowing my normal internet browsing to continue working normally via the standard ‘Main’ and ‘Local’ Routing tables.

Success! I finally got ping replies from my dial-up (UMTS) laptop!

I then just had to script all the changes to make them survive reboots. Daemonise the openvpn processes, and tighten up the firewall on the incoming p2p vpn tunnel to only allow the openvpn UDP port (as thats what i will be doing all my remote access over, so why leave anything else open, when openvpn will give me access into my subnet anyway.)

And so now, When I start openvpn on my laptop. If im not connected to my WIFI (Ie, somewhere around the world on the internet), it cannot connect to 192.168.200.2, and so tries the internet IP.. which ends up at the same openvpn server on my local network, but via a real internet IP and a bit of clever routing!

Downside: Ive been up all night
Upside: I can access all my data wherever I am… and even if i move house in the future, that internet IP will still allow me to access my systems, as theres nothing dependant on the local home internet IP/details ;)

Also… should I want to host other things from home to the public (quickly set up apache/ftp/voice server.. Its as easy as changing one IPTables rule!)

I Have intertubes in my room!!!!

//Matt

4 Comments so far

  1. Curious June 8th, 2008 6:47 pm

    This sounds really cool. I’ve been trying to do the same thing but I haven’t been able to make the rule to route the source address of one of my machines to go through a VPN tunnel instead of the default gateway. Maybe it’s me or I have a problem with the old kernel in my router machine.

    Could you please share the commands you used?

    Thanks in advance.

  2. matt June 9th, 2008 11:40 pm

    Curious,
    I am using IPrules, (see ip rule in the ‘iproute2′ toolkit)
    These allow you to specify new whole routing tables and have traffic use one of these tables based on sourceIP, destIP, or a mark from the prerouting chain of iptables MANGLE.

    So basically I have my normal routing table, and then another routing table called ‘table_tunnel’
    This ‘table_tunnel’ routing table then has all the static routes for my network, but then has a different default gateway than the main table.

    bofh trx # ip rule
    0: from all lookup local
    32763: from 192.168.1.3 lookup table_tunnel
    32764: from 192.168.1.10 lookup table_tunnel
    32765: from 217.160.203.167 lookup table_tunnel
    32766: from all lookup main
    32767: from all lookup default

    ^ As you can see, certain IP’s will use the new routing table, that can be viewed (and added too) using ‘ip route add/list table

    bofh trx # ip route list | grep default
    default via 192.168.200.1 dev eth0wan
    ^Default table

    bofh trx # ip route list table table_tunnel | grep default
    default via 10.0.0.1 dev tun1
    ^table_tunnel table

    I hope this has cleared things up a little bit, feel free to let me know how you get on.
    //Matt

  3. phil October 25th, 2008 10:43 am

    hey mate - im basically trying to do exactly what you have done here but im having problems. the tunnel is up ok, packets route ok across it, but the routed ip space does not appear to work at all.

    ive aliased the IP on my home gateway and the packets go over the vpn as below:

    -bash-3.00# ping 194.150.121.74
    PING 194.150.121.74 (194.150.121.74) 56(84) bytes of data.
    64 bytes from 194.150.121.74: icmp_seq=0 ttl=64 time=143 ms
    64 bytes from 194.150.121.74: icmp_seq=1 ttl=64 time=28.9 ms
    64 bytes from 194.150.121.74: icmp_seq=2 ttl=64 time=27.6 ms

    so that works, at least. tracerouting to the IP from the outside doesnt work.

    not sure if ive got the gateway ip route commands right, ive tried just about everything. im trying to route an entire network (10.3.0.0/23) to use the tunnel. this is my ip route ruleset from the gateway at my home end.

    [root@gw iproute2]# ip rule show
    0: from all lookup 255
    32764: from 194.150.121.74 lookup tunnel
    32765: from 10.3.0.0/23 lookup tunnel
    32766: from all lookup main
    32767: from all lookup default

    and the ip route
    root@gw iproute2]# ip route show table tunnel
    default via 10.4.1.1 dev tap0

    any ideas where ive gone wrong here? thanks.

  4. matt November 12th, 2008 3:06 am

    Hi Phil,
    Sorry for not seeing this post sooner, I have been very busy recently and the blog has suffered somewhat because of it :P

    Anyway, are you still working on this?
    It could be a number of things, as luck would have it, I actually tore down this config a few months ago and now have a need for it again, so I will be re-doing this whole setup. I will try to document better this time. In the meantime are you able to run wireshark on the tun interface from both your local gateway, and tcpdump/wireshark from your webhost server?

    A couple of short captures from these while trying to connect in from the static IP will most likely give us the quickest diagnosis.

    Please let me know if you still need help with this and I’ll happily look at the wireshark/tcpdump captures and take it from there.

    //Matt

Leave a reply

Mexico