Installation

Install necessary packages

  • Debian

 # apt-get install openvpn liblzo1 zip

  • Gentoo

 # emerge -av openvpn zip

Install easy-rsa for key management

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

Customize scripts

  • edit /etc/openvpn/easy-rsa/build-key and add:

  mkdir /tmp/$1
  cp $KEY_DIR/$1.key /tmp/$1/
  cp $KEY_DIR/$1.crt /tmp/$1/
  cp $KEY_DIR/ca.crt /tmp/$1/
  cp /etc/openvpn/ta.key /tmp/$1/
  cp /etc/openvpn/README.txt /tmp/$1/
  sed s/%NAME%/${1}/g /etc/openvpn/client.dummy > /tmp/$1/client.ovpn
  cd /tmp
  zip -r $1_vpn.zip $1
  rm -rf /tmp/$1

  • edit /etc/openvpn/easy-rsa/openssl.cnf and comment the pkcs11 section:

  #[ 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

  • create /etc/openvpn/client.dummy:

##############################################
# Sample client-side OpenVPN 2.0 config file #
# for connecting to multi-client server.     #
#                                            #
# This configuration can be used by multiple #
# clients, however each client should have   #
# its own cert and key files.                #
#                                            #
# On Windows, you might want to rename this  #
# file so it has a .ovpn extension           #
##############################################

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
dev tap
;dev tun

# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel
# if you have more than one.  On XP SP2,
# you may need to disable the firewall
# for the TAP adapter.
;dev-node tap

tls-client

# Are we connecting to a TCP or
# UDP server?  Use the same setting as
# on the server.
;proto tcp
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote XXX.XXX.XXX.XXX 1194
remote XXX.XXX.XXX.XXX 1194

# Choose a random host from the remote
# list for load-balancing.  Otherwise
# try hosts in the order specified.
;remote-random

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server.  Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.
nobind

# Downgrade privileges after initialization (non-Windows only)
;user nobody
;group nobody

# Try to preserve some state across restarts.
persist-key
persist-tun

# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here.  See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]
# Wireless networks often produce a lot
# of duplicate packets.  Set this flag
# to silence duplicate packet warnings.
;mute-replay-warnings


# SSL/TLS parms.
# See the server config file for more
# description.  It's best to use
# a separate .crt/.key file pair
# for each client.  A single ca
# file can be used for all clients.
ca ca.crt
cert %NAME%.crt
key %NAME%.key
tls-auth ta.key 1

# Verify server certificate by checking
# that the certicate has the nsCertType
# field set to "server".  This is an
# important precaution to protect against
# a potential attack discussed here:
#  http://openvpn.net/howto.html#mitm
#
# To use this feature, you will need to generate
# your server certificates with the nsCertType
# field set to "server".  The build-key-server
# script in the easy-rsa folder will do this.
ns-cert-type server

# If a tls-auth key is used on the server
# then every client must also have the key.
;tls-auth ta.key 1

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
;cipher x

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 1

# Silence repeating messages
;mute 20

;fragment 1400
mssfix

Create server config

  • Edit/create /etc/openvpn/server.conf

 port 1194
 proto udp
 dev tap
 tls-server

 crl-verify easy-rsa/keys/crl.pem
 ca /etc/openvpn/easy-rsa/keys/ca.crt
 cert /etc/openvpn/easy-rsa/keys/server.crt
 key /etc/openvpn/easy-rsa/keys/server.key  # This file should be kept secret
 dh /etc/openvpn/easy-rsa/keys/dh1024.pem

 ; if you need clients to use a particular range of IPs
 ;server-bridge <vpn server IP> <netmask> <first IP> <last IP>

 push "dhcp-option DNS 192.168.1.53"
 push "dhcp-option DNS 192.168.1.54"
 push "dhcp-option DOMAIN .priv"
 ; Default gateway of local (server) network
 push "route-gateway 192.168.1.254"
 ; if you need routes to additional subnets, add them here
 push "route 192.168.2.0 255.255.255.0"
 push "route 192.168.3.0 255.255.255.0"

 client-to-client
 ifconfig-pool-persist ipp.txt
 keepalive 10 120

 comp-lzo

 user nobody
 group nogroup

 persist-key
 persist-tun

 status /var/log/openvpn-status.log
 ;log verbosity (1 to 9)
 verb 4

 tls-auth ta.key 0

