Mastering OpenVPN - Sample Chapter
Mastering OpenVPN - Sample Chapter
Mastering OpenVPN - Sample Chapter
ee
Sa
pl
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.
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.
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.
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.
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
[ 99 ]
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.
/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
[ 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 ]
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
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
value is 1194, but any valid and available port number can be used.
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
[ 103 ]
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
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
Restart the connection if a client does not respond within 120 seconds
(2 * 60 = 120)
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.
proto udp: This specifies the protocol to use. While this is the default
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 ]
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
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
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
Mac OS X
Tunnelblick or Viscosity
Linux
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:
[ 107 ]
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.
Chapter 4
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 .
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 ]
[ 110 ]
Chapter 4
key
/etc/openvpn/movpn/server.key
user nobody
group nobody
verb 3
daemon
log-append /var/log/openvpn.log
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 ]
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
[ 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 it as basic-tcp-client.conf.
[ 113 ]
Save it as basic-tcp-client.ovpn.
[ 114 ]
Chapter 4
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 ]
/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
basic-udp-client.ovpn
movpn-ca.crt
client1.crt
client1.key
[ 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 ]
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.
[ 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.
[ 119 ]
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.
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 ]
push: This is useful for pushing DNS and WINS servers, routes, and so on
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
a client
to a client
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 ]
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.
[ 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 ]
--- 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
--- 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
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.
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 ]
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.
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
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:
When the client disconnects, the status file is updated after 3 seconds, and the
connected client is no longer listed.
[ 129 ]
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.
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.
[ 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 ]
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):
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.
[ 132 ]
Chapter 4
[ 133 ]
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
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
VPN Tunnel
Ipv4 Protected Traffic
[ 135 ]
/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>
[ 137 ]
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.
[ 138 ]
Chapter 4
--- 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
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 ]
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
[ 141 ]
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
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
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 ]
Use
192.0.2.160
192.0.2.161
192.0.2.162
Not available
192.0.2.163
Not available
192.0.2.164 - 192.0.2.170
192.0.2.171
192.0.2.172
Not available
192.0.2.173
Not available
192.0.2.174
192.0.2.175
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
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 ]
Earlier in this chapter, it was explained that the macro server 10.200.0.0
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:
[ 146 ]
Chapter 4
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 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 ]
www.PacktPub.com
Stay Connected: