Road Warriors with OpenVPN

Introduction
Most of the guides on OpenVPN concentrate on describing a routed scenario which is certainly more efficient, but may or may not require less setup to get active because you will need to setup additional new routes for all machines in the private network to talk to the subnet where the VPN clients get forwarded to.

Also the gentoo network scripts have recently been updated with latest baselayout and now it's easier to setup some network settings, but mainly you need to be careful reading older guides.

The guide below sketches out how to setup a bridged openvpn system where essentially the external machine will be given a local IP address such that it appears as just another machine on the normal local private lan network (ie no routing changes required). This may be easier for small home/soho networks, but surely doesn't scale as well for bigger installations

This HOWTO will explain the process of adding road warriors to your network with OpenVPN and the Linux network bridging features. We will be using OpenVPN 2.0.6 in this HOWTO.

The following links are useful in understanding this setup:

* http://planet.gentoo.org/developers/rphillips/2005/05/13/openvpn_setup * http://forums.gentoo.org/viewtopic-t-233080-highlight-openvpn.html * Bridging * http://openvpn.net/index.php/open-source/documentation/howto.html o http://openvpn.net/index.php/open-source/documentation/howto.html#pki

Selecting the required kernel options
OpenVPN requires the TUN/TAP network drivers. We will need to enable this option either as a module or built-in the kernel. Also, network bridging requires another options to be enabled. You will have to enable these options on the server and every client (unless they're running Windows :(, in which case you won't have to recompile anything in the kernel. :P).

This brief guide assumes you're using an older 2.6-based kernel. In kernel 2.6.14 for example, the networking options is under the root level Networking-> menu. If you can't find an option, make sure you look in both places! If you're still using a 2.4 kernel, it isn't really hard to find either if I remember correctly. Please note that only the 'X' is the option you're looking for. :)

Exit menuconfig, saving the new configurations. You now need to rebuild your kernel. 2.6-based kernels
 * 1) cd /usr/src/linux
 * 2) make menuconfig
 * 1) cd /usr/src/linux
 * 2) make &amp;&amp; make modules_install

2.4-based kernels If you compiled any of the two options built-into the kernel, copy the new kernel to /boot and see you later! (reboot)
 * 1) cd /usr/src/linux
 * 2) make dep &amp;&amp; make bzImage modules modules_install

Downloading and installing OpenVPN
Simple: After that you should have the openvpn 2.0 stuff installed on your system.
 * 1) echo "net-misc/openvpn iproute2" >> /etc/portage/package.use
 * 2) emerge openvpn

Creating the SSL keys and certificates
OpenVPN can use either SSL certificates or a pre-shared secret key to authenticate it's clients. While the SSL-based security is much more effective, the pre-shared secret keys one is twice as simple. I don't recommend it to anyone setting up a serious VPN as it's much less secure. If someone steals the secret key, he/she will be able to read all traffic passing throught the VPN (Read: MITM). In addition to all live traffic, if an attacker has captured packets that have previously traversed the network, he or she will be able to decrypt those, as well. Static keys are recommended only to be used for non-permanent tests.

Using SSL keys/certificates
This is not actually so difficult, it's just a bunch of commands to type. Please also refer to the official HOWTO docs (the steps below are based on these docs) at: http://openvpn.net/index.php/open-source/documentation/howto.html#pki

First, some explanations. To determine if a client is allowed to connect to the server or not, OpenVPN checks if it has been signed with the CA certificate that signed the server certificate. So you may understand that using commercial certificates like Thawte's really isn't an option in our case! I suggest we start right away and get this all out of the way quickly. :)

First off, change to the dir with the Openvpn scripts to setup the keys easily

$ cd /usr/share/openvpn/easy-rsa/

We then must edit the basic parameters for the certificates. Edit the vars file (called vars.bat on Windows) and set the KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL parameters. Don't leave any of these parameters blank.

Next, initialize the PKI. On Linux/BSD/Unix:

. ./vars ./clean-all ./build-ca

