Mastering OpenVPN - Sample Chapter

Download as pdf or txt
Download as pdf or txt
You are on page 1of 57

Fr

ee

Sa

pl

In this package, you will find:

The authors biography


A preview chapter from the book, Chapter 4 'Client/Server Mode with
tun Devices'
A synopsis of the books content
More information on Mastering OpenVPN

About the Authors


Eric F Crist is an IT professional with experience in hardware and software

systems integration. With a few others, he has had a key role in building the
OpenVPN community to what it is today. He works in research and development
as a principal computer system specialist for St. Jude Medical. His role involves
system engineering, configuration management, and cyber security analysis for
products related to the Cardiovascular Ablation Technology division.

You can find him online at the Freenode and EFNet IRC networks as ecrist.
He calls the Twin Cities, Minnesota, his home and lives with his wife, DeeDee,
his son, Lance, and his daughter, Taylor.

Jan Just Keijser is an open source professional from Utrecht, the Netherlands. He
has a wide range of experience in IT, ranging from providing user support, system
administration, and systems programming to network programming. He has worked
for various IT companies since 1989. He has been working mainly on Unix/Linux
platforms since 1995. He was an active USENET contributor in the early 1990s.
Currently, he is employed as a senior scientific programmer in Amsterdam,
the Netherlands, at Nikhef, the institute for subatomic physics from the Dutch
Foundation for Fundamental Research on Matter (FOM). He is working on multi-core
and many-core computing systems, grid computing, as well as smartcard applications.
His open source interests include all types of virtual private networking, including
IPSec, PPTP, and of course, OpenVPN. In 2004, he discovered OpenVPN and has been
using it ever since.
His first book was OpenVPN 2 Cookbook, Packt Publishing.

Preface
Privacy and security on the Internet and in private networks is a growing concern
and is increasingly common in the news, where there are breaches of each. Virtual
private networks (VPN) were created out of a need for secured communications.
The most popular and widely used open source VPN software today is OpenVPN.
Mastering OpenVPN aims to educate you on deployment, troubleshooting, and
configuration of OpenVPN and provide solid use cases for various scenarios.

What this book covers


Chapter 1, Introduction to OpenVPN, discusses the various types of Virtual Private
Networks and some of their various strengths and weaknesses. PPTP, OpenVPN,
IPSec, and other protocols are also discussed in this chapter.
Chapter 2, Point-to-point Mode, covers the OpenVPN roots, point-to-point mode,
and the initially only supported mode. It also covers the tap mode in a bridged
scenario and an uncommon configuration.
Chapter 3, PKIs and Certificates, explains the complex concept of X.509 certificates and
PKIs with examples and a demonstration of a couple of utilities. It also covers how to
create a certificate chain and deploy that chain to their VPN.
Chapter 4, Client/Server Mode with tun Devices, walks you through the most common
deployment mode, a tun or routed, and its setup. It also discusses the passing of
client-backed routes along with IPv4 and IPv6.
Chapter 5, Advanced Deployment Scenarios in tun Mode, covers policy-based routing
and configuring OpenVPN to integrate your VPN clients with the rest of the LAN.
Complex examples of tun mode are examined, showing that they are appropriate
even in advanced scenarios.

Preface

Chapter 6, Client/Server Mode with tap Devices, discusses the often misused and less
commonly deployed tap or bridged mode VPNs. Solid examples of broadcast and
OSI layer 2 traffic are demonstrated in this chapter.
Chapter 7, Scripting and Plugins, helps you gain an understanding of the methods
to extent the VPN, including authentication, routing, and protocol enhancements.
This chapter helps an administrator create a local experience for a worker or a user
on the move.
Chapter 8, Using OpenVPN on Mobile Devices and Home Routers, helps you learn
how to use home router OSes and features to deploy OpenVPN. We understand
that it's not just enterprise or commercial users looking to protect their privacy
and data. Increasingly, home users desire to deploy secure connections to their
home resources.
Chapter 9, Troubleshooting and Tuning, will help you become an expert in your
OpenVPN deployment by learning how to troubleshoot problems and bugs.
The ability to identify issues creates a solid and reliable installation and confidence
in your users.
Chapter 10, Future Directions, gives you a brief history and lengthier discussion
of the future direction of OpenVPN, and the mindset of the developers is revealed.
It also helps you understand the reasoning and history behind the various decisions
behind features and bugs.

Client/Server Mode with tun


Devices
The most commonly used deployment model for OpenVPN is a single server with
multiple remote clients capable of routing IP traffic. We refer to this deployment
model as the client/server mode with tun devices.
In this chapter, we start off with a basic client/server setup. We will add more
features as we go along, and some advanced examples on how to set up OpenVPN
in client/server tun mode are given at the end of this chapter. In the next chapter, we
will explain how to integrate a client/server tun-based setup in an existing network
setup, including topics such as Windows file sharing and policy based routing.
The following topics will be covered in this chapter:

Setting up the Public Key Infrastructure


Initial setup of the client/server mode
Adding extra security with production-level configuration files
Routing and server-side routing
Client-specific configuration using CCD files
Client-side routing
Redirecting the default gateway
The OpenVPN status file
The OpenVPN management interface
Session key renegotiation
Using IPv6
Proxy ARP
Handing out public IP addresses
[ 97 ]

Client/Server Mode with tun Devices

Understanding the client/server mode


The client/server mode was first introduced with OpenVPN 2.0. In this mode, the
server is a single OpenVPN process to which multiple clients can connect. Each
authenticated and authorized client is assigned an IP address from a pool of IP
addresses that the OpenVPN server manages. Clients cannot communicate directly
with one another. All traffic flows via the server, which has both advantages and
disadvantages.
The advantages are as follows:

Control: The VPN server administrator can control which traffic is allowed
to flow between clients. By default, no traffic is allowed to flow between
clients. However, using either the OpenVPN option client-to-client or
by using clever firewall and routing rules, it is possible to allow clients to
communicate with each other.

Ease of deployment: It is much easier to set up a single server that can


be reached by many different clients than it is to ensure connectivity
between a multitude of clients, each with their own network and firewall
configurations.

The disadvantages are as follows:

Scalability: As all traffic is flowing from client to server (and vice versa),
the server can quickly become the bottleneck in large scale VPN setups.

Performance: As all traffic between two clients (clients A and B) needs to


flow from client A to the server and then from the server to client B, the
performance of this type of VPN will always be lower when compared to a
direct client-to-client connection.

The most common deployment scenario for this mode is an OpenVPN server
at a corporate site that the various VPN clients connect to. Clients may include
satellite offices, road warriors, people working at home, as well as smart phone
and tablet users.
This deployment model covers 95 percent of the typical requirements for VPNs,
and is preferable over more complicated setups using advanced features such as
bridging. Only if there are specific requirements to route non-IP traffic (for example,
legacy IPX traffic) or if there is a need to form a single network broadcast domain,
then this deployment model will not suffice.

[ 98 ]

Chapter 4

Setting up the Public Key Infrastructure


In the client/server mode, OpenVPN is configured using a Public Key
Infrastructure (PKI) with X.509 certificates and private keys. Before we can set up
a client/server VPN, we need to set up this PKI first. The PKI comprises of the CA,
the private keys, and the certificates (public keys) for both the client and server. In
Chapter 3, PKIs and Certificates, we will discuss in detail how to set up such a PKI.
This chapter builds upon the certificates and keys generated in that chapter.
First, we copy the certificate and keys to a separate location. In general, it is a
good security practice to keep the PKI files in a separate location, if possible
even on a separate computer. Special care should be taken to protect the ca.key
file, as the entire security of your PKI is dependent on this file. If the ca.key
file is compromised in any way, the entire PKI is rendered insecure, and should
be abandoned. In the following commands, it is assumed that the PKI files are
generated using ssladmin and are stored in a directory <PKI_DIR>, where <PKI_
DIR> represents a real directory on the system. Execute the following commands to
copy over the necessary PKI files for the server:
[root@server] # mkdir -p /etc/openvpn/movpn
[root@server] # chmod 700 /etc/openvpn/movpn
[root@server] # cd /etc/openvpn/movpn
[root@server] # PKI=<PKI_DIR>/ssladmin/active
[root@server] # cp -a $PKI/ca.crt movpn-ca.crt
[root@server] # cp -a $PKI/Mastering_OpenVPN_Server.crt server.crt
[root@server] # cp -a $PKI/Mastering_OpenVPN_Server.key server.key

We also need to generate a Diffie-Hellman (DH) parameter file that is required


for VPN session keys. The session keys are ephemeral or temporary keys and are
generated when the connection between client and server is first set up. To ensure
optimal security, the ephemeral keys are regenerated during the session at fixed
intervals. The default key interval for OpenVPN is one hour, but this can be tuned
using various OpenVPN options. This will be explained later in this chapter in the
section Session key renegotiation.
To generate a DH parameter file, execute the following commands:
[root@server] # cd /etc/openvpn/movpn
[root@server] # openssl dhparam -out dh2048.pem 2048
Generating DH parameters, 2048 bit long safe prime, generator 2

[ 99 ]

Client/Server Mode with tun Devices


This is going to take a long time
........+................................................................
..................................................................+......

In this example, we choose a DH key size of 2048 bits, which is the recommended
size. You may also use larger DH key sizes, but it will make the initial connection
process for each OpenVPN client slower. We are now ready to set up and start the
OpenVPN server.

Initial setup of the client/server mode


In order to set up a basic OpenVPN server, we first create a server configuration file
using the following steps:
1. Create the following file
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
dh
ca
cert
key

/etc/openvpn/movpn/dh2048.pem
/etc/openvpn/movpn/movpn-ca.crt
/etc/openvpn/movpn/server.crt
/etc/openvpn/movpn/server.key

user nobody
group nobody

# use group nogroup on Debian/Ubuntu

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

2. Then, save it as movpn-04-01-server.conf. A detailed explanation of


each of the configuration lines will be given later.
3. Start the OpenVPN server:
[root@server] # openvpn --config movpn-04-01-server.conf

[ 100 ]

Chapter 4

