Workstation OpenVPN

How to set up OpenVPN to support Windows Workstations

Objective

To provide encrypted and authenticated connectivity between remote workstations and a central server.

Background

The HOWTO is based on the work log from a recent installation and this was used for another implementation currently under test.

Environment

Server

This has been installed on Debian etch and should work on Debian-based distributions such as Ubuntu.

There are HOWTOs on the Internet for Red Hat/Fedora. I would expect them to work for CentOS as well, but we have no suitable system to test them.

Workstations

Windows XP Pro SP2 and SP3. Testing will be undertaken on Vista and a Linux workstation in the near future.

Note: We are currently running under an Administrator account on the Windows workstations. This is not good practice and we will be testing the instructions for running under a normal account shortly.

Assumptions

You have a working Linux system connected to the network and are able to make firewall changes to open the necessary port, configure forwarding and so on.

As a minimum, you will need to open UDP port 1194 and, if the OpenVPN server is on a different box to the firewall, redirect port 1194 to that server.

Our installations have OpenVPN on the firewall.

You have a way of finding your server on the Internet

In our case we have a DNS record like vpn.example.org pointing to the external IP address of the VPN server. To further complicate matters the server is connected to the Internet via an ADSL modem and the IP address changes at our ISP's whim. We use ddclient to maintain a record at DynDNS.org, so vpn.example.org is a CNAME record pointing to the DynDNS A record which points to our dynamic IP address. With me so far?

You can see this in real life by doing this:

dig mifos.kula.co.nz

Recommendations

Your internal network should use a RFC 1918 private address range for devices that are not directly exposed to the Internet.

You should assign a suitable address range for the VPN - we'll need this later.

Server Configuration

In the lines below <network name> corresponds to example.com - your domain name - and <server name> to vpn.example.com - the external name of your VPN server.

All commands are run as root.

Install OpenVPN:

apt-get install openvpn

The openvpn process will have been started by the installation.

Stop it while we set up the server:

/etc/init.d/openvpn stop

Copy the sample server.conf file to /etc/openvpn, unpack it, and edit to match your local configuration with the editor of your choice:

No vi/emacs flamewars, please!

cd /etc/openvpn
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz .
gunzip server.conf.gz
vi server.conf

  • change the line starting server to match the VPN subnet you chose above. In our case it is server 10.19.3.0 255.255.255.0.
  • change the line starting push to push a route to the clients so they can reach subnets behind the server. In our case we want to access a Samba server with Windows shares in a DMZ on the 10.19.1.0 subnet: push "route 10.19.1.0 255.255.255.0".
  • we recommend that you leave the line ;duplicate-cn alone. It will make for more work later, as each client will need its own certificate, but makes it trivial to cancel access for an individual client.

Copy the easy-rsa directory to /etc/openvpn

cp -r /usr/share/doc/openvpn/examples/easy-rsa/ /etc/openvpn

Build a new CA cert using easy-rsa:

Note: there is a space between "." and "vars". I missed it the first time.

cd /etc/openvpn/easy-rsa
. vars
./clean-all
./build-ca
cp keys/ca* ..

Build a server key:

./build-key-server <server name>
(commonName: <server name>)
cp keys/<server name>.{key,crt} ..
cd ..
ln -s <server name>.crt server.crt
ln -s <server name>.key server.key

Generate Diffie Hellman parameters:

./build-dh
cp keys/dh1024.pem ..

Test by running:

cd /etc/openvpn
openvpn server.conf

Expect to see something like this:

Sat Jul 26 13:41:58 2008 OpenVPN 2.0.9 i486-pc-linux-gnu [SSL] [LZO] [EPOLL] built on Sep 20 2007
Sat Jul 26 13:41:58 2008 Diffie-Hellman initialized with 1024 bit key
Sat Jul 26 13:41:58 2008 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Sat Jul 26 13:41:58 2008 TUN/TAP device tun0 opened
Sat Jul 26 13:41:58 2008 ifconfig tun0 10.19.3.1 pointopoint 10.19.3.2 mtu 1500
Sat Jul 26 13:41:58 2008 route add -net 10.19.3.0 netmask 255.255.255.0 gw 10.19.3.2
Sat Jul 26 13:41:58 2008 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Sat Jul 26 13:41:58 2008 GID set to nogroup
Sat Jul 26 13:41:58 2008 UID set to nobody
Sat Jul 26 13:41:58 2008 UDPv4 link local (bound): [undef]:1194
Sat Jul 26 13:41:58 2008 UDPv4 link remote: [undef]
Sat Jul 26 13:41:58 2008 MULTI: multi_init called, r=256 v=256
Sat Jul 26 13:41:58 2008 IFCONFIG POOL: base=10.19.3.4 size=62
Sat Jul 26 13:41:58 2008 IFCONFIG POOL LIST
Sat Jul 26 13:41:58 2008 Initialization Sequence Completed

Control-C to cancel and then start it properly:

/etc/init.d/openvpn start

Workstation Configuration

On the Server

Create a simple client config for based on the sample:

cd /etc/openvpn
mkdir clients
cd clients
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf .

Edit to suit:

vi client.conf

  • change the line starting remote to include <server name> as above - this is how the client finds the server. For example: remote vpn.example.com 1194.
  • as I connect to multiple clients, I change ca ca.crt to ca <server name>-ca.crt with a corresponding change noted below at !1.
  • I think that's all we changed, but make sure the tun and proto lines match your server.

Build workstation keys for betty:

cd /etc/openvpn/easy-rsa
./build-key betty.<network name>
(commonName: betty.<network name>)


Create certificates and other client files:

cd /etc/openvpn/clients
mkdir betty
cd betty
cp ../client.conf mv <server name>.ovpn
cp /etc/openvpn/ca.crt . [1]
cp /etc/openvpn/easy-rsa/keys/betty.<network name>.{crt,key} .
mv betty.<network name>.crt client.crt
mv betty.<network name>.key client.key

!1 In my case, this will be:

cp /etc/openvpn/ca.crt <server name>-ca.crt

as per the comment above.

On the Workstation

Download and install the OpenVPN GUI Client

Copy the files from the server in /etc/openvpn/clients/betty to C:\Program Files\OpenVPN\config.

The OpenVPN GUI client should be running in the system tray.

Click right on its icon, then select your target server from the context menu and then "Connect".

Viola!

If it doesn't work, it's the firewall, dummy. At least it was for me. I could establish a VPN connection immediately, but couldn't connect to any resources. The answer was that the firewall didn't allow traffic from the DMZ back to the VPN.

I can now connect to network shares in the DMZ and access an internal web server.

Server Firewall Rules

We use iptables on our servers. The following lines should give you the flavour:

Create /etc/ipmasq/rules/V00OpenVpn.rul

For the network discussed above, where eth0 is the external interface, the contents will be:

# OpenVPN

# Allow TUN interface connections to OpenVPN server
iptables -A INPUT -i tun+ -j ACCEPT

# Allow TUN interface connections to be forwarded through other interfaces
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT

# Allow TUN interface connections to get out
iptables -A OUTPUT -o tun+ -j ACCEPT

# We want to allow routing from OpenVPN tunnels.
iptables -t nat -A POSTROUTING -o eth0 -s 10.19.3.0/255.255.255.0 -j MASQUERADE
iptables -A FORWARD -i tun+ -o eth0 -s 10.19.3.0/255.255.255.0 -j ACCEPT