route http and ssh traffic normally, everything else via vpn tunnel

Posted by Normadize on Server Fault See other posts from Server Fault or by Normadize
Published on 2013-10-19T04:48:08Z Indexed on 2013/10/19 15:58 UTC
Read the original article Hit count: 208

Filed under:
|
|

I've read quite a bit and am close, I feel, and I'm pulling my hair out ... please help!

I have an OpenVPN cliend whose server sets local routes and also changes the default gw (I know I can prevent that with --route-nopull). I'd like to have all outgoing http and ssh traffic via the local gw, and everything else via the vpn.

  • Local IP is 192.168.1.6/24, gw 192.168.1.1.
  • OpenVPN local IP is 10.102.1.6/32, gw 192.168.1.5
  • OpenVPN server is at {OPENVPN_SERVER_IP}

Here's the route table after openvpn connection:

# ip route show table main
0.0.0.0/1 via 10.102.1.5 dev tun0 
default via 192.168.1.1 dev eth0  proto static 
10.102.1.1 via 10.102.1.5 dev tun0 
10.102.1.5 dev tun0  proto kernel  scope link  src 10.102.1.6 
{OPENVPN_SERVER_IP} via 192.168.1.1 dev eth0 
128.0.0.0/1 via 10.102.1.5 dev tun0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.6  metric 1

This makes all packets go via to the VPN tunnel except those destined for 192.168.1.0/24.

Doing wget -qO- http://echoip.org shows the vpn server's address, as expected, the packets have 10.102.1.6 as source address (the vpn local ip), and are routed via tun0 ... as reported by tcpdump -i tun0 (tcpdump -i eth0 sees none of this traffic).

What I tried was:

  • create a 2nd routing table holding the 192.168.1.6/24 routing info (copied from the main table above)
  • add an iptables -t mangle -I PREROUTING rule to mark packets destined for port 80
  • add an ip rule to match on the mangled packet and point it to the 2nd routing table
  • add an ip rule for to 192.168.1.6 and from 192.168.1.6 to point to the 2nd routing table (though this is superfluous)
  • changed the ipv4 filter validation to none in net.ipv4.conf.tun0.rp_filter=0 and net.ipv4.conf.eth0.rp_filter=0

I also tried an iptables mangle output rule, iptables nat prerouting rule. It still fails and I'm not sure what I'm missing:

  • iptables mangle prerouting: packet still goes via vpn
  • iptables mangle output: packet times out

Is it not the case that to achieve what I want, then when doing wget http://echoip.org I should change the packet's source address to 192.168.1.6 before routing it off? But if I do that, the response from the http server would be routed back to 192.168.1.6 and wget would not see it as it is still bound to tun0 (the vpn interface)?

Can a kind soul please help? What commands would you execute after the openvpn connects to achieve what I want?

Looking forward to hair regrowth ...

© Server Fault or respective owner

Related posts about iptables

Related posts about vpn