The final command (build-ca) will build the certificate authority (CA) certificate and key by invoking the interactive openssl command:

ai:easy-rsa # ./build-ca Generating a 1024 bit RSA private key ............++++++  ...........++++++   writing new private key to 'ca.key' -  You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. -  Country Name (2 letter code) [KG]: State or Province Name (full name) [NA]: Locality Name (eg, city) [BISHKEK]: Organization Name (eg, company) [OpenVPN-TEST]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:OpenVPN-CA Email Address [me@myhost.mydomain]:

Note that in the above sequence, most queried parameters were defaulted to the values set in the vars or vars.bat files. The only parameter which must be explicitly entered is the Common Name. In the example above, I used "OpenVPN-CA". Generate certificate & key for server

Next, we will generate a certificate and private key for the server. On Linux/BSD/Unix:

./build-key-server server

As in the previous step, most parameters can be defaulted. When the Common Name is queried, enter "server". Two other queries require positive responses, "Sign the certificate? [y/n]" and "1 out of 1 certificate requests certified, commit? [y/n]".

Generating client certificates is very similar to the previous step. On Linux/BSD/Unix:

./build-key client1 ./build-key client2 ./build-key client3

If you would like to password-protect your client keys, substitute the build-key-pass script.

Remember that for each client, make sure to type the appropriate Common Name when prompted, i.e. "client1", "client2", or "client3". Always use a unique common name for each client. Generate Diffie Hellman parameters

Diffie Hellman parameters must be generated for the OpenVPN server. On Linux/BSD/Unix:

./build-dh

Output:

ai:easy-rsa # ./build-dh Generating DH parameters, 1024 bit long safe prime, generator 2 This is going to take a long time .................+...........................................  ...................+.............+.................+.........   ......................................

Key Files

Now we will find our newly-generated keys and certificates in the keys subdirectory. The .key files are the only ones that shouldn't be left unprotected as it's the only part that's private. You should now transfer the client's keys / certificates, along with the CA CERTIFICATE (Read: NOT the key) to their respective machines via a secure channel. The dh1024.pem file only has to be on the server.

Using both methods
Yes. You can use the secret key file and the certificate encryption at the same time. This is even more secure and protects your network against MITM attacks. So if you used the certificate method, you can also do the alternative step down here to keep your network even more secure!

Alternative: Using pre-shared private keys
This is a very quick operation. You will have to make sure this key isn't left out in the open for everyone to see as it's your only protection against MITM attacks. (See: http://openvpn.net/howto.html#security )


 * 1) /usr/sbin/openvpn --genkey --secret ta.key

Transfer this file over a secure channel to all clients.

Creating the network bridge
You only have to complete this step on the machine that is going to host the OpenVPN server. We will create the network bridge that will link the OpenVPN virtual network interfaces with our real, big, bad NIC! Start by emerging bridge-utils and usermode-utilites (for TAP support.)


 * 1) emerge bridge-utils usermode-utilities

Baselayout supports bridging, TUN/TAP out of the box. In /etc/conf.d/net (this is a real world example with 2 NICs, amend to taste, see /etc/conf.d/net.example as well. If you only have one NIC then remove references to eth1 and rename routes_eth1 to routes_br0): modules=("openvpn") config_eth0=( "null" ) bridge_br0=( "eth0 tap0" ) config_br0=(       "192.168.0.254/24" ) config_eth1=(       "xxxxxxxxxxxx/xx" ) routes_eth1=(       "default via xxxxxxxxxxxx" )
 * 1) /etc/conf.d/net
 * 2) LAN - eth0 - e1000, onboard NIC
 * 3)       bridged with tap0 for OpenVPN
 * 4) WAN - eth1 - e100, PCI slotted NIC
 * 5) Note:I recieved an error that no such module (openvpn) exists, so i added iproute2 to my use flags,
 * 6)      re-emerge openvpn and emerged iproute2. I changed modules below from openvpn to iproute2.
 * 7)      I also added the line tuntap_tap0="tap" to /etc/conf.d/net.
 * 1)      re-emerge openvpn and emerged iproute2. I changed modules below from openvpn to iproute2.
 * 2)      I also added the line tuntap_tap0="tap" to /etc/conf.d/net.
 * 1) config_tap0=( "0.0.0.0" )
 * 1) the xxxxxx here should be set to your gateway IP