4. The command will not produce any output on the command line, as all
output is redirected to the log file /var/log/openvpn.log. Check this file
for OpenVPNs startup message details:
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO]
[EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Enter Private Key Password:
WARNING: this configuration may cache passwords in memory -- use
the auth-nocache option to prevent this
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.1/24 broadcast 10.200.0.255
GID set to nobody
UID set to nobody
UDPv4 link local (bound): [undef]
UDPv4 link remote: [undef]
Initialization Sequence Completed

5. Please note that normally each log file entry starts with a timestamp. For the
sake of clarity, this timestamp has been removed.
6. Next, create the client configuration file:
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
ca
/etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/client1.crt
key /etc/openvpn/movpn/client1.key

Save it as movpn-04-01-client.conf.
7. Transfer the PKI files to the client using a secure channel, for example, using
the scp command:
[root@client]# mkdir -p /etc/openvpn/movpn
[root@client]# chmod 700 /etc/openvpn/movpn
[root@client]# cd /etc/openvpn/movpn
[root@client]# PKI_HOST=openvpnserver.example.com
[root@client]# PKI=<PKI_DIR>/ssladmin/active

[ 101 ]

Client/Server Mode with tun Devices


[root@client]# scp root@$PKI_HOST:$PKI/ca.crt movpn-ca.crt
[root@client]# scp root@$PKI_HOST:$PKI/client1.crt client1.crt
[root@client]# scp root@$PKI_HOST:$PKI/client1.key client1.key

8. Start the OpenVPN client:


[root@client]# openvpn --config movpn-04-01-client.conf
--suppress-timestamps
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO]
[EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
WARNING: No server certificate verification method has been
enabled. See http://openvpn.net/howto.html#mitm for more info.
UDPv4 link local: [undef]
UDPv4 link remote: [AF_INET]openvpnserver:1194
[Mastering OpenVPN Server] Peer Connection Initiated with [AF_
INET]openvpnserver:1194
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.2/24 broadcast 10.200.0.255
Initialization Sequence Completed

9. The timestamps are again missing, but this time they are suppressed
using the OpenVPN option suppress-timestamps, as specified on the
command line.
10. After the connection has come up, check for the following message:
Initialization Sequence Completed

11. You can verify that the connection is functioning correctly by pinging the
VPN address of the server:

[ 102 ]

Chapter 4

Detailed explanation of the configuration files


As this is the first client/server example, a detailed explanation of the server and
client configuration files is in order. The server configuration file contains the
following lines:

proto udp: While this is the default protocol, it is wise to explicitly list it in

port 1194: This is the local port that OpenVPN will listen on. The default

dev tun: This specifies the name of the tun device that will be used for the

server 10.200.0.0 255.255.255.0: The server statement puts OpenVPN

the configuration file to avoid any confusion.

value is 1194, but any valid and available port number can be used.

server. By not adding a number behind the tun, we instruct OpenVPN to


open a new tun device. This new device will be assigned the first available
number in the system kernel, starting at 0 (tun0, tun1, tun2 and so on). For
Windows servers, it is advisable to keep this line as is. If a specific Windows
device needs to be used, then the option dev-node is required.

in server mode. The IP subnet and subnet mask specify the subnet and mask
to use for the VPN server and clients. The VPN server is assigned the first
address, which in this case is 10.200.0.1. The first client is assigned the
address 10.200.0.2 (because we are using topology subnet). The server
statement for this configuration is internally expanded as follows:
mode server
tls-server
push topology subnet
ifconfig 10.200.0.1 255.255.255.0
ifconfig-pool 10.200.0.2 10.200.0.254 255.255.255.0
push route-gateway 10.200.0.1

This is taken from the OpenVPN manual page at https://community.


openvpn.net/openvpn/wiki/Openvpn23ManPage. If these configuration
lines are used instead of the macro server, the same configuration is used.
The expansion includes push topology subnet because we
have also specified topology subnet in the configuration file.
Without this line, the expansion would not have occurred.

[ 103 ]

Client/Server Mode with tun Devices

topology subnet: This specifies the topology for the VPN. The current
default topology is net30, in which the server and each client are assigned
a separate miniature /30 subnet space. More details on the use of topology

subnet versus topology net30 are given in the following section.

persist-tun and persist-key: Instruct OpenVPN to neither reopen

keepalive 10 60: This is used to make sure that the VPN connection
remains up, even if there is no traffic flowing over the tunnel. The keepalive
statement is a macro for the ping and ping-restart commands. The
statement keepalive 10 60 in a server-side configuration expands to:

the tun device, nor generate new keying material whenever the tunnel is
restarted. These options are particularly useful in combination with user
nobody, as the user nobody normally does not have the access rights to
open a new tun interface.

ping 10
ping-restart 120
push ping 10
push ping-restart 60

The preceding code means:

Send a ping message to each client every 10 seconds

Restart the connection if a client does not respond within 120 seconds
(2 * 60 = 120)

Push the statements ping 10 and ping-restart 60 to each client

dh <path to Diffie Hellman file>: This specifies the path to the

ca <path to CA file>: This specifies the path to the CA file. The CA file
needs to contain the CA certificate (or even set of certificates) that was used
to sign the client certificates. It does not necessarily have to be the same CA
as the one that was used to sign the server certificate, although in our PKI
setup we used the same CA. It is advisable to use an absolute path for this
file (as well as the other certificate and private key paths).

cert <path to X.509 certificate file>: This specifies the path to the
server X.509 public certificate file. This certificate is needed by the OpenVPN
server, even if the clients are connection without using certificates. It is
advisable to use an absolute path for this file (as well as the other certificate
and private key paths).

DH file that is required for the OpenVPN server. Without this file, the
server cannot establish a secure TLS connection with the clients. It is
advisable to use an absolute path for this file (as well as the other
certificate and private key paths).

[ 104 ]

Chapter 4

key <path to private key file>: This specifies the path to the server

user nobody and group nobody: This instructs OpenVPN to drop to Unix
user nobody and group nobody after the connection has come up. This

private key file. This private key file is needed by the OpenVPN server, even
if the clients are connecting without using certificates or private keys. This
file needs to be readable by the root (or administrator) user only, as anyone
with read access to private keys can decrypt OpenVPN traffic. Note that
OpenVPN will read this file before dropping user privileges. It is advisable
to use an absolute path for this file (as well as the other certificate and private
key paths).

further enhances security, as an attack on the tunnel will less likely result in a
root exploit. Note that on Debian/Ubuntu the group nogroup is used.

verb 3: This sets the verbosity level to the default value of 3. Increase
this number to view more detailed output of the OpenVPN process. If the
verbosity is set to 0, then hardly any logging output is produced. However,
this is not recommended.

daemon: This tells OpenVPN to daemonize itself, which means that the

OpenVPN process will keep running even after the terminal window in
which OpenVPN was started is closed.
log-append <path to log file>: This specifies the path to the server
log file. By using log-append instead of log <path to file>, we prevent
OpenVPN from truncating the log file each time it starts. For this file, it is
also advisable to use an absolute path.

The client configuration file contains:

client: This puts OpenVPN into client mode. It instructs OpenVPN


to connect to the remote server and to pull and process configuration
parameters from the server after a successful connection has been made.
The client statement is internally expanded as follows:
tls-client
pull

proto udp: This specifies the protocol to use. While this is the default

remote openvpnserver.example.com: This specifies the name of the VPN

protocol, it is wise to explicitly list it in the configuration file to avoid


any confusion.

server to connect to. The name can be either a Fully qualified domain name
(FQDN) or an IPv4 address. Later in this chapter, we will see how to connect
to an IPv6-based VPN server.

[ 105 ]

Client/Server Mode with tun Devices

port 1194: This is the port that the OpenVPN client will use to connect to

the server. The default value is 1194, but any valid and available port number
can be used.

There are multiple ways to specify a remote address and port for
the VPN server. For example, it is also possible to use remote
openvpnserver.example.com:1194.

dev tun: This specifies the name of the tun device that will be used for the

nobind: This instructs the OpenVPN client not to bind to (and not listen on)
the port specified using port. Instead, the OpenVPN client will use a port in
the anonymous port range, which is typically 1024-65335.

ca <path to CA file>: This specifies the path to the CA file. This CA file

server. By not adding a number behind the tun, we instruct OpenVPN to


open a new tun device. This new device will be assigned the first available
number in the system kernel, starting at 0 (tun0, tun1, tun2 and so on). For
Windows servers, it is advisable to keep this line as is. If a specific Windows
device needs to be used, then the option dev-node is required.

needs to contain the CA certificate (or even set of certificates) that was used
to sign the server certificate. It does not necessarily have to be the same CA
as the one that was used to sign the client certificate, although we used the
same CA in our PKI setup. On Linux/Unix it is advisable to use an absolute
path for this file (as well as the other certificate and private key paths).
cert <path to X.509 certificate file>: This specifies the path to this

clients X.509 public certificate file. It is possible to configure OpenVPN to


use username/password authentication instead of certificates, but this is
considered less secure. On Linux/Unix, it is advisable to use an absolute path
for this file (as well as the other certificate and private key paths).
key <path to private key file>: This specifies the path to the client

private key file. This file needs to be readable by the root (or administrator)
user only, as OpenVPN will read this file before dropping user privileges. On
Linux, it is advisable to use an absolute path for this file (as well as the other
certificate and private key paths).

[ 106 ]

Chapter 4

Note that we did not specify daemon or log-append for the client configuration, as
in most cases a wrapper application will launch the openvpn process. This wrapper
application will then control the logging of OpenVPN. The most commonly used
wrapper applications are:
Operating system

Wrapper applications

Windows

OpenVPN-GUI.exe (part of OpenVPN installer package)

Mac OS X

Tunnelblick or Viscosity

Linux

NetworkManager (with OpenVPN plugin)

Topology subnet versus topology net30


OpenVPN supports several topologies in tun mode:

net30 (default, may change with v2.4)

subnet

p2p

To start off with the last one, topology p2p is hardly ever used anymore and was the
first method to assign a single IP address to a VPN client. However, it only works on
Linux and Unix derivatives, and hence was never very widely used.
Topology net30 is the current default. In this mode, OpenVPN sets up a
Point-to-Point network interface for each client (and for the server) and it assigns
a /30 subnet to each. This means that the server and each client are assigned a
block of four IP addresses. In the server configuration file, the server 10.200.0.0
255.255.255.0 was specified. With topology net30, this causes OpenVPN to
assign the following IP blocks:

The OpenVPN server is assigned from 10.200.0.0 to 10.200.0.3.

The first client is assigned from 10.200.0.4 to 10.200.0.7.

The second client is assigned from 10.200.0.8 to 10.200.0.11 and so on.


Each /30 subnet consist of four addresses; for the first client, these
addresses are as follows:

10.200.0.4: This is the /30 subnet network address. Each subnet is


normally required to have such an address associated with it.

10.200.0.5: This is the virtual endpoint address. This address is


required for OpenVPN to function, but it cannot actually be used,
and is not even pingable.

[ 107 ]

Client/Server Mode with tun Devices

10.200.0.6: This is the client VPN IP address.

10.200.0.7: This is the /30 subnet broadcast address. Each subnet is


required to have such a broadcast address associated with it.

As you can see, this is not a very efficient method of assigning IP addressesfor
each VPN client, four IP addresses are assigned. For small VPN setups, this method
works fine, but this method does not scale for a server with more than 100 clients
connected.
To overcome this problem, the topology subnet mode was introduced. It allows
OpenVPN to assign a single IP address to all clients, which makes it much easier to
manage a large-scale VPN. There are some issues with server-side routing (for more
details, see the Routing and server-side routing section later in this chapter) that have
prevented this topology mode from becoming the default, but it is expected that as of
Version 2.4 this will be the default topology mode.

Adding extra security


The initial set of configuration files is a good starting point for a client/server
deployment. However, for a production-level system, we want to add more
security. Security can be enhanced in two ways:

By adding tls-auth keys

By checking the extended key usage attributes of the certificates used

Using tls-auth keys


In the client/server mode, OpenVPN will attempt to establish a TLS control channel
for each client that tries to connect. Setting up a TLS control channel is resource
consuming, which makes OpenVPN susceptible to denial-of-service attacks: an
attacker could launch a multitude of misconfigured clients that all try to connect to the
OpenVPN server. For each of these, the OpenVPN server would attempt to set up a
TLS connection, which will effectively lead to a denial of service for well-configured
clients. This is especially true when OpenVPN is running using proto udp (the
recommended default). UDP traffic is connectionless, which means that for each new
UDP packet that the server receives, it must verify if it is a valid OpenVPN packet.
To address this possible vulnerability, OpenVPN introduced an extra authentication
layer to the TLS control channel using the tls-auth option. This TLS authentication
must be done using a pre-shared key, as the server does not yet know if a valid client
is attempting to connect. The pre-shared keys used for this are the exact same keys as
the keys used in point-to-point mode, as described in Chapter 2, Point-to-point Mode.
[ 108 ]

Chapter 4

Generating a tls-auth key


To generate a tls-auth key, we use the same command as described in Chapter 2,
Point-to-point Mode:
[root@server]# openvpn --genkey --secret /etc/openvpn/movpn/ta.key

Just like the clients private key file, this file needs to be copied to each client using a
secure channel, or it needs to be included in a secure client configuration package:
[root@client]# cd /etc/openvpn/movpn
[root@client]# scp root@openvpnserver:/etc/openvpn/movpn/ta.key .

Checking certificate key usage attributes


When X.509 certificates are generated, special Extended Key Usage (EKU) attributes
can be added to the certificate. This allows us to specify a purpose for the certificate,
for example as a server-only certificate or a client-only certificate. Certificates used by
secure websites make use of the same EKU attributes.
The easy-rsa scripts and the ssladmin tool set the EKU attributes by default when
generating a server certificate or a non-server (client) certificate. To check the EKU
attributes of a certificate, use the following commands:
$ openssl x509 -text -noout -in server.crt | \
grep -C 1 Key Usage

X509v3 Extended Key Usage:


TLS Web Server Authentication
X509v3 Key Usage:
Digital Signature, Key Encipherment

This tells us that the server.crt certificate can be used only for server
authentication.
Older certificates may not have these EKU attributes set, but instead use the
(deprecated) Netscape Cert Type attribute. The easy-rsa scripts and the
ssladmin tool set this attribute as well:
$ openssl x509 -text -noout -in server.crt | \
grep -C 1 Netscape Cert
Netscape Cert Type:
SSL Server
[ 109 ]

Client/Server Mode with tun Devices

However, this certificate can only be set for server-side certificates.


OpenVPN security can be increased by checking these attributes. For this, we use the
option remote-cert-tls.
The option remote-cert-tls client instructs the OpenVPN server to only allow
connections from VPN clients that have a certificate with the X.509 EKU attribute set
to TLS Web Client Authentication.
This prevents a hacker from setting up a rogue OpenVPN server using a client
certificate.
Similarly, for the client, the option remote-cert-tls server instructs the
OpenVPN client to only allow connections to a VPN server that has a certificate with
the X.509 EKU attribute set to TLS Web Server Authentication.
This prevents a malicious client from setting up a rogue OpenVPN server to attract
connections from other VPN users.
It is also possible to check for the Netscape Cert Type attribute. As this is an
attribute of the server certificate, the OpenVPN client needs to check this attribute
when connecting. For this, the option ns-cert-type server can be used.
Preferably, the option remote-cert-tls should be used.

Basic production-level configuration files


We extend the previous client and server configuration files to use the newly
created tls-auth key. We do this by adding a line to the configuration file
movpn-04-01-server.conf, as well as the second security-enhancing option:
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh
/etc/openvpn/movpn/dh2048.pem
ca
/etc/openvpn/movpn/movpn-ca.crt
cert
/etc/openvpn/movpn/server.crt

[ 110 ]

Chapter 4
key

/etc/openvpn/movpn/server.key

user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log

Note that the order of the statements in this configuration file is


random. The remote-cert-tls and tls-auth lines could have
been added at any point in the file.

This server configuration file is a basic server configuration file that we will reuse
throughout this chapter and others. Save it as basic-udp-server.conf so that we
can reuse it later.
We add two similar lines to the client configuration file movpn-04-01-client.conf:
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth /etc/openvpn/movpn/ta.key 1
ca
/etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/client1.crt
key /etc/openvpn/movpn/client1.key

Save it as basic-udp-client.conf.
The second parameter to the tls-auth option is the so-called direction of the key.
OpenVPN supports the use of directional keys, that is, different keys are used for
incoming versus outgoing data. This further enhances security. The direction flag
needs to be set to 0 on one end and to 1 on the other end. In the client/server mode,
this means that the server has the parameter 0 for the direction, and all clients have
the direction parameter set to 1.

[ 111 ]

Client/Server Mode with tun Devices

When we start the OpenVPN server, we can see that the TLS control channel is now
protected using a static key:
[root@server]# openvpn --config basic-udp-server.conf --suppresstimestamps
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL]
[PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Enter Private Key Password:
WARNING: this configuration may cache passwords in memory -- use the
auth-nocache option to prevent this
Control Channel Authentication: using /etc/openvpn/movpn/ta.key as a
OpenVPN static key file
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.1/24 broadcast 10.200.0.255
GID set to nobody
UID set to nobody
UDPv4 link local (bound): [undef]
UDPv4 link remote: [undef]
Initialization Sequence Completed

Similarly, when we start the OpenVPN client we see:


[root@client]# openvpn --config basic-udp-client.conf --suppresstimestamps
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL]
[PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Control Channel Authentication: using /etc/openvpn/movpn/ta.key as a
OpenVPN static key file
UDPv4 link local: [undef]
UDPv4 link remote: [AF_INET]openvpnserver:1194
[Mastering OpenVPN Server] Peer Connection Initiated with [AF_INET]
openvpnserver:1194
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.2/24 broadcast 10.200.0.255
Initialization Sequence Completed

[ 112 ]

Chapter 4

TCP-based configuration
The default protocol that OpenVPN uses is the UDP protocol. It is very simple
to create TCP-based versions based on the configuration files created previously.
In both client and server configuration files, change the line proto udp to proto
tcp. The entire TCP-based server configuration file is listed here:
proto tcp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh
/etc/openvpn/movpn/dh2048.pem
ca
/etc/openvpn/movpn/movpn-ca.crt
cert
/etc/openvpn/movpn/server.crt
key
/etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log

Save this configuration file as basic-tcp-server.conf.


Similarly, for the client configuration file:
client
proto tcp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth /etc/openvpn/movpn/ta.key 1
ca
/etc/openvpn/movpn/movpn-ca.crt
cert /etc/openvpn/movpn/client1.crt
key /etc/openvpn/movpn/client1.key

Save it as basic-tcp-client.conf.

[ 113 ]

Client/Server Mode with tun Devices

Configuration files for Windows


The basic configuration files for the Windows platform are slightly different from
the ones for the Linux/Unix or Mac OS platforms. On the Windows platform, the
Openvpn-GUI.exe wrapper is used, which expects that all configuration files are
stored in the directory C:\Program Files\OpenVPN\config or a subdirectory
thereof. The name of the directory Program Files may be different for other
languages. In all languages, the Windows environment variable %PROGRAMFILES%
will point to the proper location.
Thus, the basic UDP and TCP configuration files are actually slightly shorter.
Create the UDP client configuration file:
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth ta.key 1
ca
movpn-ca.crt
cert
client1.crt
key
client1.key

Save it as basic-udp-client.ovpn so that we can re-use it later in this book.


Similarly, create the client configuration:
client
proto tcp
remote openvpnserver.example.com
port 1194
dev tun
nobind
remote-cert-tls server
tls-auth ta.key 1
ca
movpn-ca.crt
cert
client1.crt
key
client1.key

Save it as basic-tcp-client.ovpn.

[ 114 ]

Chapter 4

Routing and server-side routing


A VPN is only truly useful when the VPN clients have access to server-side
resources. In order to access these resources, routing is needed in most cases.
OpenVPN has many options to automatically set up and tear down extra routes
whenever a client connects or disconnects.
It should be stated that most OpenVPN troubleshooting issues are related to routing.
Setting up a VPN connection is one thing, getting network traffic to flow properly is
another. This often has little to do with OpenVPN itself, but more with the routing
tables and firewall rules on both client and server side.
The most common layout for accessing resources on the server-side network is
depicted here:
Site B LAN:
192.168.122.0/24

Internet
/WAN
Client
tun0: 10.200.0.2

Server
VPN

tun0: 10.200.0.1

The server-side LAN is 192.168.122.0/24. The resources that the VPN clients need to
access are located on this subnet. Thus, the server needs to instruct the VPN clients
that an extra route needs to be set. This is done using a push option, where the route
configuration is pushed to the client. It could also be achieved by adding the route to
the client configuration file itself, but this does not scale well. This is because for each
new server-side network route, all client configuration files would need to be updated.
We start out with the basic-udp-server.conf file, and add one line:
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client

[ 115 ]

Client/Server Mode with tun Devices


tls-auth
dh
ca
cert
key

/etc/openvpn/movpn/ta.key 0
/etc/openvpn/movpn/dh2048.pem
/etc/openvpn/movpn/movpn-ca.crt
/etc/openvpn/movpn/server.crt
/etc/openvpn/movpn/server.key

user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
push route 192.168.122.0 255.255.255.0

We save it as movpn-04-03-server.conf and we start the OpenVPN server using


this configuration file. This time, we use a Windows 7 64-bit Professional machine
as the OpenVPN client, on which the X86_64 Version of OpenVPN 2.3.4-I004 is
installed. Copy over the following files to the Windows machine:

basic-udp-client.ovpn

movpn-ca.crt

client1.crt

client1.key

Take and place them in C:\Program Files\OpenVPN\config (or %PROGRAMFILES%\


config).
Launch the OpenVPN GUI application, select the configuration basic-udp-client
and click on Connect:

[ 116 ]

Chapter 4

Once the connection is successfully established, the OpenVPN GUI icon turns green
and connection information is shown when hovering over the icon:

We can now verify that the VPN connection to the server is working by opening a
command shell and pinging the server:

After we verify that we can reach the OpenVPN server, we need to ensure that the
OpenVPN server is forwarding IP traffic and we need to add an extra route on the
server side gateway to ensure that the VPN traffic is routed correctly back via the
VPN server. Without this route, the machines on the server-side network will now
know where the VPN traffic with IP addresses 10.200.0.0/24 is coming from,
and will most likely wrongly route or drop the packets:
[root@server]# sysctl -w net.ipv4.ip_forward=1
[router]# ip route add 10.200.0.0/24 via 192.168.122.1

[ 117 ]

Client/Server Mode with tun Devices

Now, we check the routing table on the client side, and we verify that we can reach a
machine on the server-side LAN:

The first part of the output shows that multiple routes for the VPN subnet
10.200.0.0/24 were added to the routing tables, including a route for the pushed
network 192.168.122.0/24. Note the last column in the output, which shows
the route metric. Windows calculates a metric (286 in this case), but this can be
overruled using the right route statements. The route added using push route
192.168.122.0 255.255.255.0 has a lower metric as the OpenVPN default metric
of 30 was specified.

Special parameters for the route option


Analogous to what is explained in Chapter 2, Point-to-point Mode the configuration
statement push route <network> <netmask> [vpn_gateway] [metric] is vital in
this setup. The route option accepts up to four parameters, two mandatory and two
optional. It is the third parameter which plays an important role in this setup. The
word vpn_gateway is a special OpenVPN keyword, and it specifies the VPN remote
endpoint address. Normally, this keyword does not have to be specified, unless it is
also necessary to specify the metric for this route.
The full syntax for the route statement is route <network> <netmask> [gateway]
[metric], where gateway can either be explicitly set as an IPv4 address or either of
the special keywords vpn_gateway or net_gateway can be used. If no gateway and
no metric are specified, then vpn_gateway is used.

[ 118 ]

Chapter 4

The keyword net_gateway is useful to specify a subnet that should explicitly not
be routed via the VPN. For net_gateway, the default gateway before the VPN
connection was established is substituted.
The metric has a default metric that can be set using route-metric m, which then
applies to all routes. If you wish to overrule the metric for a particular route (as we
have done in this example), then it is required to specify the gateway (vpn_gateway
in our case) followed by the metric for that particular route.

Masquerading
Sometimes, it is not possible to add a server-side route to redirect all VPN
traffic back to the OpenVPN server. In this case, a quick and dirty approach is
to use masquerading. On Linux, you can use the iptables command to set up
masquerading on the server:
[root@server]# iptables -t nat -I POSTROUTING -o eth0 \
-s 10.200.0.0/24 -j MASQUERADE

This iptables statement instructs the Linux kernel to rewrite all traffic that is
coming from the VPN subnet 10.200.0.0/24 and that is leaving the Ethernet
interface eth0. The traffic leaving the eth0 interface has its source address rewritten
so that it appears as if it is coming from the OpenVPN server itself and not from
the OpenVPN client. This is an easy shortcut to get routing to work, but the
disadvantage is that it is no longer possible to distinguish whether such traffic is
coming from the OpenVPN server itself, or from one of the connected clients.

Redirecting the default gateway


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 Internet cafe).
Redirecting the default gateway is achieved by adding the line push redirectgateway [def1 local bypass-dhcp bypass-dns] to the server configuration file.

