OpenVPN 2 Cookbook
上QQ阅读APP看书,第一时间看更新

Server-side routing

This recipe will demonstrate how to set up server-side routing in client or server mode. With this setup, the OpenVPN client will be able to reach all the machines behind the OpenVPN server.

Compared to the previous recipe, this recipe contains extra settings that are often used in production environments, as well as OpenVPN 2.1-specific features to make use of linear addresses (topology subnet).

The configuration files used in this recipe are useful building blocks for other recipes throughout this book, hence, they are named as basic-udp-server.conf, basic-udp-client.conf, and so on.

Getting ready

We use the following network layout here:

Getting ready

This recipe uses the PKI files created in the first recipe of this chapter. Install OpenVPN 2.1 on two computers. For this recipe, the server computer was running CentOS 5 Linux and OpenVPN 2.1.1 and the client was running Fedora 13 Linux and OpenVPN 2.1.1.

How to do it...

  1. Create the server configuration file:
    proto udp
    port 1194
    dev tun
    server 192.168.200.0 255.255.255.0
    
    ca       /etc/openvpn/cookbook/ca.crt
    cert     /etc/openvpn/cookbook/server.crt
    key      /etc/openvpn/cookbook/server.key
    dh       /etc/openvpn/cookbook/dp024.pem
    tls-auth /etc/openvpn/cookbook/ta.key 0
    
    persist-key
    persist-tun
    keepalive 10 60
    
    push "route 10.198.0.0 255.255.0.0"
    topology subnet
    
    user  nobody
    group nobody
    
    daemon
    log-append /var/log/openvpn.log

    Then save it as basic-udp-server.conf. Note that in some Linux distributions, the group nogroup is used instead of nobody.

  2. Copy over the tls-auth secret key file from the /etc/openvpn/cookbook/keys directory:
    [root@server]# cp keys/ta.key ta.key
    
  3. And start the server:
     root@server]# openvpn --config basic-udp-server.conf
    
  4. Make sure IP-traffic forwarding is enabled on the server:
    [root@server]# sysctl -w net.ipv4.ip_forward=1
    
  5. Next, create the client configuration file:
    client
    proto udp
    remote openvpnserver.example.com
    port 1194
    dev tun
    nobind
    
    ca       /etc/openvpn/cookbook/ca.crt
    cert     /etc/openvpn/cookbook/client1.crt
    key      /etc/openvpn/cookbook/client1.key
    tls-auth /etc/openvpn/cookbook/ta.key 1
    
    ns-cert-type server

    Save it as basic-udp-client.conf.

  6. Transfer the tls-auth secret key file, ta.key, to the client machine using a secure channel, such as scp:
    [root@client]# scp \ 
     openvpnserver:/etc/openvpn/cookbook/keys/ta.key . 
    
  7. Start the client:
     [root@client]# openvpn --config basic-udp-client.conf
          OpenVPN 2.1.1 x86_64-redhat-linux-gnu [SSL] [LZO2] [EPOLL]      [PKCS11] built on Jan  5 2010
         NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to  call user-defined scripts or executables
         Control Channel Authentication: using '/etc/openvpn/cookbook/ta.key' as a OpenVPN static key file
          UDPv4 link local: [undef]
          UDPv4 link remote: 194.171.96.27:1194
          [openvpnserver] Peer Connection Initiated with 194.171.96.27:1194
  8. Add a route to the server-side gateway gateway1 so that all VPN traffic is sent back to the VPN server. In this recipe, we use a router that understands a Linux ip route like syntax:
     [gateway1]> ip route add 192.168.200.0/24 via 10.198.1.1
    

After the VPN is established, verify that we are able to ping a machine on the remote server LAN:

[client]$ ping -c 2 10.198.0.10
PING 10.198.0.10 (10.198.0.10) 56(84) bytes of data.
64 bytes from 10.198.0.10: icmp_seq=1 ttl=63 time=31.1 ms
64 bytes from 10.198.0.10: icmp_seq=2 ttl=63 time=30.0 ms

How it works...

The server starts and configures the first available TUN interface with IP address 192.168.200.1. With the directive 'topology subnet', the fake remote address is also 192.168.200.1. After that, the server listens on the UDP port 1194 for incoming connections. For security reasons, the OpenVPN process switches to user and group, nobody. Even if a remote attacker was able to compromise the OpenVPN process, the security breach would be contained to the user nobody instead of the user root. When the 'user' and 'group' directives are used, it also wise to add the following as well:

persist-key
persist-tun

Otherwise, OpenVPN will not be able to restart itself correctly.

Another security measure is the use of the following on the server side (and ta.key 1 on the client side):

tls-auth /etc/openvpn/cookbook/ta.key 0

This prevents the server from being overloaded by a so-called Distributed Denial of Service (DDoS) attack, as OpenVPN will just ignore those packets immediately if the HMAC is not correct.

The following directive sets up a keepalive timer on both the client and the server side:

keepalive 10 60

Every 10 seconds, a packet is sent from the server to the client side and vice-versa, to ensure that the VPN tunnel is still up and running. If no reply is received after 60 seconds on the client side, the VPN connection is automatically restarted. On the server side, the timeout period is multiplied by 2, hence the server will restart the VPN connection if no reply is received after 120 seconds.

Finally, the following directives are very commonly used in a production setup, where the OpenVPN process continues to run in the background (daemonizes itself) after the operator logs out:

daemon
log-append /var/log/openvpn.log

All output of the OpenVPN process is appended to the log file: /var/log/openvpn.log. You can use the tail -f command to monitor the output of the OpenVPN process.

The client connects to the server. After the initial TLS handshake, using both the client and server certificates, the client is assigned the IP address 192.168.200.2. The client configures its first available TUN interface using this information and updates its routing table so that traffic for the server-side Site B's LAN is tunneled over the VPN.

There's more...

As the example files used in this recipe are reused later on , it is useful to explain a bit more about the options used.

Linear addresses

After the connection is established, you can query the tun0 interface like this:

[client]$ /sbin/ifconfig tun0 | grep inet

Look for the following:

inet addr:192.168.200.2  P-t-P:192.168.200.2

This is caused by the directive topology subnet, which is something new in OpenVPN 2.1. This directive tells OpenVPN to assign only a single IP address to each client. With OpenVPN 2.0, the minimum number of IP addresses per client is four (as we can see in the previous recipe).

Using the TCP protocol

In the previous example, we chose the UDP protocol. The configuration files in this recipe can easily be converted to use TCP protocol by changing the line:

proto udp

It should be changed to the following:

proto tcp

This should be done in both the client and server configuration files. Save these files for future use as basic-tcp-server.conf and basic-tcp-client.conf:

$ cd /etc/openvpn/cookbook
$ sed 's/proto udp/proto tcp' basic-udp-server.conf \
 > basic-tcp-server.conf
$ sed 's/proto udp/proto tcp' basic-udp-client.conf \
 > basic-tcp-client.conf

Server certificates and ns-cert-type server

On the client side, the directive ns-cert-type server is often used in combination with a server certificate that is built using:

$ build-key-server

This is done in order to prevent Man-in-the-Middle attacks. The idea is that a client will refuse to connect to a server that does not have a special server certificate. By doing this, it is no longer possible for a malicious client to pose as a server. OpenVPN 2.1 also supports the directive:

remote-cert-tls server

This also supports certificates with explicit key usage and extended key usage based on the RFC 3280 TLS rules.

Masquerading

In this recipe, the gateway on the server-side LAN is configured with an extra route for the VPN traffic. Sometimes, this is not possible, in which case the Linux iptables command can be used to set up masquerading:

[root@server]# iptables -t nat -I POSTROUTING -o eth0 \
 -s 192.168.200.0/24 -j MASQUERADE

This instructs the Linux kernel to rewrite all traffic that is coming from the subnet 192.168.200.0/24 (that is our OpenVPN subnet) and that is leaving the Ethernet interface eth0. Each of these packets has its source address rewritten so that it appears as if it's coming from the OpenVPN server itself and not from the OpenVPN client. iptables keeps track of these rewritten packets so that when a return packet is received the reverse is done and the packets are forwarded back to the OpenVPN client again. This is an easy method to enable routing to work, but there is a drawback when many clients are used, as it is no longer possible to distinguish traffic on the Site B's LAN if it is coming from the OpenVPN server itself, from client1 via the VPN tunnel, or from clientN via the VPN tunnel.