The goal of this recipe is to create an OpenVPN tunnel without assigning IP addresses to the endpoints of the tunnel. In a routed network setup, this ensures that the tunnel endpoints can never be reached through themselves, which adds some security and can also make the routing tables a bit shorter. In the OpenVPN configuration files, an IP address needs to be specified, but it is never assigned to the tunnel interface.
This recipe has only been tested on Linux systems, as it requires some network-interface configuration that is not available on other platforms.
We will use the following network layout:
Make sure that the client and server are not on the same local network. If the client and server can contact each other directly then this recipe will fail. Set up the client and server certificates using the first recipe from Chapter 2, Client-server IP-only Networks. In this recipe, the server computer was running CentOS 6 Linux and OpenVPN 2.3.12. The client was running Fedora 22 Linux and OpenVPN 2.3.11. Keep the server config file, example3-1-server.conf
, from the Simple configuration - non-bridged recipe from Chapter 3, Client-server Ethernet-style Networks.
example3-1-server.conf
file:route 192.168.4.0 255.255.255.0 192.168.99.1
example10-8-server.conf
.[root@server]# openvpn --config example10-8-server.conf
client proto udp remote openvpnserver.example.com port 1194 dev tap nobind remote-cert-tls server tls-auth /etc/openvpn/cookbook/ta.key 1 ca /etc/openvpn/cookbook/ca.crt cert /etc/openvpn/cookbook/client1.crt key /etc/openvpn/cookbook/client1.key script-security 2 ifconfig-noexec up /etc/openvpn/cookbook/example10-8-up.sh route-noexec route-up /etc/openvpn/cookbook/example10-8-route-up.sh
example-10-8-client.conf
.example10-8-up.sh
script:#!/bin/bash /sbin/ifconfig $1 0.0.0.0 up # needed for TAP interfaces !!! echo 1 > /proc/sys/net/ipv4/conf/$1/proxy_arp
/etc/openvpn/cookbook/example10-8-up.sh
.example10-8-route-up.sh
script:#!/bin/bash # add an explicit route back to the VPN endpoint /sbin/ip route add $route_vpn_gateway/32 dev $dev n=1; while [ $n -le 100 ] do network=`env | sed -n "/^"route_network_${n}=/s/^route_network_${n}=//p"`" netmask=`env | sed -n "/^"route_netmask_${n}=/s/^route_netmask_${n}=//p"`" if [ -z "$"network" -o -z "$"netmask" ] then break fi /sbin/ip route add $network/$netmask dev $dev let n=n+1 done
/etc/openvpn/cookbook/example10-8-route-up.sh
.[[root@client]# chmod 755 /etc/openvpn/cookbook/example10-8*.sh [root@client]# openvpn --config example10-8-client.conf
tap0
interface and the routing tables, and verify that you can ping the server:[root@client]# ip addr show tap0 13: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100 link/ether b6:b3:0e:41:d5:4d brd ff:ff:ff:ff:ff:ff inet6 fe80::b4b3:eff:fe41:d54d/64 scope link valid_lft forever preferred_lft forever [root@client]# netstat-rn Kernel IP routing table Destination Gateway Genmask Flags[...] Iface 192.168.4.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 10.198.0.0 0.0.0.0 255.255.0.0 U 0 0 0 tap0 [...] [root@client]# ping -c 2 192.168.99.1 PING 192.168.99.1 (192.168.99.1) 56(84) bytes of data. 64 bytes from 192.168.99.1: icmp_seq=1 ttl=64 time=25.7 ms 64 bytes from 192.168.99.1: icmp_seq=2 ttl=64 time=26.2 ms
The OpenVPN server allocates an IP address for the client, but that does not mean that the client interface actually needs to assign these addresses. The example10-8-up.sh
script does exactly this.
Some older Linux kernels refuse to add a route without an address being assigned to an interface. Hence, we assign the address 0.0.0.0
to the tun0
interface. To add the routes that are pushed by the server, a special route-up
script is used, example10-8-route-up.sh
, which brings up all the routes.
Please note the following when considering an IP-less setup.
This recipe can also be used in a point-to-point style environment, where static keys are used to connect two networks. Similarly, it can also be used in a TUN-style setup.
At first, this recipe might seem odd. The advantage of this setup is that the OpenVPN client itself is not reachable by other machines on the VPN. This is handy when connecting many clients to an OpenVPN server, but some clients are used as gateways to the networks behind them (for example, to connect a remote office to the OpenVPN server). By not assigning the remote office gateway an IP address, there is no risk of the gateway itself being attacked from the remote VPN side. Also, server-side firewalling and iptables
rules can be slightly shorter in this scenario, as there will be no traffic coming from the OpenVPN client with the VPN source address. This is also the reason why the server configuration has an explicit route to the client-side network:
route 192.168.4.0 255.255.255.0 192.168.99.1
It also explains why this recipe will fail if the VPN client and server are on the same local area network. If the VPN client can contact the VPN server directly then the VPN server will not be able to determine which traffic needs to go inside the tunnel and which traffic needs to be sent directly to the client.
13.59.123.182