Install and setup OpenVPN on Debian 4.0 Etch
by Razvan on Mar.05, 2009, under Linux World
OpenVPN is a software allowing to create virtual private network without using such technologies as PPtP (Microsoft) or IPSec. It is available on many operating systems (Microsoft Windows, GNU / Linux, MacOS X, …). It a simple way to manage a virtual private network between various operating systems and computers.
Software installation
OpenVPN installation is done by this command line :
apt-get install openvpn openssl liblzo1
Once OpenVPN installed on our system, we create a folder to regroup scripts used by this howto :
mkdir –parents /etc/openvpn/scripts/
We also need to create character devices used by the server and load necessary modules :
modprobe tun
mkdir /dev/net
mknod /dev/net/tun c 10 200
Encryption keys creation
OpenVPN use OpenSSL to encrypt connections. Clients authentication is based on private / public keys signature. This keys are the core of a OpenVPN network. You need to be carefull when creating them.
EasyRSA scripts setup
OpenVPN is installed with some scripts that easy encryption keys creation. We now copy this scripts in the VPN server configuration folder so that we can edit them :
cp -r /usr/share/doc/openvpn/examples/easy-rsa/ /etc/openvpn
Two of the files of this configuration needs to be edited. We start by downloading modified versions needed by this howto :
wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/vars \ --output-document /etc/openvpn/easy-rsa/vars wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/openssl.cnf \ --output-document /etc/openvpn/easy-rsa/openssl.cnf
VPN server parameters
You can now edit the VPN configuration files to fit your needs :
vim /etc/openvpn/easy-rsa/vars
Here is a short description of the values you need to change :
- OPENVPN_SERVER : DNS alias of the host of the OpenVPN server software.
- OPENVPN_CLIENTS : Space separated list of VPN clients names.
- OPENVPN_IPRANGE : The first 3 digits of IP address in your VPN.
- OPENVPN_LOCALDOMAIN : The VPN DNS extension.
Warning : The IP address ranges of your VPN and of your local networks MUST be different. You will find more information on available IP address ranges by reading Numbering private subnets.
You should also enter your geographical informations :
- KEY_COUNTRY : Your country code.
- KEY_PROVINCE : Your province.
- KEY_CITY : Your city.
- KEY_ORG : The key name (you don’t have to change it).
- KEY_EMAIL : The email address associated to the key.
Note : By default, the length of created keys is 1024 bits. If you are quite paranoïd, you can raise this value at cost of your VPN performances.
KEY_SIZE=2048
Certification authority creation
A certification authority is a private / public keys pair used to sign other public keys. To create your certification authority, use the following command lines :
source /etc/openvpn/easy-rsa/vars export KEY_COMMONNAME="ca.$OPENVPN_SERVER" /etc/openvpn/easy-rsa/clean-all /etc/openvpn/easy-rsa/build-ca
If you have correctly set up easy-rsa, you can use the default values.
Note : Some free certification authority exists and can be used to sign HTTPS servers certificates. This is not necessary for a OpenVPN server, but if you want to do this, I think it is possible. To find more about this, visit CAcert.
Server certificate creation
We will now create our server certificate. This is done by running these commands :
source /etc/openvpn/easy-rsa/vars export KEY_COMMONNAME="$OPENVPN_SERVER" /etc/openvpn/easy-rsa/build-key-server server
Here again, use default values.
Note : You can protect your server certificate with a password. If you choose to do this, the password will be asked each time you need to create or revoke clients certificates. DO NOT LOOSE IT. It’s a security asset, but it is not mandatory. Take your descision according to your paranoïa level.
The script ask you to confirm the certificate signature. Answer Yes at both asks.
Sign the certificate? [y/n]: y 1 out of 1 certificate requests certified, commit? [y/n] y
Note : The certificate signature is done with our certification authority.
Diffie Hellman parameters
Diffie Hellman parameters must be computed so that your configuration work. This is done by running these command lines :
source /etc/openvpn/easy-rsa/vars /etc/openvpn/easy-rsa/build-dh
TLS key
We now create a key that will protect our VPN from some attacks. It allow us to setup a HSA firewall :
openvpn --genkey --secret /etc/openvpn/keys/ta.key
Server configuration
To create our VPN server configuration, we use a example file :
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/ gunzip /etc/openvpn/server.conf.gz
We modify this file to feet our needs :
source /etc/openvpn/easy-rsa/vars sed -i \ -e "s/^ca ca\.crt/ca \/etc\/openvpn\/keys\/ca\.crt/" \ -e "s/^cert server\.crt/cert \/etc\/openvpn\/keys\/server\.crt/" \ -e "s/^key server\.key/key \/etc\/openvpn\/keys\/server\.key/" \ -e "s/^dh[\t ]*dh1024.pem/dh \/etc\/openvpn\/keys\/dh$KEY_SIZE.pem/" \ -e "s/^server[\t ].*$/server $OPENVPN_IPRANGE\.0 255\.255\.255\.0/" \ -e 's/^;\(tls-auth \)\(ta.key.*\)$/\1\/etc\/openvpn\/keys\/\2/' \ -e 's/^;\(.*# Triple-DES\)$/\1/' \ -e 's/^\(status \).*/\1\/var\/log\/openvpn-status.log/' \ /etc/openvpn/server.conf
Reduced permissions
We want our VPN server to run with minimals permissions. First, make you keys folder readable :
chmod go+rx /etc/openvpn/keys
And setup OpenVPN to run with nouser and nogroup permissions :
sed -i \ -e 's/^;\(user[ \t]*.*\)/\1/' \ -e 's/^;\(group[ \t]*.*\)/\1/' \ /etc/openvpn/server.conf
Client to Client communication in the VPN network
If you want your VPN clients to be able to dialog with each others, and not only with the server, run this command line :
sed -i -e 's/^;client-to-client/client-to-client/' \ /etc/openvpn/server.conf
Clients revocation management :
In order to detect revoked clients, we enable the revoked certificates management :
echo " # Revoked certificate list crl-verify /etc/openvpn/keys/crl.pem" >> /etc/openvpn/server.conf
And we create a empty crl.pem file :
chmod +x /etc/openvpn/easy-rsa/make-crl /etc/openvpn/easy-rsa/make-crl /etc/openvpn/keys/crl.pem
Last step
The last step is to restart the VPN server :
/etc/init.d/openvpn restart
VPN clients management
A client certificate can be created or revoked. The revocation allow to eject an unwanted client from our virtual private network. It’s a process i’ve ignored for some time, since i did not need it. But now, i can see that it is very usefull.
First, we download two scripts that easy client revocation and addition.
wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/add-client.sh \ --output-document /etc/openvpn/scripts/add-client.sh chmod +x /etc/openvpn/scripts/add-client.sh wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/revoke-client.sh \ --output-document /etc/openvpn/scripts/revoke-client.sh chmod +x /etc/openvpn/scripts/revoke-client.sh
Clients certificates creation
We now create our clients certificates. Run the following comand lines :
source /etc/openvpn/easy-rsa/vars for OPENVPN_CLIENT in $OPENVPN_CLIENTS; do export KEY_COMMONNAME="$OPENVPN_CLIENT.client.$OPENVPN_SERVER"; /etc/openvpn/easy-rsa/build-key $OPENVPN_CLIENT; done
When the script ask you something, just use default values, but be sure to reply “y” at these two questions :
Sign the certificate? [y/n]: y 1 out of 1 certificate requests certified, commit? [y/n] y
Client addition
If you want to add a new client, you can do this using this command line :
/etc/openvpn/scripts/add-client.sh client_name
After adding a client, i suggest you to replay the following steps (described bellow in this page) :
- Clients configuration files creation
- Clients fixed IP addresses attribution
- Bind configuration files creation or update
Client revocation
If you want to exclude one of your client from your virtual private network, you can revoke it by using this command line :
/etc/openvpn/scripts/revoke-client.sh client_name
Clients configuration files creation
We will now create tar.gz files containing keys and configurations files needed by our VPN clients. In order to do this, we download a script designed to easy this task :
wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/create-clients-configuration.sh \ --output-document /etc/openvpn/scripts/create-clients-configuration.sh chmod +x /etc/openvpn/scripts/create-clients-configuration.sh
We create configuration files for each VPN clients :
/etc/openvpn/scripts/create-clients-configuration.sh
You have now many tar.gz files that you can copy on clients computers and extract we this command line :
tar --directory /etc -xzf votre-fichier-client.tar.gz
Now, you need to install OpenVPN on clients computers and start or restart it :
apt-get install openvpn liblzo1 /etc/init.d/openvpn restart
If all went well, you should see a message telling you that everything is OK. The following command line allow you to get more informations about your VPN link :
ifconfig tun0
Going deeper
The first part of this article helped you to create a simple Virtual Private Network where clients can’t communicate between each others and with the server. It’s fine but in most case, it is not sufficient. We will see here how we can enhance our VPN. The first step is to run this command lines :
mkdir /etc/openvpn/clients-configs echo " # Advanced configurations client-config-dir /etc/openvpn/clients-configs" \ >> /etc/openvpn/server.conf
Allowing VPN clients to access VPN server local network
If you want to access your VPN server local network from your VPN clients, you should first make sure that your clients local networks does not use the same IP address range that your server local network. If all is checked, you can signal to your clients which route to use to access your server local network :
ifconfig eth0 | grep inet | \ sed -e 's/.*:\([0-9\.]*\)[0-9]\{1,3\} .*:\([0-9\.]*\) .*:\([0-9\.]*\).*/push "route \10 \3"/g' \ >> /etc/openvpn/server.conf
Once this done, we will play with the iptables configuration to make a NAT router from our VPN server. Yep, i’ve said NAT. I’ve see a lot of complicated howtos to setup a complete routing between VPN clients and the server local network, but i think it is totally overkill for most needs.
Netfilter (IpTables) configuration
First, if needed, we create the iptables ip-up.d script. This script will be run each time the network is started:
if [ ! -e /etc/network/if-up.d/iptables ]; then echo '#!/bin/sh # IpTables rules.' | /usr/bin/tee /etc/network/if-up.d/iptables fi /bin/chmod +x /etc/network/if-up.d/iptables
We allow NAT rules to work on the system:
sed -i -e 's/[# ]*\(net\.ipv4\.conf\.default\.forwarding=\).*/\11/g' /etc/sysctl.conf echo 1 > /proc/sys/net/ipv4/ip_forward
We load the NAT configuration for our VPN:
iptables -t nat -A POSTROUTING -s $OPENVPN_IPRANGE.0/24 -o eth0 -j MASQUERADE
And we add it to the if-up.d script so that it will be loaded at each system start:
echo "iptables -t nat -A POSTROUTING -s $OPENVPN_IPRANGE.0/24 -o eth0 -j MASQUERADE" \ | /usr/bin/tee -a /etc/network/if-up.d/iptables
Your iptables configuration will be now reloaded each time your server restart.
Clients fixed IP addresses attribution
It is possible to fix VPN clients IP addresses. You can then connect to them easily by using this IP adresses.
For more informations, visit Configuring client specific rules and access policies.
In order to do this, we download a script designed to ease this task :
wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/setup-clients-ips.sh \ --output-document /etc/openvpn/scripts/setup-clients-ips.sh chmod +x /etc/openvpn/scripts/setup-clients-ips.sh
And we run it :
/etc/openvpn/scripts/setup-clients-ips.sh
Setting up a name server for our VPN
If you have choosen to fix your VPN clients IP addresses, it is interesting to have a DNS server to provide computer/IP associations for our VPN network. In my configuration, i use Bind :
apt-get install bind9
If you think it is using a homing missile to kill a flee, you are probably right, but i was willing to try Bind (and nothing is better than learning by usage).
We now add the fixed IP addresses from our VPN to the Bind configuration.
Bind configuration initialization
This step is done once and for all. We configure Bind in order that it know were to find our VPN specific configuration. First, we get needed data, and we run a light computation :
source /etc/openvpn/easy-rsa/vars REVERSE_IPRANGE=`echo $OPENVPN_IPRANGE | sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3\.\2\.\1/'`
We then tell Bind to use the file we will create to manage our VPN clients names.
echo " # OpenVPN configuration zone \"$REVERSE_IPRANGE.in-addr.arpa\" in { type master; file \"/etc/bind/db.$OPENVPN_IPRANGE\"; }; zone \"$OPENVPN_LOCALDOMAIN\" in { type master; file \"/etc/bind/db.$OPENVPN_LOCALDOMAIN\"; };" >> /etc/bind/named.conf.local
You now need to setup your VPN server so that it tell the VPN clients witch DNS server to use :
echo " # VPN provided DNS server configuration. push \"dhcp-option DOMAIN $OPENVPN_LOCALDOMAIN\" push \"dhcp-option DNS $OPENVPN_IPRANGE.1\"" \ >> /etc/openvpn/server.conf
Restart your VPN server :
/etc/init.d/openvpn restart
This configuration will work by itself for your Microsoft VPN clients. For linux clients, you need to do something more (see below).
Bind configuration files creation or update
We now download a script allowing us to update the bind configuration when we add or revoke a VPN client :
wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/update-bind-config.sh \ --output-document /etc/openvpn/scripts/update-bind-config.sh chmod +x /etc/openvpn/scripts/update-bind-config.sh
From now on, each time you add a new client to your VPN, once you’ve setted up its fixed IP address, you can update the Bind daemon configuration by running :
/etc/openvpn/scripts/update-bind-config.sh
Once this done, you should reload Bind configuration :
/etc/init.d/bind9 reload
Configuring Linux clients to use DNS informations provided by VPN server
Warning : The following is to be done on every linux client for your VPN (and not on the server).
We first download the script client.up that fetch DNS informations from our VPN link, and insert it in the resolv.conf file :
wget http://howto.landure.fr/gnu-linux/debian-4-0-etch/installer-et-configurer-openvpn-sur-debian-4-0-etch/client.up \ --output-document=/etc/openvpn/client.up chmod +x /etc/openvpn/client.up
We type our VPN network name :
OPENVPN_LOCALDOMAIN=vpndomain.vpn
Then, we configure the client so that it run the client.up script when connecting to the VPN network :
echo " # VPN provided DNS configuration. up /etc/openvpn/client.up route-up /etc/openvpn/client.up plugin /usr/lib/openvpn/openvpn-down-root.so \"script_type=down /etc/openvpn/client.up\"" \ >> /etc/openvpn/$OPENVPN_LOCALDOMAIN.conf
You just need to restart your VPN client to activate this configuration :
/etc/init.d/openvpn restart