[ 119 ]

Client/Server Mode with tun Devices

The parameters to redirect-gateway listed previously are optional, but they can
play a very important role:

No parameters added: In this case, OpenVPN will replace the existing default
gateway (0.0.0.0/0) with the address of the OpenVPN server itself. An extra
route to the OpenVPN server itself is also added so that the OpenVPN
traffic itself is sent directly to the server, instead of via the tunnel. The
disadvantage is that if the OpenVPN connection is stopped or breaks down,
the original default gateway is lost. This usually causes a full loss of network
connectivity.

Parameter def1: Instead of replacing the existing default gateway, OpenVPN


will add two new routes, 0.0.0.0/1 and 128.0.0.0/1. These routes together also
cover all IPv4 space, and are more specific (/1) than the regular gateway (/0).
Routing always takes place over the more specific routes, and thus all traffic
is sent over the VPN. The advantage of this trick is that the default gateway
is left intact. If the VPN connection is stopped, the original gateway can be
restored. Note that in this case, OpenVPN will add an explicit route to the
OpenVPN server itself, so the encrypted traffic itself will not be sent over the
tunnel.

Parameter bypass-dhcp: Sometimes, it is useful to add an explicit route to


the local DHCP server on the client-side LAN. This avoids DHCP renewals
to also be tunneled over the VPN, although in most network setups this does
not happen, as there usually is a more specific route to the network segment
on which the local DHCP server resides.

