A very common use of a VPN is to route all the traffic over a secure tunnel. This allows one to safely access a network or even the Internet itself from within a "hostile" environment (for example, a poorly protected, but properly trojaned Internet caféteria).
In this recipe, we will set up OpenVPN to do exactly this. This recipe is very similar to the Server-side routing recipe, but there are some pitfalls when redirecting all the traffic over a VPN tunnel.
The network layout used in this recipe is the same as in the recipe Server-side routing. This recipe uses the PKI files created in the first recipe of this chapter. For this recipe, the server computer was running CentOS 5 Linux and OpenVPN 2.1.1. The client was running Fedora 13 Linux and OpenVPN 2.1.1. Keep the configuration file, basic-udp-server.conf
, from the recipe Server-side routing at hand, as well as the client configuration file, basic-udp-client.conf
.
- Create the server configuration file by adding a line to the
basic-udp-server.conf
file:push "redirect-gateway def1"
Save it as
example2-6-server.conf
. - Start the server:
[root@server]# openvpn --config example2-6-server.conf
- In another server terminal, enable IP-traffic forwarding:
[root@server]# sysctl -w net.ipv4.ip_forward=1
- Start the client:
[root@client]# openvpn --config basic-udp-client.conf
- After the VPN is established, verify that all traffic is going over the tunnel:
The first address in the traceroute
output is the address of the OpenVPN server, hence all the traffic is routed over the tunnel.
When the client connects to the OpenVPN server, a special route is pushed out by the server to the OpenVPN client:
push "redirect-gateway def1"
The configuration option def1
tells the OpenVPN client to add three routes to the client operating system:
10.198.1.1 via 192.168.4.254 dev eth0 0.0.0.0/1 via 192.168.200.1 dev tun0 128.0.0.0/1 via 192.168.200.1 dev tun0
The first route is an explicit route from the client to the OpenVPN server via the LAN interface. This route is needed as otherwise all the traffic for the OpenVPN server itself would go through the tunnel.
The other two routes are a clever trick to overrule the default route so that all the traffic is sent through the tunnel instead of to the default LAN gateway. The existing default route to the LAN gateway is not deleted due to the def1
parameter.
Originally, OpenVPN supported only the directive:
push "redirect-gateway"
This is used to delete the original default route and replace it with a route to the OpenVPN server. This may seem like a clean solution, but in some cases, OpenVPN was unable to determine the existing default route. This often happened to clients connecting through UMTS. This also used to create routing lockups, where all traffic was routed through the tunnel, including the packets sent by the OpenVPN client itself.
With OpenVPN, there are several flags for the redirect-gateway
directive:
local
: It doesn't set a direct route from the client to the server. It is useful only if the client and server are in the same LAN, such as when securing wireless networks.bypass-dhcp
: It adds a direct route to the local DHCP server. It is picked up automatically by Windows client. On other operating systems, a plugin or script is required.bypass-dns
: It adds a direct route to the local DNS server. It is also picked up by Windows client automatically and require a plugin or script on other other operating systems.
In some cases, the redirect-gateway
parameter is a bit too restrictive. You might want to add a few routes to local networks and route all other traffic over the VPN tunnel. The OpenVPN route
directive has a few special parameters for this:
net_gateway
: This is a special gateway representing the LAN gateway address that OpenVPN determined when starting. For example, to add a direct route to the LAN 192.168.4.0/24, you would add the following to the client configuration file:route 192.168.4.0 255.255.255.0 net_gateway
vpn_gateway
: This is a special gateway representing the VPN gateway address. If you want to add a route that explicitly sends traffic for a particular subnet over the VPN tunnel, overruling any local routes, you would add: