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 isserver 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
toca <server name>-ca.crt
with a corresponding change noted below at !1. - I think that's all we changed, but make sure the
tun
andproto
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