brctl_br0=( "stp on" )
 * 1) Below is an example of configuring the bridge
 * 2) Consult "man brctl" for more details

depend_br0 { need net.eth0 openvpn

} Edit: Be very careful with the brctl_br0=( "stp on" ) option. This enables the spanning tree protocol. Some people are telling their switches to error out this protocol. If this happens to often, the port might be disabled. In my case it was the gateway which killed my whole infrastructure until the port was set back to be open. -markus Then make symlinks for new devices Stop existing and start the new ones Add Bridge to default runlevel ... and carry on to configuring OpenVPN
 * 1) cd /etc/init.d
 * 2) ln -s net.lo net.br0
 * 3) ln -s net.lo net.tap0
 * 4) ln -s net.eth1 (only if needed)
 * 1) /etc/init.d/net.eth0 stop
 * 2) /etc/init.d/net.br0 start
 * 1) rc-update -a net.br0 default

Configuring our VPN!
We will start by creating the /etc files we require to get this up and running! This step is to be done on the server and every client.


 * 1) mkdir -p /etc/openvpn/cool_network
 * 2) touch /etc/openvpn/cool_network.conf
 * 3) cd /etc/init.d
 * 4) ln -s openvpn openvpn.cool_network

Copy the encryption keys to the /etc/openvpn/cool_network/ directory. On a SSL Certificate configuration, this would be the CA certificate, the machine's certificate and key, and the dh1024.pem file only on the server. On a static key configuration, you just have to copy the ta.key file.

Afterwards, we have to tell OpenVPN what to do! So...

nano -w /etc/openvpn/cool_network.conf

In the following section, we will look into the possible options to add to the cool_network.conf file.

OpenVPN Server
This is the interface we will be binding the OpenVPN server on. Don't ask questions. :)

dev tap0

The proto option can safely be removed, if you do this, the server will assume you are using the default protocol, UDP. I myself use TCP over UDP for my OpenVPN servers, even thought it's not as effective. The port option is, well, the port the OpenVPN server will be listening on! Change this to anything that can suit your needs. You may also specify a 'local ' option to tell the OpenVPN server to bind itself to this specific IP address only. More secure, they say.

proto tcp-server port 1194

The server directive indicates that we're going to be... a server! The first parameter is the subnet of the network we're adding the warriors on, the second parameter is the subnet mask, the third and the forth the ip range for the clients. The ifconfig-pool-persist is an optional, SSL-certificates-configuration-only directive that tells the server to check if the common name of the client's certificate is in the IP Pool. The IP Pool is just a simple file with CN/IP bindings. If you use that, the clients will always be assigned the same IP Address on the network. I recommend this.

mode server server-bridge 10.1.0.0 255.255.255.0 10.1.0.100 10.1.0.130 ifconfig-pool-persist /etc/openvpn/cool_network/ip_pool

Do I really have to explain the mode? :) status is a file where information about OpenVPN is displayed. tls-auth is an optional directive. Use this only if you're on a SSL-certificate configuration. Basically, it's another key, that is in fact a static key just like the static-key encryption configuration. It is used to enhance security. I myself use it. Please notice the second argument. 0=server 1=client. keepalive is used to check if the connection still is alive! The first argument is the ping interval, the second one is the timeout. If a client doesn't answers in the timeout, we drop the connection. client-to-client... Don't ask. :) and verb 3 is good for normal operation.

status /tmp/vpn-cool_network.status tls-auth /etc/openvpn/cool_network/ta.key 0 keepalive 10 30 client-to-client max-clients 150 verb 3

The following section can be completly dumped and replaced with "secret 

tls-server dh /etc/openvpn/cool_network/dh1024.pem ca /etc/openvpn/cool_network/ca.crt cert /etc/openvpn/cool_network/server.crt key /etc/openvpn/cool_network/server.key comp-lzo

These options drop the privileges to the selected UID/GID when everything is setup. Many recommendations.

user openvpn group openvpn

Keep-alive stuff. Don't ask. :)

persist-key persist-tun

You can now start the OpenVPN server! :)

OpenVPN Client
The remote directive is there to indicate where the client will attempt to establish it's connection. The proto can again be removed to use UDP over TCP. The port directive needs to match the server's, and so does dev.

remote example.com proto tcp-client port 1194 dev tap

The client directive indicates that we're a client. Setting resolv-retry to infinite can only help if you're using a laptop that sometimes has to go offline. mute-replay-warnings is an option I recommend so your log files don't get swarmed. verb 3 is good for debugging purposes. persist-tun and persist-key are random Keep-Alive stuff and tls-auth is an optionnal option to increase security even more as explained in the Server section. Remember that the second argument of tls-auth has to be 0 is the machine is a server and 1 if it's a client.

client resolv-retry infinite mute-replay-warnings verb 3 persist-tun persist-key tls-auth ta.key 1

These options indicate that we should drop our privileges to the selected UID/GID when we're done with setting everything up.

user openvpn group openvpn

The ifconfig directive. The first argument is the requested IP on the subnet while the second one is the subnet mask of the network we're connecting to. Don't ask me what ifconfig-nowarn is used for. :)

ifconfig 10.1.0.2 255.255.255.0 ifconfig-nowarn

The tls-client directive indicates that we are a tls... client. The ca, cert and key directives are the paths to the certificate stuff somewhere on your box. comp-lzo is the compression option. If the server has it, you must have it.

tls-client ca /etc/openvpn/cool_network/ca.crt cert /etc/openvpn/cool_network/client.crt key /etc/openvpn/cool_network/client.key comp-lzo

For my windows machine I use the GUI client to manage the connections and the following config file:

port 1194 dev tap remote 81.6.236.5 tls-client ca ca.crt cert client.crt key client.key tls-auth ta.key 1 verb 3 comp-lzo pull

You can now start the OpenVPN client! :)

Automating OpenVPN
Author of this section: Riskable (riskable@youknowwhat.com or Riskable.com). Feel free to contact me with any info/questions. Many users will want to launch OpenVPN automatically upon establishing a network connection (as opposed to "rc-update --add openvpn default"). Also, many users will have different openvpn configurations for the various networks they connect to. Some examples:

 You have an OpenVPN configuration file for home and one for on the road.  You want to run OpenVPN while at home but don't want it to connect when at the office.  You only use OpenVPN for increased security on your home wireless network and don't want to start OpenVPN for any other connection.

 All of these situations can be handled automatically thanks to Gentoo's excellent network configuration scripts. The key to making this work is to have an openvpn.conf file for each network you connect to (and/or having a generic default "openvpn.conf" for any given network). For instance, /etc/openvpn/openvpn.work.conf and /etc/openvpn/openvpn.home.conf with their respective init.d scripts (e.g. /etc/init.d/openvpn.work). Once you've tested that your OpenVPN scripts/configurations work on their respective networks, it is time to configure Gentoo to start them automatically. This is done via the postup and predown functions in the /etc/conf.d/net configuration file.

In this example, I've configured my network connection to automatically launch either openvpn.work or openvpn.home depending on the essid of the wireless connection but you could change the script conditions to whatever you want. If you're using a wired network, you could change $ESSID to check for local DNS servers or whether or not you can ping a certain server. Note: postup runs after your interface has been given an address. So this method works wonderfully with wpa_supplicant. With these lines in your /etc/conf.d/net configuration file, OpenVPN will start according to your preferences whenever a network interface is brought up on your machine (obviously this excludes net.lo). Enjoy!

Conclusion
Well, that's it! By now you should have an operational VPN and clients should be able to connect to it.

Troubleshooting
Please use the associated talk page for troubleshooting.