How-To: OpenVPN on Debian Squeeze with Username/Password authentication

10 minute read

OpenVPN is a SSL based VPN software that runs on most OS. It is simple to install and run.

In this tutorial, I will go over the steps needed to configure OpenVPN on Debian Squeeze to provide a full VPN tunnel, this is particularly useful when you want to access internet from non-trusted networks such as free hotspots…

There are many ways of setting up OpenVPN, a common one is to use a unique certificate for each users. Another one is to have each user authenticate with a username/password.

In this article, we will be setting OpenVPN to authenticate users using PAM.

more

In this scenario, we will run a VPN server on a machine with external IP 172.16.132.5 on eth0, in a real life case, this should be a public IP.

OpenVPN client will be getting IPs in range 10.8.0.0/24 which is the network that our OpenVPN server will handle.

The traffic will then be _NAT_ted on the external interface.

The OpenVPN server also needs to run a DNS server that replies to request on IP 10.8.0.1, this is required as we will be pushing DNS settings to the OpenVPN clients.

The setup of such server is outside the scope of this article.

Installing

Installation of OpenVPN is pretty simple on Debian:

# apt-get install openvpn

Now that we have installed openvpn, we need to configure it… that is where it gets a bit more complicated!

Configuration

As OpenVPN is an SSL based VPN, it uses SSL certificates to encrypt data. Even though we will not use certificates for each clients, we still need to generate certificates for the server side.

There is a bit of work to be done here, fortunately, OpenVPN comes with a lot of helper scripts to make it easier for us!

Generating Certificates

Debian ships a bunch of helper script in its openvpn package. Those scripts are stored in /usr/share/doc/openvpn/examples. We will copy the utilities to /etc/openvpn/.

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

Now, we will go to /etc/openvpn/easy-rsa/2.0 and create the certificates…

# cd /etc/openvpn/easy-rsa/2.0

All default values for generating certificates are stored in vars file. Edit this file and look for the KEY_*, CA_EXPIRE and KEY_EXPIRE variables and edit them t your likings.

Finally, create the CA

[email protected]:2.0# ./build-ca
Generating a 1024 bit RSA private key
......++++++
...++++++
writing new private key to 'ca.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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:
Name []:
Email Address [[email protected]]:

And the Diffie Hellman parameter

[email protected]:2.0# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.....................................++*++*++*

Finally, we generate the server certificate:

[email protected]:2.0# ./build-key-server server01
Generating a 1024 bit RSA private key
.....................++++++
.................++++++
writing new private key to 'server01.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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [server01]:
Name []:
Email Address [[email protected]]:

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/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName : PRINTABLE:'US'
stateOrProvinceName : PRINTABLE:'CA'
localityName : PRINTABLE:'SanFrancisco'
organizationName : PRINTABLE:'Fort-Funston'
commonName : PRINTABLE:'server01'
emailAddress :IA5STRING:[email protected]'
Certificate is to be certified until Jan 13 07:52:57 2023 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
  
Write out database with 1 new entries
  
Data Base Updated 

And, to avoid DoS attack and UDP port flooding, we will generate a shared secret between the server and the clients:

[email protected]:2.0# openvpn --genkey --secret keys/ta.key

Creating the configuration

Now that we have our certificates ready, we need to create a set of config for the server and the client.

Server side

On the server side, you will need to create the file /etc/openvpn/server.conf and edit it with:

dev tun
proto udp
port 1194

# since OpenVPN 2.1 we can use topology subnet
topology subnet
# if we want to change the temp directory location
; tmp-dir /dev/shm
# certs
ca keys/ca.crt
cert keys/server01.crt
key keys/server01.key
dh keys/dh1024.pem
# TLS
tls-auth keys/ta.key 0

# Keepalive
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120

comp-lzo
# Write operational status to this file
status openvpn-status.log

# Drop privileges
user nobody
group nogroup
# As we dropped privileges, make sure we dont
# close/reopen tun interface amd re-read key files
# accross SIGUSR1
persist-key
persist-tun


# Our subnet
server 10.8.0.0 255.255.255.0
# Redirect all traffic to our OpenVPN server
push "redirect-gateway def1 bypass-dhcp"
# We want client to use our DNS server
push "dhcp-option DNS 10.8.0.1"
ifconfig-pool-persist ipp.txt

# If you want OpenVPN clients
# to be able to connect directly
# to each others
; client-to-client

# Use PAM authentication
plugin /usr/lib/openvpn/openvpn-auth-pam.so login

# we dont want to use client certificate
client-cert-not-required
username-as-common-name
# enable mgmt over telnet
management localhost 1194 mgmt-pw-file
verb 3

Then, we need to copy the certificates/keys in the keys directory of /etc/openvpn:

mkdir /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/2.0/keys/{ca.crt,server01.crt,server01.key,dh1024.pem,ta.key} /etc/openvpn/keys/

And, in order to be able to manage openvpn from a telnet connection, we will create a file called /etc/openvpn/mgmt-pw-file with password “password”:

echo password > /etc/openvpn/mgmt-pw-file
chmod 700 /etc/openvpn/mgmt-pw-file
chown root:root /etc/openvpn/mgmt-pw-file

Everything should be setup for the server side, now we need to edht /etc/default/openvpn to make sure that this configuration get started when using the init script. So, edit that file and make sure it contains:

AUTOSTART="server"

O’rite, you can now restart openvpn service with:

# /etc/init.d/openvpn restart

Now, our server should be up and running. If anything went wrong, /var/log/daemon.log is the place to look into.

At this stage, you should also be able to connect to localhost on TCP port 1194 using telnet. You will be prompted for a password, this is the password you have set in /etc/openvpn/mgmt-pw-file.

Once you logged in, you will be able to access the management interface of openvn!

Enabling IP forwarding

As we will be routing packets, we need to enable IP forwarding. To do this create a file called /etc/sysctl.d/forwarding.conf which contains:

net.ipv4.ip_forward=1

And apply the change with:

[email protected]:~# sysctl -p /etc/sysctl.d/forwarding.conf
net.ipv4.ip_forward = 1

IPTable

At this stage, the openvpn server could handle clients, forward packets, but packets would be routed with their original private IP. To give proper network connectivity to our OpenVPN clients, we will need to NAT the traffic.

This can be done by using the following command:

[email protected]:~# iptables -t nat -I POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Configuring Iptable is not in the scope of this article. You might want to refer to IPtables: how to share your internet connection.

Anyhow, let’s move forward and set up a client!

Client configuration

To get the client configuration set, you will need to provide the following file:

  • ta.key
  • ca.crt
# mkdir clientconfig
# cp /etc/openvpn/easy-rsa/2.0/keys/{ca.crt,ta.key} clientconfig/

And finally create the config file clientconfig/client.ovpn

client
dev tun
proto udp
# change to your vpn server
remote 172.16.132.5 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
ns-cert-type server
tls-auth ta.key 1
# in UDP mode, explicitely notify
# the server that we exit
# send up to 3 attempts
explicit-exit-notify 3
comp-lzo
verb 3
auth-user-pass

Finally, provide the clientconfig folder and its content to a client.

I would recommend using network-manager-openvpn package on Debian/Ubuntu. It is a easy as importing the configuration through network-manager wizard.

Another way to connect to your newly intalled openvpn server is to run the following command:

