Admin Stuff

This setup is based on v2.0 of the easy-rsa scripts with some modifications and additions. Here a list of all relevant files. I placed all those in /etc/openvpn:

drwxr-xr-x 3 root root   352 2007-05-31 21:04 pki

drwxr-xr-x 2 root root   672 2007-05-31 21:10 pki/keys
-rw-r--r-- 1 root root   342 2007-05-31 21:10 pki/keys/index.txt
-rw-r--r-- 1 root root     3 2007-05-31 21:10 pki/keys/serial

-rw-r--r-- 1 root root   354 2007-05-31 12:06 pki/build-dh
-rw-r--r-- 1 root root   232 2007-05-31 13:39 pki/client.conf
-rwxr-xr-x 1 root root   706 2007-05-31 13:46 pki/create-key
-rwxr-xr-x 1 root root   383 2007-05-31 12:27 pki/list-crl
-rw-r--r-- 1 root root  8232 2007-05-31 21:03 pki/openssl.cnf
-rwxr-xr-x 1 root root 12154 2007-05-31 12:14 pki/pkitool
-rwxr-xr-x 1 root root   980 2007-05-31 12:27 pki/revoke-full
-rw-r--r-- 1 root root  1591 2007-05-31 12:47 pki/vars

-rw-r--r-- 1 root root   486 2007-05-31 21:05 server.conf

Most of these files in pki are copied straight from /usr/share/doc/openvpn/examples/easy-rsa/2.0 (this is on debian-etch). I did not use the clean-all script, I did the setup myself to make sure, the permissions are correct:

 # umask 022
 # mkdir -p /etc/openvpn/pki/keys
 # touch /etc/openvpn/pki/keys/index.txt
 # echo 01 >/etc/openvpn/pki/keys/serial
 # cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/{build-dh,list-crl,openssl.cnf,pkitool,revoke-full,vars} \
       /etc/openvpn/pki
 # chmod ugo-x /etc/openvpn/pki/build-dh


Next I modified all executable scripts and added the following two lines near the top

 base="`dirname $0`"; base="`cd "$base"; pwd`"
 cd $base
 [ -r vars ] && source vars


In /etc/openssl.cnf two lines need to be commented out at the end to fix revoke-all since those environment variables are not found:

 [ pkcs11_section ]
 engine_id = pkcs11
 dynamic_path = /usr/lib/engines/engine_pkcs11.so
 # MODULE_PATH = $ENV::PKCS11_MODULE_PATH
 # PIN = $ENV::PKCS11_PIN
 init = 0


Then setup the vars file:

 export EASY_RSA="/etc/openvpn/pki"
 export OPENSSL="openssl"
 export PKCS11TOOL="pkcs11-tool"
 export GREP="grep"
 export KEY_CONFIG="$EASY_RSA/openssl.cnf"
 export KEY_DIR="$EASY_RSA/keys"
 export KEY_SIZE=1536
 export CA_EXPIRE=3650
 export KEY_EXPIRE=3650
 export KEY_COUNTRY="..."
 export KEY_PROVINCE="..."
 export KEY_CITY="..."
 export KEY_ORG="..." # Use some domain name here
 export KEY_EMAIL="..." # And some admin email address


Then initialize the PKI. build-dh takes quite some time, so be patient:

 # cd /etc/openvpn/pki
 # . vars
 # /bin/sh build-dh
 # ./pkitool --initca
 # ./pkitool --server <server-fqdn>
 # openvpn --genkey --secret keys/ta.key
 # KEY_CN="" KEY_OU="" openssl ca -config openssl.cnf -gencrl -out keys/crl.pem


(need to source vars for build-dh). Now we need the configuration files for the client and server. The server configuration lives in /etc/openvpn/server.conf:

 port 1194
 proto tcp
 dev tun
 ca pki/keys/ca.crt
 crl-verify pki/keys/crl.pem
 cert pki/keys/<server-fqdn>.crt
 key pki/keys/<server-fqdn>.key
 dh pki/keys/dh1536.pem
 server <client-net> <client-netmask>
 ifconfig-pool-persist /var/ipp.txt
 push "route <local-net> <local-netmask>"
 push "dhcp-option DNS <local-nameserver>"
 push "dhcp-option WINS <local-samba>"
 keepalive 10 120
 tls-auth pki/keys/ta.key 0
 comp-lzo
 user nobody
 group nogroup
 persist-key
 persist-tun
 status /var/log/openvpn-status.log
 verb 3


<client-net>/<client-netmask> is the Range of IP addresses which will be assigned to connecting clients. <local-net>/<local-netmask> is the local network which should be accessible by the clients. <local-nameserver> and <local-samba> are the ip's of the corresponding servers. Lastly we build the client configuration. This will be the same for every client. This is placed into /etc/openvpn/pki/client.conf:

 client
 dev tun
 proto tcp
 remote <server-address> 1194
 resolv-retry infinite
 nobind
 user nobody
 group nogroup
 persist-key
 persist-tun
 ca ca.crt
 cert client.crt
 key client.key
 tls-auth ta.key 1
 ns-cert-type server
 comp-lzo
 verb 3


Here <server-address> is the ip address or hostname to access the openvpn server from the outside. This need not be the same as <server-fqdn>. We then start the server with /etc/init.d/openvpn start. We need one more script, create-key which will build a new client-key-pair and wrap it together with all necessary configuration files into a .zip archive:

#!/bin/sh

base="`dirname $0`"; base="`cd "$base"; pwd`"

if [ -z "$1" ]; then
        echo "Usage: $0 <email address>"
        echo
        echo "Creates a new keypair for the given user."
        echo "Will place a file '<email address>.zip' into the current directory."
        echo "This ZIP file contains all configuration parameters and other"
        echo "files needed to run the openvpn client"
        echo
        exit 2
fi

"$base"/pkitool --pass "$1"
umask 077

mkdir .vpnconf
cd .vpnconf
cp "$base/keys/$1.crt" client.crt
cp "$base/keys/$1.csr" client.csr
cp "$base/keys/$1.key" client.key
cp "$base/keys/ca.crt" ca.crt
cp "$base/keys/ta.key" ta.key
cp "$base/client.conf" client.conf
zip ../"$1.zip" *
cd ..
rm -r .vpnconf

rm "$base/keys/$1.key"

This script will be called with the email address of every user.

 # create-key <email-address>

The generated <email-address>.zip file contains the complete client configuration. To revoke access for a user, use

 # revoke-all <email-address>

I added /etc/openvpn/pki to root's PATH in ~/.bashrc to make these commands accessible directly.

Networkwise, make sure incoming packets on port 1194 are forwarded to the openvpn server. On the openvpn server ip forwarding must be enabled if access to hosts besides the openvpn server is desired. Additionally, if the openvpn server is not the networks default router, either you need to tell your router about the <client-net> or enable masquerading on the openvpn server.

Changing/removing the key passphrase

After the key has been transfered to the remote system and if the remote system is sufficiently secure, the passphrase can be removed using

 # openssl rsa -in client.key -out client.key.new
 # mv client.key client.key.old
 # mv client.key.new client.key


To change the passphrase, add the -des3 parameter before -out to the openssl command line