OpenVPN

The following guide shows how to install and configure OpenVPN for use on your VPS.

Installation

Debian

As root:

apt-get install openvpn

CentOS

As root:

rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
yum update
yum install openvpn

Configuration

Certificate Configuration

To configure OpenVZ, simply run the following commands as root.

cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /etc/openvpn/ca
cd /etc/openvpn/ca
nano -w vars

Note: newer versions of openvpn do not ship easy-rsa in the package anymore. You can download the latest version of easy-rsa from github at the following address: https://github.com/OpenVPN/easy-rsa/archive/master.zip

It is recommended to change the default RSA key size to 2048 on the line export KEY_SIZE=1024.

For centos, the path would be /usr/share/openvpn/easy-rsa/2.0/. The sample configuration files will also be in the /usr/share/openvpn path.

With vars open, edit the values as needed (city, etc), then use Ctrl-X to save and exit nano.

source ./vars
./clean-all
./build-ca
./build-key-server server
./build-dh

Now generate a client certificate. You'll make one of these per client, use a different name for each one.

./build-key <CLIENTNAME>

Choose 'Yes' to sign and commit the keys. If desired, the passwords may be left empty (recommended).

Server Configuration

Copy the example configuration file to /etc/openvpn

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn
cd /etc/openvpn
gunzip server.conf.gz

Change the lines for ca, cert, key, and dh to point to the files created by easy-rsa, which will look like the following:

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

Uncomment the lines for user, group, and maxclients. Set max-clients to something reasonable.

user nobody
group nogroup
max-clients 10

If you want all traffic to be routed over the vpn (true in most cases, including US VPN), uncomment the following line

push "redirect-gateway def1 bypass-dhcp"

Under redirect-gateway, add the following two lines, to add DNS to clients on connect.

push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 4.2.2.2"

If you plan on using the us vpn, change the server line to use 10.0.0.0

server 10.0.0.0 255.255.255.0

Otherwise add the following rule to your firewall.

iptables -t nat -A POSTROUTING -s <SERVER_NET> -j SNAT --to <EXTERNAL IP>

You may need this to be more specific if you're routing over more than one interface. In that case, adding -o venet0 (openvz) or -o eth0 (kvm) may be appropriate.

If your iptables policy for the FORWARD chain is not set to ACCEPT, you may need the following rules:

iptables -A FORWARD -o <venet0 or eth0> -i tun0 -j ACCEPT
iptables -A FORWARD -o tun0 -i <venet0 or eth0> -m state --state RELATED,ESTABLISHED -j ACCEPT

Without comments, the final config should look something like this

$ egrep -v '^(#|;|$)' /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/ca/keys/ca.crt
cert /etc/openvpn/ca/keys/server.crt
key /etc/openvpn/ca/keys/server.key  # This file should be kept secret
dh /etc/openvpn/ca/keys/dh1024.pem
server 10.0.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 4.2.2.2"
keepalive 10 120
comp-lzo
max-clients 10
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3

Start it as root

/etc/init.d/openvpn start

Client Configuration

For all but the smallest vpn servers, you'll want a different certificate per client. Refer to the Certificate Configuration above for how to generate client keys.

Copy the example configuration file to the working directory. Replace CLIENTNAME with the name you picked for the certificate above.

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf $HOME/client-<CLIENTNAME>.ovpn

Put the certificate, ca, and key inline in the client config file. Change the first line of the following script to match CLIENTNAME from above and execute it.

clientname=<CLIENTNAME>
clientfile=$HOME/client-${clientname}.ovpn
echo "<ca>" >> $clientfile
openssl x509 -in /etc/openvpn/ca/keys/ca.crt >> $clientfile
echo "</ca>" >> $clientfile
echo "<cert>" >> $clientfile
openssl x509 -in /etc/openvpn/ca/keys/${clientname}.crt >> $clientfile
echo "</cert>" >> $clientfile
echo "<key>" >> $clientfile
openssl rsa -in /etc/openvpn/ca/keys/${clientname}.key >> $clientfile
echo "</key>" >> $clientfile

Remove the following lines for ca, cert, and key

ca ca.crt
cert client.crt
key client.key

Change the server address to the address or hostname of your server.

remote <SERVER NAME> 1194

Now send the client config to the user/machine where it will be used and test it by starting openvpn.

Things to check if it doesn't work

Check that your ip_forwarding is on.

cat /proc/sys/net/ipv4/ip_forward

If not, edit /etc/sysctl.conf and uncomment or add the following line.

net.ipv4.ip_forward=1

Then apply the changes

sysctl -p

Check that the tun device is available. It should report the second line.

$ cat /dev/net/tun
cat: /dev/net/tun: File descriptor in bad state

If it isn't available on a KVM, you'll have to modprobe tun. It is available on all of the ovz nodes.