[email protected]:~/clientconfig$ sudo openvpn ovpn.ovpn 
Tue Jan 15 20:22:14 2013 OpenVPN 2.2.1 x86_64-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110424-2 (2.2RC2)] built on Oct  8 2012
Enter Auth Username:chantra
Enter Auth Password:
Tue Jan 15 20:22:22 2013 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Tue Jan 15 20:22:22 2013 Control Channel Authentication: using 'ta.key' as a OpenVPN static key file
Tue Jan 15 20:22:22 2013 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Jan 15 20:22:22 2013 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Jan 15 20:22:22 2013 LZO compression initialized
Tue Jan 15 20:22:22 2013 Control Channel MTU parms [ L:1542 D:166 EF:66 EB:0 ET:0 EL:0 ]
Tue Jan 15 20:22:22 2013 Socket Buffers: R=[212992->131072] S=[212992->131072]
Tue Jan 15 20:22:22 2013 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Tue Jan 15 20:22:22 2013 Local Options hash (VER=V4): '504e774e'
Tue Jan 15 20:22:22 2013 Expected Remote Options hash (VER=V4): '14168603'
Tue Jan 15 20:22:22 2013 NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
Tue Jan 15 20:22:22 2013 UDPv4 link local: [undef]
Tue Jan 15 20:22:22 2013 UDPv4 link remote: [AF_INET]172.16.132.5:1194
Tue Jan 15 20:22:22 2013 TLS: Initial packet from [AF_INET]172.16.132.5:1194, sid=8c1e69ca 24d3f240
Tue Jan 15 20:22:22 2013 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Tue Jan 15 20:22:22 2013 VERIFY OK: depth=1, /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/CN=Fort-Funston [email protected]
Tue Jan 15 20:22:22 2013 VERIFY OK: nsCertType=SERVER
Tue Jan 15 20:22:22 2013 VERIFY OK: depth=0, /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/CN=Fort-Funston [email protected]
Tue Jan 15 20:22:22 2013 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Tue Jan 15 20:22:22 2013 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Jan 15 20:22:22 2013 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Tue Jan 15 20:22:22 2013 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Jan 15 20:22:22 2013 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
Tue Jan 15 20:22:22 2013 [frd1h01] Peer Connection Initiated with [AF_INET]172.16.132.5:1194
Tue Jan 15 20:22:24 2013 SENT CONTROL [frd1h01]: 'PUSH_REQUEST' (status=1)
Tue Jan 15 20:22:24 2013 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 10.8.0.1,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.0.2 255.255.255.0'
Tue Jan 15 20:22:24 2013 OPTIONS IMPORT: timers and/or timeouts modified
Tue Jan 15 20:22:24 2013 OPTIONS IMPORT: --ifconfig/up options modified
Tue Jan 15 20:22:24 2013 OPTIONS IMPORT: route options modified
Tue Jan 15 20:22:24 2013 OPTIONS IMPORT: route-related options modified
Tue Jan 15 20:22:24 2013 OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
Tue Jan 15 20:22:24 2013 ROUTE default_gateway=172.16.132.2
Tue Jan 15 20:22:24 2013 TUN/TAP device tun0 opened
Tue Jan 15 20:22:24 2013 TUN/TAP TX queue length set to 100
Tue Jan 15 20:22:24 2013 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Tue Jan 15 20:22:24 2013 /sbin/ifconfig tun0 10.8.0.2 netmask 255.255.255.0 mtu 1500 broadcast 10.8.0.255
Tue Jan 15 20:22:24 2013 /sbin/route add -net 172.16.132.5 netmask 255.255.255.255 gw 172.16.132.2
Tue Jan 15 20:22:24 2013 /sbin/route add -net 0.0.0.0 netmask 128.0.0.0 gw 10.8.0.1
Tue Jan 15 20:22:24 2013 /sbin/route add -net 128.0.0.0 netmask 128.0.0.0 gw 10.8.0.1
Tue Jan 15 20:22:24 2013 GID set to nogroup
Tue Jan 15 20:22:24 2013 UID set to nobody
Tue Jan 15 20:22:24 2013 Initialization Sequence Completed

That’s it, you should now be able to connect to your OpenVPN server and encrypt all the traffic between your workstation and your server!