Pinging an external server through OpenVPN tunnel doesn’t work

1

I have an OpenVPN server and a client, and I want to use this tunnel to access not only 10.0.8.0/24 but the whole internet. So far, pinging the server from the client through the tun0 interface works, and vice versa.

However, pinging www.google.com from the client through tun0 doesn’t work (all packets are lost).

I figured that I should configure the server so that any packet coming from tun0 in destination of the internet be forwarded, so I came up with this iptables config line:

interface_connecting_to_the_internet='eth0'
interface_openvpn='tun0'
internet_ip_address=`ifconfig "$interface_connecting_to_the_internet" | sed -n s'/.*inet \([0-9.]*\).*/\1/p'`

iptables -t nat -A POSTROUTING -o "${interface_connecting_to_the_internet}" -j SNAT --to-source "${internet_ip_address}"
echo '1' > /proc/sys/net/ipv4/ip_forward

Yet, this doesn’t work, the packets are still lost and I am wondering what could possibly be wrong with my setup.


Some details:

ip route gives on the server:

default via 176.31.127.254 dev eth0  metric 3 
10.8.0.0/24 via 10.8.0.2 dev tun0 
10.8.0.2 dev tun0  proto kernel  scope link  src 10.8.0.1 
127.0.0.0/8 via 127.0.0.1 dev lo 
176.31.127.0/24 dev eth0  proto kernel  scope link  src 176.31.127.109 

ip route gives on the client:

default via 192.168.1.1 dev wlan0  proto static 
10.8.0.1 via 10.8.0.5 dev tun0 
10.8.0.5 dev tun0  proto kernel  scope link  src 10.8.0.6 
127.0.0.0/8 via 127.0.0.1 dev lo  scope link 
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.109 

  • client uses wifi adapter wlan0 and TUN adapter tun0.
  • server uses ethernet adapter eth0 and TUN adapter tun0.
  • the VPN spans on 10.0.8.0/24

  • both client and linux are using Linux 3.6.1.

qdii

Posted 2012-11-03T21:29:21.790

Reputation: 787

It probably would be helpful if you could elaborate on the OS used on the client and the routes defined on both the server and the client (the output of ‘ip route’ should do in the case of Linux). – Claudius – 2012-11-03T21:55:00.037

@Claudius here you go! – qdii – 2012-11-03T22:03:26.843

I assume that you have tried turning off iptables to eliminate that as the cause? – Julian Knight – 2012-11-03T22:04:36.033

@JulianKnight I normally don’t use iptables, I just added the rule to see if it would help. So my first configuration did not use iptables. – qdii – 2012-11-03T22:08:08.153

I take it you did not enable the push "redirect-gateway def1" option on the OpenVPN server? As of now, the routes on the client direct it to use 192.168.1.1 as the default gateway. To change that, you would have to add a specific route to your server via the current default gateway, then delete the default route and set a new one via your server (or, alternatively, use the option mentioned above). – Claudius – 2012-11-03T22:08:15.037

And you either need the iptables rule given in your post or something like iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE to enable masquerading on the server (else it pushes out the packages with the private IP of the client, and that won’t work :-)) – Claudius – 2012-11-03T22:08:34.413

@Claudius: I might be wrong, but I used ping -Itun0 www.google.com to override the gateway, shouldn’t that work? I didn’t want to redirect the default gateway to the tun0 adapter before I was sure it worked (or I wouldn’t be able to talk right now) – qdii – 2012-11-03T22:12:59.867

That merely tells ping to push the packet out the tun0 interface, but it will still be directed towards 192.168.1.1, I think. -I is usually only meant for link-local pings (mostly IPv6, I guess). – Claudius – 2012-11-03T22:18:08.940

@Claudius I routed the google ip addresses via tun0 but I can’t wget them anymore, so I don’t think this works. see http://bpaste.net/show/55677/

– qdii – 2012-11-03T22:27:50.950

let us continue this discussion in chat

– Claudius – 2012-11-03T22:38:22.207

@Claudius if you wanna formulate an answer, I’d be glad to give you the response point. – qdii – 2012-11-04T23:09:38.620

Answers

2

To sum up the discussion:

In order to reach a specific host A through a VPN from client C to server S, one has to:

  • enable ip forwarding on S (sysctl -w net.ipv4.ip_forward=1)
  • enable either masquerading or snat via iptables on S: iptables -t nat -A POSTROUTING -o ext_if -j MASQUERADE or iptables -t nat -A POSTROUTING -o ext_if-j SNAT --to-source ext_ip with the obvious meaning of ext_if and ext_ip.
  • set up appropriate routing on C, either (S denotes S’ IP address in the VPN):
    • by setting an explicit route to A via S: ip route add A via S dev vpn_if
    • by setting a default route via S: ip route add default via S dev vpn_if, where one also has to set an appropriate route to S: ip route add S via previous_gateway dev prev_if.
    • by using the push "redirect-gateway def1" on the server, in which case OpenVPN will set up routes to 0.0.0.0/1 and 128.0.0.0/1 on C via S, which are more specific than the default route and can easily be removed when the tunnel is stopped.

Claudius

Posted 2012-11-03T21:29:21.790

Reputation: 6 330