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 including the use of linear addresses (topology subnet).

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

Getting ready

Install OpenVPN 2.3.9 or higher on two computers. Make sure the computers are connected over a network. Set up the client and server certificates using the previous recipe. For this recipe, the server computer was running CentOS 6 Linux and OpenVPN 2.3.9 and the client was running Fedora 20 Linux and OpenVPN 2.3.9.

We use the following network layout here:

Getting ready

How to do it...

  1. Create the server configuration file:
            proto udp 
            port 1194 
            dev tun 
            server 10.200.0.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/dh2048.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   # use "group nogroup" on some distros 
     
            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. Then 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 
     
            remote-cert-tls 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.3.9 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] 
            [EPOLL]
    [PKCS11] [MH] [IPv6] built on Dec 16 2015
    library versions: OpenSSL 1.0.1e-fips 11 Feb 2013, LZO 2.08
    Control Channel Authentication: using   
            '/etc/openvpn/cookbook/ta.key' as a OpenVPN static key file
    UDPv4 link local: [undef]
    UDPv4 link remote: [AF_INET]openvpnserver:1194
    [openvpnserver] Peer Connection Initiated with      
            [AF_INET]openvpnserver:1194
    TUN/TAP device tun0 opened
    do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
    /usr/sbin/ip link set dev tun0 up mtu 1500
    /usr/sbin/ip addr add dev tun0 10.200.0.2/24 broadcast 
            10.200.0.255
    Initialization Sequence Completed
    
  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 10.200.0.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 the IP address 10.200.0.1. With the directive topology subnet, the fake remote address is also 10.200.0.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 is 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 two; 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 10.200.0.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

Then, look for the following:

inet addr:10.200.0.2  P-t-P:10.200.0.2 

This is caused by the topology subnet directive, 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 the TCP protocol by changing the following 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 as basic-tcp-server.conf and basic-tcp-client.conf for future use:

$ 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 remote-cert-tls server directive is often used in combination with a server certificate that is built using the following:

$ 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. This option also supports certificates with explicit key usage and extended key usage, based on the RFC 3280 TLS rules.

Older versions of OpenVPN used the ns-cert-type server directive. This option is still supported, but it will be deprecated in a future version of OpenVPN.

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 10.200.0.0/24 -j MASQUERADE

This instructs the Linux kernel to rewrite all traffic that is coming from the subnet 10.200.0.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. The iptables module 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 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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.1.22