Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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 ...

share|improve this question

1 Answer 1

0.0.0.0/1 via 10.102.1.5 dev tun0 This is your issue.

0.0.0.0/1 is an insanely large IP range (0.0.0.0 - 127.255.255.255) and it's the first entry in your routing table so any IP address that falls into that range will be forced to route down tun0 . The range is so large that it encompasses a major portion of the routable IP space on the internet. So echoip.org, which for me, resolves to 69.163.172.52 is contained within 0.0.0.0/1 (0.0.0.0 - 127.255.255.255).

To see if I'm correct try a wget to http://serverfault.com, which for me resolves to 198.252.206.16, and see if it goes out eth0. It should because it falls outside of (0.0.0.0 - 127.255.255.255).

In general I usually make my tun0 IP space a specific as possible. 10.102.0.0/16 via 10.102.1.5 for example.

Unless your goal is to route all your internet traffic through a specific egress point for security/monitoring reasons I would try to narrow down your tunnel IP space.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.