Parameter bypass-dns: Sometimes, it can be necessary to add an explicit


route to the local DNS server, as DNS resolution breaks down otherwise.
This happens only if you want to use the client-side DNS server, yet you
want to route all traffic over the tunnel.

Apart from the option redirect-gateway, we could also specify the option push
redirect-private [def1 local bypass-dhcp bypass-dns] to the server
configuration file. This option takes the same parameters as redirect-gateway, but
it does not change the existing default gateway at all. This can be useful for pushing
private subnets.
For now, we add push redirect-gateway def1 to the basic-udp-server.conf
configuration file. Save it as movpn-04-06-server.conf, start the OpenVPN server,
and reconnect the client using the default configuration file.

[ 120 ]

Chapter 4

After the connection is established, we verify that all traffic is now flowing via
the VPN using the traceroute command (use tracert -d in a command shell
on Windows):

The first hop in the traceroute output is 10.200.0.1, which is the IP address of the
OpenVPN server. This proves that traffic is flowing via the VPN by default.
The configuration option redirect-gateway 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 10.200.0.1 dev tun0
128.0.0.0/1 via 10.200.0.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 all the traffic for the OpenVPN server itself
would go through the tunnel otherwise.
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 advantage of this method is that the original default gateway is left intact.
When the VPN is disconnected, the original gateway address automatically takes
over again. If we would simply use redirect-gateway, there is a chance that the
default gateway is lost when the VPN is disconnected, resulting in a complete loss
of network connectivity.
The downside of this method is with Windows 7 and above clients: Windows
sometimes refuses to trust the TAP-Win adapter without a default route, and
therefore marks it as a public adapter. It is not possible to use a public adapter in
Windows 7 for file or printer sharing. We will see in the next chapter how to work
around this peculiarity.

[ 121 ]

Client/Server Mode with tun Devices

Client-specific configuration CCD files


In a setup where a single server can handle many clients, it is sometimes necessary
to set per-client options that overrule the global options, or to add extra options to a
particular client. The option client-config-dir is very useful for this. It allows the
VPN administrator to assign a specific IP address to a client, in order to push specific
options such as a DNS server to a particular client or to temporarily disable a client
altogether. This option is also vital if you want to route a subnet from the client side
to the server side, as we will see later on.
A client-config-dir or CCD file can contain the following options:

push: This is useful for pushing DNS and WINS servers, routes, and so on

push-reset: This is useful to overrule global push options

iroute: This is useful for routing IPv4 client subnets to the server

iroute-ipv6: This is useful for routing IPv6 client subnets to the server

ifconfig-push: This is useful for assigning a specific IPv4 address to

a client

ifconfig-ipv6-push: This is useful for assigning a specific IPv6 address

to a client

disable: This is useful for temporarily disabling a client altogether

config: This is useful for including another CCD configuration file

In order to use CCD files, we add a line to the basic-udp-server.conf


configuration file:
client-config-dir /etc/openvpn/movpn/clients

Save it as movpn-04-04-server.conf. Next, create the CCD directory and create a


CCD file in it for the client with certificate client1.crt:
[root@server]# mkdir -p /etc/openvpn/movpn/clients
[root@server]# echo ifconfig-push 10.200.0.99 255.255.255.0 \
> /etc/openvpn/movpn/clients/client1
[root@server]# chmod 755 /etc/openvpn/movpn/clients
[root@server]# chmod 644 /etc/openvpn/movpn/clients/client1