Build server keys

Enter the easy-rsa directory previously created as root

# cd /etc/openvpn/easy-rsa

Edit vars file and set variables at the end of the file as follow:

export KEY_COUNTRY="FR"
export KEY_PROVINCE="NA"
export KEY_CITY="Paris"
export KEY_ORG="Example"
export KEY_UNIT="VPN"
export KEY_EMAIL="example@example.com"
Prepare the keys environnement:

# source ./vars
# ./clean-all

Initialise the PKI:

#./build-ca

Generate a certificate and private key for the server:

# ./build-key-server server

Generate Diffie Hellman parameters:

# ./build-dh

NOTE: for more help, please see http://openvpn.net/howto.html#pki

Enable access to local network

By default, only the openvpn host is accessible from the client. To enable access to all local hosts, you have to add a firewall forward rule.

edit/create /etc/init.d/fw, and make sure it is executable:

# /sbin/iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

and launch it

# /etc/init.d/fw

Build certificate

Change directory and prepare environment:

# cd /etc/openvpn/easy-rsa
# source ./vars

Build certificate:

# ./build-key <user>

NOTE: usual format for user is [first letter of first name].[last name]

You will have to enter some information for the user's cerficate. For most of the fields, press <enter> for default value, except for Organizational Unit Name (VPN), Common Name (complete name) and Email Address:

  host:/etc/openvpn/easy-rsa# ./build-key j.doe
  Generating a 1024 bit RSA private key
  .........++++++
  .....................................++++++
  writing new private key to 'j.doe.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) [FR]:
  State or Province Name (full name) [NA]:
  Locality Name (eg, city) [Paris]:
  Organization Name (eg, company) [Example]:
  Organizational Unit Name (eg, section) []:VPN
  Common Name (eg, your name or your server's hostname) [j.doe]:John Doe
  Email Address [example@example.com]:j.doe@example.com
  Please enter the following 'extra' attributes
  to be sent with your certificate request
  A challenge password []:
  An optional company name []:
  Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
  DEBUG[load_index]: unique_subject = "yes"
  Check that the request matches the signature
  Signature ok
  The Subject's Distinguished Name is as follows
  countryName           :PRINTABLE:'FR'
  stateOrProvinceName   :PRINTABLE:'NA'
  localityName          :PRINTABLE:'Paris'
  organizationName      :PRINTABLE:'Example'
  organizationalUnitName:PRINTABLE:'VPN'
  commonName            :PRINTABLE:'John Doe'
  emailAddress          :IA5STRING:'j.doe@example.com'
  Certificate is to be certified until Oct 19 09:27:26 2017 GMT (3650 days)
  Sign the certificate? [y/n]:y

A zip file name j.doe_vpn.zip will the be created in /tmp/ with all necessary files, send it to the user via encrypted channel; if you really do want to send it over e-mail, you can use SendEmail:

# sendEmail -f vpn@example.com -t j.doe@example.com -u "VPN certificate" -m "here it is." -a /tmp/j.doe_vpn.zip

Revoke certificate

Change directory and prepare environment:

# cd /etc/openvpn/easy-rsa
# source ./vars

Revoke certificate:

# ./revoke-full <user>

NOTE: usual format for user is [first letter of first name].[last name] you can check existing certificates in the current directory.

Troubleshooting

If Routing does not work on the client side, you will have to manually add a route; example on a Windows machine:

# route ADD 192.168.1.0 MASK 255.255.0.0 192.168.1.254

this issue should mostly occur on Windows Vista & Windows 7 with pre-2.1rc2 OpenVPN versions.