The name of the CCD file is based on the certificate subjects common name
(the /CN= part), as found in the client1.crt file:
$ openssl x509 -subject -noout -in client1.crt

[ 122 ]

Chapter 4
subject= /C=ZA/ST=Enlightenment/O=Mastering OpenVPN/CN=client1/
[email protected]

The filename needs to be just client1 with no extension in this case, not even
on Windows! If there are spaces present in the common name, then they need to
be converted to underscores (_). If the Windows Explorer is configured to hide
extensions for common file types, then it is easiest to open a command shell (cmd.
exe) window, and remove the extension using the following commands:
C:\> cd %PROGRAMFILES%\openvpn\config\clients
C:\> rename client1.txt client1,145.102.134.201:35519

Next, we start the OpenVPN server using this configuration file and we connect
the VPN client. The connection log shows that the client is assigned the address
10.200.0.99:
[root@client]# openvpn --config basic-udp-client.conf
OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL]
[PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Control Channel Authentication: using /etc/openvpn/movpn/ta.key as a
OpenVPN static key file
UDPv4 link local: [undef]
UDPv4 link remote: [AF_INET]openvpnserver:1194
[Mastering OpenVPN Server] Peer Connection Initiated with [AF_INET]
openvpnserver:1194
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 10.200.0.99/24 broadcast 10.200.0.255
Initialization Sequence Completed

The server-side log does not show any messages about picking up the CCD file when
using the default verbosity setting. Increase the verbosity setting to 5 or higher to
view whether the CCD file is processed:
<client-ip>:49299 [client1] Peer Connection Initiated with [AF_
INET]<client-ip>:49299
client1/<client-ip>:49299 OPTIONS IMPORT: reading client specific options
from: /etc/openvpn/movpn/clients/client1client1/<client-ip>:49299 MULTI:
Learn: 10.200.0.99 -> client1/<client-ip>:49299

[ 123 ]

Client/Server Mode with tun Devices

How to determine whether a CCD file is


properly processed
Troubleshooting whether a CCD file is correctly processed can be a bit tricky.
The following guidelines will aid in debugging CCD file issues:

Always specify the full path for the client-config-dir option.

Make sure the directory is accessible and the CCD file is readable to the
user which is used to run OpenVPN (nobody or openvpn in most cases;
in the configurations listed in this book, the user nobody is used).

Make sure that the right filename is used for the CCD file, without
any extensions.

If possible, add the option ccd-exclusive to the server configuration


file. This instructs OpenVPN to only allow client connections if there is a
particular CCD file for that client. If there was a problem reading the CCDfile for a particular client, then the client will also be denied access. This way,
you will know that your client-config-dir settings are misconfigured.

CCD files and topology net30


If you are using the (default) topology setting (topology net30), then the
ifconfig-push statement is slightly different. As each client is now assigned a /30
subnet, the ifconfig-push statement needs to specify a valid VPN /30 subnet.
The following rules apply:

Each /30 subnet needs to start at an address divisible by 4


(4, 8, 12, and so on)

The VPN local IP is the third address in this subnet

The virtual remote endpoint IP is the second address

For example, a valid IP address for a VPN client is 10.200.0.50:

The subnet is 10.200.0.48/32, where 48 is a multiple of 4

The VPN IP address is 50 (48+2 = 50)

The virtual remote endpoint is 49 (48 + 1 = 49)

The CCD file should now contain the following:


ifconfig-push 10.200.0.50 10.200.0.49

[ 124 ]

Chapter 4

Client-side routing
Sometimes, it is useful to allow the VPN server (or other VPN clients) to access
resources connected to a particular client. This is known as client-side routing.
Client-side routing in OpenVPN requires a CCD file for that client containing an
iroute statement. It also requires a corresponding route statement in the OpenVPN
server configuration file.
Consider the following network layout:
Site A LAN:
192.168.4.0/24

Site B LAN:
192.168.122.0/24

Internet
/WAN
Client
tun0: 10.200.0.99

Server
VPN

tun0: 10.200.0.1

The subnet 192.168.4.0/24 needs to be accessible from the server-side LAN and the
server-side subnet 192.168.122.0/24 needs to be accessible from the client-side LAN.
This can be achieved as follows:
1. Add two lines to the basic-udp-server.conf configuration file:
client-config-dir /etc/openvpn/movpn/clients
route 192.168.4.0 255.255.255.0 10.200.0.1

Save it as movpn-04-05-server.conf.
2. Create a CCD file client1 in the directory /etc/openvpn/movpn/clients
with contents:
ifconfig-push 10.200.0.99 255.255.255.0
iroute 192.168.4.0 255.255.255.0
push route 192.168.122.0 255.255.255.0

3. Ensure that IP traffic forwarding is enabled and allowed on both client and
server:
[root@client]# sysctl -w net.ipv4.ip_forward=1
[root@server]# sysctl -w net.ipv4.ip_forward=1

[ 125 ]

Client/Server Mode with tun Devices

4. Start the OpenVPN server using the configuration file


movpn-04-05-server.conf.
5. Connect the client using the default configuration file
basic-udp-client.conf.
6. After the connection has been established, we verify that both subnets
can reach each other using ping:
[root@client]# ping -c 3 192.168.122.184
PING 192.168.122.184 (192.168.122.184) 56(84) bytes of data.
64 bytes from 192.168.122.184: icmp_seq=1 ttl=63 time=3.29 ms
64 bytes from 192.168.122.184: icmp_seq=2 ttl=63 time=3.27 ms
64 bytes from 192.168.122.184: icmp_seq=3 ttl=63 time=3.31 ms

--- 192.168.122.184 ping statistics --3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 3.277/3.296/3.317/0.016 ms

[root@server]# ping -c 3 192.168.4.10


PING 192.168.4.10 (192.168.4.10) 56(84) bytes of data.
64 bytes from 192.168.4.10: icmp_seq=1 ttl=63 time=6.31 ms
64 bytes from 192.168.4.10: icmp_seq=2 ttl=63 time=5.07 ms
64 bytes from 192.168.4.10: icmp_seq=3 ttl=63 time=5.14 ms

--- 192.168.4.10 ping statistics --3 packets transmitted, 3 received, 0% packet loss, time 2007ms
rtt min/avg/max/mdev = 5.073/5.512/6.317/0.575 ms

In-depth explanation of the client-config-dir


configuration
In the first step, we add two new lines to the server configuration file. These lines set
up client-config-dir, and they instruct OpenVPN to add a system network route
for the subnet 192.168.4.0/24. We need to explicitly specify the gateway address
10.200.0.1 here, due to a minor bug in OpenVPN. This shortcoming is expected
to be resolved in Version 2.4, after which you can specify route 192.168.4.0
255.255.255.0 again.
[ 126 ]

Chapter 4

The contents of the CCD file instruct OpenVPN that when the client with Common
Name client1 connects the IP address for this client is to be set to 10.200.0.99.
Furthermore, OpenVPN needs to set an internal route (iroute) for this client so
that OpenVPN itself is aware that the subnet 192.168.4.0/24 is located behind this
particular client.
Finally, the push route statement instructs OpenVPN to push a route for this
particular subnet to client client1. This way, an OpenVPN server can push different
routes to different clients in a transparent manner.
Selectively pushing a route to a particular client can be handy, but it is
not tamper-proof. A rogue VPN client that adds a route to this subnet
by itself will also have access to it. If you need to control access to a
particular subnet, use a firewalling solution such as iptables or ipfw.

This example shows the flexibility of the OpenVPN configuration options.


Without having to change a single line in the client configuration file, it is possible
to assign a different IP address, route a particular subnet to a client, or route a
particular subnet from the client-side network to the server-side LAN.

Client-to-client traffic
OpenVPN also allows you to set up client-to-client traffic. By default, the VPN
clients are not allowed to communicate directly with each other. This is a good
security measure, but sometimes it is necessary to allow inter-client traffic. Be aware
that all VPN client-to-client traffic will flow via the OpenVPN server: from client1
to the VPN server and then again from the VPN server to client 2, and vice versa.
This can easily lead to performance issues.
In tun mode, client-to-client connectivity can be achieved using either iptables or
by using the OpenVPN option client-to-client. The option client-to-client
has the advantage that it is faster: traffic from one client arriving at the server is
automatically forwarded to the second client, without passing through the system
routing tables or firewalling rules. The downside is that it is hard to monitor the
traffic, and it is impossible to apply access control.
Without the client-to-client option, the traffic from one client is received by the
OpenVPN server, forwarded out to the system routing and firewalling tables, and
(if configured correctly) bounced back to the OpenVPN server again. The server then
forwards it out to the second client.

[ 127 ]

Client/Server Mode with tun Devices

If other VPN clients need to access the subnet 192.168.4.0/24 as specified in the
preceding example, then the server configuration needs to be extended with a line:
push 192.168.4.0 255.255.255.0

This instructs the OpenVPN server to push a route to all clients that subnet
192.168.4.0/24 is reachable through the VPN tunnel, except for client client1.
The client client1 itself is excluded due to the matching iroute entry.

The OpenVPN status file


OpenVPN offers several options to monitor the clients connected to a server.
The most commonly used method is using a status file. The OpenVPN status
file is continually updated by the OpenVPN process and contains the following
information:

Which clients are connected

From which IP address the clients are connecting

The number of bytes each client has received and transferred

The time at which the client connected

In addition, the routing table also shows which networks are routed
to each client

We modify the client-side routing server configuration file movpn-04-05server.conf by adding a line to the server configuration:
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
remote-cert-tls client
tls-auth /etc/openvpn/movpn/ta.key 0
dh
/etc/openvpn/movpn/dh2048.pem
ca
/etc/openvpn/movpn/movpn-ca.crt
cert
/etc/openvpn/movpn/server.crt
key
/etc/openvpn/movpn/server.key

[ 128 ]

Chapter 4
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
client-config-dir /etc/openvpn/movpn/clients
route 192.168.4.0 255.255.255.0 10.200.0.1
status /var/run/openvpn.status 3

Save it as movpn-04-07-server.conf. After re-establishing the VPN connection,


we then see the following contents in the status file, after the VPN client client1
has connected and has transferred some data:
OpenVPN CLIENT LIST
Updated,Tue Oct 21 15:45:27 2014
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
client1,<client-IP>:35519,7730,9342,Tue Oct 21 15:44:35 2014
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
192.168.4.0/24,client1,145.102.134.201:35519,Tue Oct 21 15:44:35 2014
10.200.0.99,client1,145.102.134.201:35519,Tue Oct 21 15:44:35 2014
GLOBAL STATS
Max bcast/mcast queue length,0
END

The CLIENT LIST shows the list of connected clients, including information about
the number of bytes received and bytes sent.
The ROUTING TABLE shows the list of OpenVPN internal routes:

The subnet 192.168.4.0/24 is routed to client1 due to the iroute statement


in the server configuration

The IP address 10.200.0.99 is the IP address of client1 which we set


explicitly in the CCD file named client1

When the client disconnects, the status file is updated after 3 seconds, and the
connected client is no longer listed.

[ 129 ]

Client/Server Mode with tun Devices

When a client disconnects, all information is removed from the status file
and all statistics are reset. If the client connects again later, the number
of received and sent bytes starts again from zero. The client-disconnect
script is given all the status info when a client has been disconnected.

The second parameter to the status option is the interval after which the status file
is updated (rewritten). The default value is 60 seconds.

Reliable connection tracking for UDP mode


The OpenVPN server cannot immediately detect when using the UDP protocol
that a client is disconnected, either on purpose or due to a bad internet connection.
This allows a client to reconnect to the VPN server without losing all tunneled
connections in case of a bad connection. The downside is that it takes some time for
the OpenVPN server to realize that a client is gone.
An OpenVPN client can explicitly notify the server that it is disconnecting using the
option explicit-exit-notify. This option takes one parameter that specifies the
number of explicit messages that the client attempts to send to the server. The default
value is 1, which does not work well if the underlying network connection itself is
unstable. In that case it is recommended to increase this value to 3.
When explicit-exit-notify is used, the OpenVPN server immediately receives
a remote-exit message when the client disconnects, as can be seen in the server
log file:
SIGTERM[soft,remote-exit] received, client-instance exiting

Note that this problem does not occur when proto tcp is used, as the termination
of a TCP connection is immediately noticed by the server.

The OpenVPN management interface


One of the most powerful but less well-known options of OpenVPN is the
management interface. The management interface is available on both the server
side and the client side. On the server side, it can be used to collect statistics, monitor
and control the connected clients, and perform other management related tasks. On
the client side, it can be used to query for passwords, enter proxy information for
establishing a connection with the VPN server, interact with a PKCS #11 device, and
collect client-side statistics.

[ 130 ]

Chapter 4

The OpenVPN plugin for the Linux NetworkManager makes extensive use of the
management interface to control the startup and shutdown of the VPN connection.
To use the management interface, add a line management 127.0.0.1 23000 stdin
to either the client or the server configuration file. This option instructs OpenVPN
to set up the management interface on IP address 127.0.0.1, port 23000, and to use
stdin to specify the management password.
If we add this to the basic-udp-server.conf configuration file and launch
the OpenVPN server, then OpenVPN will first query us for the management
password to use:

We can then use telnet to log in on the management interface (user input is listed
in boldface):
[root#server]# telnet 127.0.01 23000
Trying 127.0.0.1...
Connected to 127.0.01.
Escape character is ^].
ENTER PASSWORD:[password]
SUCCESS: password is correct
>INFO:OpenVPN Management Interface Version 1 -- type help for more
info
help
Management Interface for OpenVPN 2.3.2 x86_64-redhat-linux-gnu [SSL
(OpenSSL)]
[LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Sep 12 2013
Commands:
auth-retry t
: Auth failure retry mode
(none,interact,nointeract).
bytecount n
: Show bytes in/out, update every n secs
(0=off).

[ 131 ]

Client/Server Mode with tun Devices


echo [on|off] [N|all]
exit|quit
forget-passwords
help
[...]
END

: Like log, but only show messages in echo


buffer.
: Close management session.
: Forget passwords entered so far.
: Print this message.

This raw telnet interface can be used to view the status of the server, providing the
same output as the option status from the previous example. It can also be used to
terminate a client connection immediately, using the following command:
kill client1

This will cause client client1 one to be disconnected. Note that in most cases
the client will automatically attempt to reconnect. Now, type exit to end the
telnet session.
The management interface can be used to control OpenVPN in many different ways
(adapted from the OpenVPN manual page https://community.openvpn.net/
openvpn/wiki/Openvpn23ManPage):

management IP port [pw-file]: Enable a TCP server on IP:port to


handle daemon management functions. pw-file, if specified, is a password
file (password on first line) or stdin to prompt from standard input. The

password provided will set the password which TCP clients will need to
provide in order to access management functions.
The management interface can also listen on a Unix domain socket, if
supported. To use a domain socket, specify the Unix socket pathname in
place of IP and set port to unix.

The management interface provides a special mode where the TCP


management link can operate over the tunnel itself. To enable this mode, set
IP = tunnel. Tunnel mode will cause the management interface to listen
for a TCP connection on the local VPN address of the TUN/TAP interface.

management-client: The management interface will connect as a TCP/


Unix domain client to IP:port specified by --management rather than listen

as a TCP server or on a Unix domain socket. If the client connection fails to


connect or is disconnected, a SIGTERM signal will be generated, and cause
OpenVPN to quit.

management-query-passwords: This is the query management channel for


private key password and --auth-user-pass username/password.

[ 132 ]

Chapter 4

management-hold: Start OpenVPN in a hibernating state, until a client of the

management-signal: Send SIGUSR1 signal to OpenVPN if management

management-client-auth: This gives management interface client


the responsibility to authenticate clients after their client certificate has
been verified.

management interface explicitly starts it with the hold release command.

session disconnects. This is useful when you wish to disconnect an OpenVPN


session on user logoff.

Session key renegotiation


To ensure the security of each OpenVPN connection, the server periodically
renegotiates the secret key for the data channel with each client. This is controlled
using three options:

reneg-sec N: Renegotiate data channel key after N seconds (default is 3600)

reneg-bytes N: Renegotiate data channel key after N bytes (default=0=off)

reneg-pkts N: Renegotiate data channel key after N packets (default=0=off)

If a VPN client is experiencing periodic timeouts when connected to the server, it is


often useful to vary these parameters. If you set the reneg-sec parameter at a very
short interval, however, the performance of the VPN will be severely degraded.
The reneg options can be specified on either the client or the server side, or both. The
reneg option that runs the most frequently on either side will reset the counters on
both ends. If the server specifies reneg-sec 500 but the client specifies reneg-sec
60, then the data channel renegotiation will occur approximately every 60 seconds.
We create an example by adding three lines to the basic-udp-server.conf
configuration file:
reneg-sec
10
reneg-pkts 1000
reneg-bytes 1000000

We save the configuration as movpn-04-09-server.conf and re-establish the VPN


connection. The server log will now contain many lines stating TLS: soft reset:
Tue Oct 21 16:53:29 2014 <IP>:41679 [client1] Peer Connection Initiated
with [AF_INET]<IP>:41679
[...]

[ 133 ]

Client/Server Mode with tun Devices


Tue Oct 21 16:53:39 2014 client1/<IP>:41679 TLS: soft reset sec=0
bytes=0/100000 pkts=0/100
[...]
Tue Oct 21 16:53:49 2014 client1/<IP>:41679 TLS: soft reset sec=0
bytes=53/100000 pkts=1/100
[...]
Tue Oct 21 16:53:59 2014 client1/<IP>:41679 TLS: soft reset sec=0
bytes=105/100000 pkts=2/100

With the option reneg-sec 10 set we see from the server log timestamps that the
data channel key is renegotiated every 10 seconds.
On the client side, we can also see the impact this key renegotiation has on the
performance of the VPN connection. By letting a simple ping command run after the
connection has come up, we can see when the key renegotiation is happening based
on the spikes in the ping response times:
[client]$ ping 10.200.0.1
PING 10.200.0.1 (10.200.0.1) 56(84) bytes of data.
64 bytes from 10.200.0.1: icmp_seq=1 ttl=64 time=3.29 ms
64 bytes from 10.200.0.1: icmp_seq=2 ttl=64 time=3.55 ms
64 bytes from 10.200.0.1: icmp_seq=3 ttl=64 time=61.6 ms
64 bytes from 10.200.0.1: icmp_seq=4 ttl=64 time=16.6 ms
64 bytes from 10.200.0.1: icmp_seq=5 ttl=64 time=3.23 ms
64 bytes from 10.200.0.1: icmp_seq=6 ttl=64 time=3.22 ms
64 bytes from 10.200.0.1: icmp_seq=7 ttl=64 time=3.74 ms
64 bytes from 10.200.0.1: icmp_seq=8 ttl=64 time=3.25 ms
64 bytes from 10.200.0.1: icmp_seq=9 ttl=64 time=3.21 ms
64 bytes from 10.200.0.1: icmp_seq=10 ttl=64 time=3.26 ms
64 bytes from 10.200.0.1: icmp_seq=11 ttl=64 time=3.26 ms
64 bytes from 10.200.0.1: icmp_seq=12 ttl=64 time=3.55 ms
64 bytes from 10.200.0.1: icmp_seq=13 ttl=64 time=3.27 ms
64 bytes from 10.200.0.1: icmp_seq=14 ttl=64 time=3.26 ms
64 bytes from 10.200.0.1: icmp_seq=15 ttl=64 time=3.31 ms
64 bytes from 10.200.0.1: icmp_seq=16 ttl=64 time=3.28 ms
64 bytes from 10.200.0.1: icmp_seq=17 ttl=64 time=77.1 ms
...

The same thing will happen when the packet or byte boundary is crossed, at which
moment the data channel keys will also be renegotiated.

[ 134 ]

Chapter 4

A note on PKCS#11 devices


Especially when using PKCS#11 devices, the key renegotiation can be
cumbersome. Some PKCS#11 devices put a heavy penalty on key renegotiation,
causing the renegotiation process to take several seconds. During this time the
VPN is unresponsive.
Setting the reneg-sec value to 0 will effectively disable key renegotiation, but this
makes the VPN itself susceptible to man-in-the-middle and timing attacks, rendering
the extra security of using a hardware security device useless.

Using IPv6
With OpenVPN 2.3 came solid support for IPv6, both within the OpenVPN tunnel
as well as for transit of the tunnel itself. OpenVPN all the way back to 1.x had
rudimentary support for IPv6, which was largely rewritten. Overall, inside an
OpenVPN tunnel an administrator can choose to support Ethernet (layer 2), IPv4
(layer 3), and IPv6 (layer 3).
The diagram illustrates the logical relationship of the transit network path and the
protected network path. Only a single transit method needs to be used, and a single
OpenVPN configuration can contain both IPv4 and IPv6 --remote entries. All traffic,
regardless of type, will be protected within the tunnel. It is perfectly acceptable
to have an all-IPv6 tunnel, using IPv6 for both transit and protected traffic. With
additional routing and proxying, its even possible to use OpenVPN to aid in IPv6 to
IPv4 translation.
VPN TRANSIT-IPv4 or IPv6

Ipv6 Protected Traffic

VPN Tunnel
Ipv4 Protected Traffic

[ 135 ]

Client/Server Mode with tun Devices

Protected IPv6 traffic


Building on the examples from the previous section, we can provide IPv6 addresses
to clients and protect that traffic within the tunnel. To do this, we add a --serveripv6 option to our server configuration. This operates similarly to the --server
directive, only for IPv6 instead of IPv4 and takes an IPv6 network address and
netmask as arguments. Like --server, --server-ipv6 is a macro for other options
that can be passed individually: --ifconfig-ipv6, --ifconfig-ipv6-pool, --tunipv6, and push tun-ipv6.
Just like with IPv4, IPv6 routes can be pushed from the main server configuration or
from per-client configuration files in your client-config directory. In this example,
however, we will simply push a default route for all IPv6 traffic.
There is not currently a redirect-gateway option in OpenVPN for IPv6. Routes are
added similar to IPv6, with the keyword route-ipv6 instead of route.
Now, modify the movpn-04-01-server.conf file, and add the --server-ipv6
directive:
proto udp
port 1194
dev tun
server 10.200.0.0 255.255.255.0
server-ipv6 2001:DB8:100::/64
push route-ipv6 ::/0
topology subnet
persist-key
persist-tun
keepalive 10 60
dh
ca
cert
key

/etc/openvpn/movpn/dh2048.pem
/etc/openvpn/movpn/movpn-ca.crt
/etc/openvpn/movpn/server.crt
/etc/openvpn/movpn/server.key

user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log

[ 136 ]

Chapter 4

Once the file has been saved, a restart of the OpenVPN server process is required.
If the process started correctly with the new option, you should see something like
this in your log file:
IFCONFIG POOL IPv6: (IPv4) size=252, size_ipv6=65536, netbits=64,
base_ipv6=2001:db8:100::1000

At this point, clients are able to pass traffic using IPv6 inside the tunnel,
and the server is pushing a default route to clients for IPv6. Adding the server
configuration options requires no additional corresponding options within the
client configurations.
A connected client will show both an IPv4 and IPv6 address on the tunX interface.
Heres a FreeBSD example:
utun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1331
inet 10.200.0.2 --> 10.200.0.2 netmask 0xffffff00
inet6 fe80::5ab0:35ff:fef5:811f%utun1 prefixlen 64 scopeid 0x9
inet6 2001:db8:100::1001 prefixlen 64
nd6 options=1<PERFORMNUD>

Heres a Windows 7 example:

[ 137 ]

Client/Server Mode with tun Devices

Note that the popup from hovering over the task bar icon doesnt display the IPv6
address, but the ipconfig command from a terminal does show both addresses.

Using IPv6 as transit


OpenVPN doesnt currently have the ability to listen on both IPv4 and IPv6
addresses at the same time, but most modern kernels can handle this for you with
IPv6-mapped addresses. What this does is takes a Version 4 IP, such as 192.168.200.4
and maps it as the IPv6 address of ::ffff:192:168.:200:.:4. Also, instead of proto udp,
the protocol will be udp6 on both the client and the server.
After changing the proto statement from our sample config, client2 is initialized
and we can see the address are assigned. Both the OpenVPN server v4 and v6
addresses can be pinged and we can confirm that the transit over the tunnel is via
IPv6 with tcpdump.
Heres the client tun interface:
ecrist@phillip:~-> ifconfig tun4
tun4: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
inet6 fe80::216:3eff:fe09:5d4e%tun4 prefixlen 64 scopeid 0x9
inet 10.200.0.2 --> 10.200.0.2 netmask 0xffffff00
inet6 2001:db8:100::1000 prefixlen 64
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
Opened by PID 45391

Heres the IPv4 inside tunnel ping:


ecrist@phillip:~-> ping -c 1 10.200.0.1
PING 10.200.0.1 (10.200.0.1): 56 data bytes
64 bytes from 10.200.0.1: icmp_seq=0 ttl=64 time=0.490 ms
--- 10.200.0.1 ping statistics --1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.490/0.490/0.490/0.000 ms

[ 138 ]

Chapter 4

Heres the IPv6 inside tunnel ping:


ecrist@phillip:~-> ping6 -c 1 2001:db8:100::1
PING6(56=40+8+8 bytes) 2001:db8:100::1000 --> 2001:db8:100::1
16 bytes from 2001:db8:100::1, icmp_seq=0 hlim=64 time=0.591 ms

--- 2001:db8:100::1 ping6 statistics --1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.591/0.591/0.591/0.000 ms

Heres the tcpdump output (note the IPv6 keyword in the output):
root@terrance:/usr/local/etc/openvpn-> tcpdump -i xn0 host
2001:db8:5555:5555::1
tcpdump: verbose output suppressed, use -v or -vv for full protocol
decode
listening on xn0, link-type EN10MB (Ethernet), capture size 65535 bytes
19:14:05.449553 IP6 phillip.1194 > terrance.1194: UDP, length 53
19:14:05.449692 IP6 terrance.1194 > phillip.1194: UDP, length 53
19:14:08.389222 IP6 phillip.1194 > terrance.1194: UDP, length 93
19:14:08.389394 IP6 terrance.1194 > phillip.1194: UDP, length 93
19:14:09.389858 IP6 phillip.1194 > terrance.1194: UDP, length 93

Advanced configuration options


The next few sections illustrate some advanced configuration options. It is suggested
you fully understands the impact to their network before deploying these in a
production environment. These options are rarely used, but can be extremely
beneficial in the right circumstances.

Proxy ARP
It is often desirable to make VPN clients appear as if they are part of the serverside network. This makes it easier to browse folders and share files and printers. To
achieve this purpose, many setups resort to Ethernet bridging (see Chapter 6, Client/
Server Mode with tap Devices), which has its own drawbacks. The performance of a
bridged configuration can be much lower compared to a nonbridged setup.

[ 139 ]

Client/Server Mode with tun Devices

When the OpenVPN server runs on Linux or Unix, there is an alternative solution:
most Unix kernels have Proxy ARP capabilities, which can be used to assign an
OpenVPN client with an IP address on the server-side LAN, and make it appear
as if it is part of that LAN. Note that this works only for IPv4 networks, as IPv6
networking does not use ARP.
Consider the following network layout:
Site B LAN:
192.168.3.0/24

Internet
/WAN
Client
tun0: 192.168.3.34

Server
VPN

tun0: 192.168.3.33

In this layout, the standard VPN subnet 10.200.0.0/24 cannot be used, as we have
to integrate the VPN clients into the existing subnet, which for this example is
192.168.3.0/24. Current machines in this subnet are in the range 192.168.3.10 192.168.3.24, thus we place the VPN addresses a little outside of this range. Make
sure that the VPN addresses should not be advertised by a DHCP server on the
server-side LAN, as we want OpenVPN to assign the addresses for the VPN clients.
For this example, we will make use of the OpenVPN capability to run scripts when
a client connects or disconnects. The scripting abilities of OpenVPN are explained in
more detail in Chapter 7, Scripting and Plugins.
1. We start out with the following server configuration file:
proto udp
port 1194
dev tun
server 192.168.3.32 255.255.255.224
push route 192.168.3.0 255.255.255.0
topology subnet
persist-key
persist-tun
keepalive 10 60
tls-auth /etc/openvpn/movpn/ta.key 0

[ 140 ]

Chapter 4
dh
ca
cert
key

/etc/openvpn/movpn/dh2048.pem
/etc/openvpn/movpn/movpn-ca.crt
/etc/openvpn/movpn/server.crt
/etc/openvpn/movpn/server.key

verb 3
daemon
log-append /var/log/openvpn.log
script-security 2
client-connect
/etc/openvpn/movpn/proxyarp-connect.sh
client-disconnect /etc/openvpn/movpn/proxyarp-disconnect.sh

Note that we have added three statements to set the security level for the
scripts, and to run a custom script whenever a client connects or disconnects.
2. Save this configuration file as movpn-04-10-server.conf.
3. Next, create the proxyarp-connect.sh script that is executed each time a
VPN client connects:
#!/bin/bash
/sbin/arp -i eth0 -Ds ${ifconfig_pool_remote_ip} eth0 pub
/sbin/ip route add ${ifconfig_pool_remote_ip}/32 dev tun0

4. Save the script as /etc/openvpn/movpn/proxyarp-connect.sh. The


script location must match the absolute path specified in the movpn-04-10server.conf file.
5. Then, create the proxyarp-disconnect.sh script that is executed when the
client disconnects:
#!/bin/bash
/sbin/arp -i eth0 -d ${ifconfig_pool_remote_ip}
/sbin/ip route del ${ifconfig_pool_remote_ip}/32 dev tun0

6. Save the script as /etc/openvpn/movpn/proxyarp-disconnect.sh.


The device names eth0 and tun0 are hardcoded into the scripts.
This is necessary as the device on which the extra ARP address
needs to be published is unknown to OpenVPN. It is also possible to
publish the extra ARP address on multiple interfaces (eth0, eth1,
wlan0, and so on) by duplicating the /sbin/arp line in both scripts.

[ 141 ]

Client/Server Mode with tun Devices

Make both scripts executable, and launch the OpenVPN server using the
following commands:
[root@server]# chmod a+x /etc/openvpn/movpn/proxyarp-connect.sh
[root@server]# openvpn --config movpn-04-10-server.conf

7. As always, use the basic-udp-client.conf (or basic-udp-client.


ovpn) configuration file to connect to the server. After the VPN client has
successfully connected, we verify that the client is seen by other devices
on the LAN. For this, we used an Android smart phone with the app
Fing installed:

No extra network routes were added on the Android device.


The VPN client is truly integrated into the existing subnet.

8. We can also verify that the OpenVPN server machine is now publishing an
extra IP address in its ARP tables:
[server]$ /sbin/arp -an | grep PERM
? (192.168.3.34) at * PERM PUP on eth0

How does Proxy ARP work?


Proxy ARP is a feature supported by most Unix and Linux kernels. It is used most
often for connecting dial-in clients to a LAN, and nowadays also by ADSL and cable
Internet providers.
[ 142 ]

Chapter 4

The OpenVPN server borrows an IP address from its local LAN range when a client
connects. This IP address is then assigned to this OpenVPN client. The server also
creates a special entry in the systems ARP tables to tell the rest of site Bs LAN
that the OpenVPN server acts as a proxy for IP 192.168.3.34. This means that when
another machine on the server-side LAN wants to know where to find the host with
IP 192.168.3.34 then the OpenVPN server will respond with its own MAC address of
the interface on which the Proxy ARP address was published.
The server configuration file contains a few statements that need some explanation:
server 192.168.3.32 255.255.255.224
push route 192.168.3.0 255.255.255.0

The preceding lines cause the OpenVPN server to assign the address 192.168.3.33 to
the server VPN IP address, with a netmask of 255.255.255.224 (or /27). The first VPN
client is assigned the address 192.168.3.34/27. However, this means that the VPN
client itself cannot reach any IP addresses outside of this range. The push route
statement is needed to tell the OpenVPN client that the entire subnet 192.168.3.0/24
is reachable via the VPN.
So far, the server configuration file normally included the following lines:
user nobody
group nobody

In this configuration file, they are absent because the client-connect and
client-disconnect scripts need to run as user root. An alternative approach is
to set up sudo rights so that the user nobody is allowed to execute the /sbin/arp
command with root privileges.
Finally, the lines:
script-security 2
client-connect /etc/openvpn/movpn/proxyarp-connect.sh
client-disconnect /etc/openvpn/movpn/proxyarp-disconnect.

Set up OpenVPNs scripting features. The first line sets the security level of
the scripts to 2, which means that certain environment variables are available
to the script.
The client-connect and client-disconnect lines both specify an absolute
path to the scripts to be executed.

[ 143 ]

Client/Server Mode with tun Devices

Assigning public IP addresses to clients


As a follow up to the Proxy ARP example, we will now look at how we can hand
out public IPv4 addresses to OpenVPN clients. Lets assume that the following set
of (example only) public IPv4 addresses is available to us:
Our public IPv4 network is 192.0.2.160/28, which gives us 16 addresses.
These addresses are used as follows:
IP address

Use

192.0.2.160

This is the subnets network address

192.0.2.161

This is used for the servers VPN IP address

192.0.2.162

Not available

192.0.2.163

Not available

192.0.2.164 - 192.0.2.170

This is available for VPN clients

192.0.2.171

This is the LAN address of the OpenVPN server itself

192.0.2.172

Not available

192.0.2.173

Not available

192.0.2.174

This is the router on the remote LAN

192.0.2.175

This is the network broadcast address

We now want to set up an OpenVPN server that is capable of handing out the
addresses 192.0.2.164 through 192.0.2.170, with the OpenVPN server itself at the
address 192.0.2.161:
1. First we create the server configuration file:
proto udp
port 1194
dev tun
mode server
tls-server
ifconfig 192.0.2.161 255.255.255.240
ifconfig-pool 192.0.2.164 192.0.2.170
push route 192.0.2.171 255.255.255.255 net_gateway
push route-gateway 192.0.2.174
push redirect-gateway def1
push topology subnet

[ 144 ]

Chapter 4
topology subnet
persist-key
persist-tun
keepalive 10 60
tls-auth
dh
ca
cert
key

/etc/openvpn/movpn/ta.key 0
/etc/openvpn/movpn/dh2048.pem
/etc/openvpn/movpn/movpn-ca.crt
/etc/openvpn/movpn/server.crt
/etc/openvpn/movpn/server.key

verb 3
daemon
log-append /var/log/openvpn.log
script-security 2
client-connect
/etc/openvpn/movpn/proxyarp-connect.sh
client-disconnect /etc/openvpn/movpn/proxyarp-disconnect.sh

2. Save this file as movpn-04-11-server.conf. We will reuse the proxyarpconnect.sh and proxyarp-disconnect.sh scripts from the previous
example. Create proxyarp-connect.sh that is executed each time a VPN
client connects:
#!/bin/bash
/sbin/arp -i eth0 -Ds ${ifconfig_pool_remote_ip} eth0 pub
/sbin/ip route add ${ifconfig_pool_remote_ip}/32 dev tun0

3. Save it as /etc/openvpn/movpn/proxyarp-connect.sh.
4. Then, create the proxyarp-disconnect.sh script that is executed when the
client disconnects:
#!/bin/bash
/sbin/arp -i eth0 -d ${ifconfig_pool_remote_ip}
/sbin/ip route del ${ifconfig_pool_remote_ip}/32 dev tun0

5. Save it as /etc/openvpn/movpn/proxyarp-disconnect.sh. Make both


scripts executable and launch the OpenVPN server:
[root@server]# chmod a+x /etc/openvpn/movpn/proxyarp-connect.sh[
[root@server]# openvpn --config movpn-04-11-server.conf

6. Use the basic configuration file to connect the OpenVPN client to the server.
The first client will be assigned the address 192.0.2.164.

[ 145 ]

Client/Server Mode with tun Devices

Check the IP address of the first client by browsing to https://www.whatismyip.


com.
The server configuration file is similar to the file movpn-04-10-server.conf with
the exception of this block:
mode server
tls-server
ifconfig 192.0.2.161 255.255.255.240
ifconfig-pool 192.0.2.164 192.0.2.170
push route 192.0.2.171 255.255.255.255 net_gateway
push route-gateway 192.0.2.174
push redirect-gateway def1
push topology subnet

Earlier in this chapter, it was explained that the macro server 10.200.0.0

255.255.255.0 expands as follows:


mode server
tls-server
push topology subnet

ifconfig 10.200.0.1 255.255.255.0


ifconfig-pool 10.200.0.2 10.200.0.254 255.255.255.0
push route-gateway 10.200.0.1

When handing out public IP addresses, we usually do not have the luxury of wasting
IPv4 addresses. The option topology subnet, which was introduced in OpenVPN
2.1, is really useful here.
After examining our public IPv4 space, we forsake the server statement and include
our own version of the ifconfig and ifconfig-pool options:

ifconfig 192.0.2.161 255.255.255.240: This specifies that the server

ifconfig-pool 192.0.2.164 192.0.2.170: This specifies that the pool of


available IP addresses for VPN clients ranges from 192.0.2.164 to 192.0.2.170
for a total of seven addresses. Note that an ifconfig-pool range needs to
be contiguous.

VPN IP address is 192.0.2.161/28.

If there are holes in a range then it is often easier to assign IP addresses


using a script, as we will learn in Chapter 7, Scripting and Plugins.

[ 146 ]

Chapter 4

push route 192.0.2.171 255.255.255.255 net_gateway: This route

to the LAN address of the VPN server needs to be explicitly pushed to the
clients. Normally, this route is added automatically by the OpenVPN client
to ensure that traffic that is intended for the OpenVPN server itself is not
injected into the tunnel again, which would cause a packet loop. With our
special ifconfig and ifconfig-pool setup, it is advisable to add an explicit
route to the LAN address of the OpenVPN server.

push route-gateway 192.0.2.174: route-gateway specifies the


gateway address that is used to direct all tunnel traffic to. Normally routegateway is equal to the VPN server IP address. In this case, it would only
cause a route hop, as the VPN server would immediately forward it to the
real gateway, 192.0.2.174, which is on the same subnet. Hence, we specify the
IP address of the LAN gateway.

push redirect-gateway def1: For an OpenVPN client to use the public

push topology subnet: Normally, the server macro takes care of this
push for us, but as we are not using the server macro here we must explicitly

address for all its traffic, it must route all traffic over the VPN tunnel.

push this option. If this option is omitted, then the server would be assigning
linear addresses (because it has a line topology subnet in its configuration),
yet the VPN clients would assume that they are assigned topology net30
addresses, which is the current default. The explicit push circumvents this
potential misconfiguration.

Summary
In this chapter, a wide variety of features and options of client/server mode with
tun devices were covered. We established a basic set of configuration files for both
the OpenVPN server and the client, for both the UDP and TCP protocol as means
of transport, and for both Windows and Linux/Unix clients. This set of basic
configuration files will be used throughout the rest of the book.
We discussed how to set up an OpenVPN server serving both IPv4 addresses and
IPv6 addresses. We covered server-side and client-side routing, including redirecting
all traffic over the VPN tunnel. We also saw how to hand out public IPv4 addresses
using OpenVPN.
In the next chapter, we will explore the advanced features that OpenVPN offers.
Also, in Chapter 6, Client/Server Mode with tap Devices, several options and examples
will be explained that are useful for tun mode as well.

[ 147 ]

Get more information Mastering OpenVPN

Where to buy this book


You can buy Mastering OpenVPN from the Packt Publishing website.
Alternatively, you can buy the book from Amazon, BN.com, Computer Manuals and most internet
book retailers.
Click here for ordering and shipping details.

www.PacktPub.com

Stay Connected:

You might also like