OpenVPN tunnel - setup

Read here how to connect two networks with OpenVPN over the Internet. In my case, the server is an Ubuntu 8.04 and the client is OpenSuse 10.2. It should work similar for other distributions but maybe details (like packet names) may differ. (Indeed, meanwhile the server is Ubuntu 12.04 but it doesn't matter)

I chose a routed tunnel (not a bridged one). What's the difference? Like in my case, in most situations there are two networks, independently grown, which happen to have not the same network mask (e.g. one is 192.168.0.0/24, the other 10.0.0.0/8). My clients are mostly Windows-machines in both networks.

With a bridged tunnel, all clients have to be in the same network. So all broadcasts have to be passed over the tunnel. The tunnel just seems to be a virtual ethernet cable, thats the advantage. But this is also the disadvantage, the higher traffic. It can be considerably high if your network has many clients and can consume a considerable amount of a low bandwith Internet connection. The advantage would be that e.g. Windows-clients could browse the complete bulk of machines, could see printers etc.. In most cases, this is not only unnecessary but also unwanted.

With a routed tunnel, clients on both sides are in different networks but they can reach each other via predefined routes. There is zero stand-by-traffic and the full Internet bandwith is available for data transmission. But if a Windows-client browses his Network Neighborhood he will not see clients on the other side of the tunnel. But he could access them if the remote name is known to the local DNS or to the local machine (via hosts-file) or if he uses the remote IP (i.e. type \\10.0.0.x in his windows-explorer).
With a routed tunnel, the connected nets must not be in the same subnet. If they happen to be, you must decide which one to switch over to a different one.

About this howto

Well, this is not a real howto but more a protocol of my way to solve the problem.

I did not record every key I pressed when I set up my tunnel. So it is required that you think a little bit over what you're doing. But I hope that my description will help you a few steps on your way, either in the decision or the realization phase of your project.

If you find something wrong or something you think that should be mentioned, feel free to contact me.

I hate howtos cursing the Internet for decades that are no longer of use with current versions trying to solve problems that do no longer exist for years or suggest solutions that only work with a particular configuration and can completely mess up a modern setup. So this page is subject to be updated any time or disappear without notice if it is no longer relevant.

Prequisites

Install the packets ipsec-tools and openvpn on both machines.

The directory /etc/openvpn is mostly empty after that.
According to Ubuntuusers: sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gunzip /etc/openvpn/server.conf.gz
sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa2
You may want to adjust the variables in /etc/openvpn/easy-rsa2/vars: export KEY_COUNTRY="DE"
export KEY_PROVINCE="BY"
export KEY_CITY="Nuremberg"
export KEY_ORG="Your-Company-Name"
export KEY_EMAIL="certmaster@your-company.com"
I set the timeout for the certificates to 10 years (3650 days). In ten years from now, the creation of the certificates would have to be done again.
On the client machine, you need the client.conf of course and you can omit easy-rsa.

Creating the CA and the server certificate

To avoid foreign systems to use the tunnel you will have to setup a certificate based authentication. For the server the following has to be done once:

OpenVPN includes some scripts which ease up your work. The howto at openvpn.net gives some help.

and then:

Answer the questions "sign" and "commit" with "y".

The files ca.crt server.crt and server.key have been created in easy-rsa2/keys and have to be moved to /etc/openvpn.

You have to execute (in /etc/openvpn/easy-rsa2 as well) openssl dhparam -out dh1024.pem 1024 and move dh1024.pem to /etc/openvpn (see also server.conf).

Client certificate

Important note: we are still working on our server!

Again, answer "sign" and "commit" with "y".
OpenVPN-Outstation-1 is a meaningful name to identify the client net. You can choose the name freely but choose it wisely if you want to keep oversight if the number of client networks increases. Of course the name must be unique for each client.

The key is created on the server for now. Later we will need it on the client. Move it over a secure channel (scp or an usb-stick). In the client's /etc/openvpn you should later find the files ca.crt, client.crt, client.key and client.conf. Important: client.key is only readable for root (mod 0600).

Note: if client.key would be world-readable, every user (or everyone who hacked a weakly protected user-account) could make a copy of it and could establish the tunnel. If he also succeeded with the server.key he could even do a man-in-the-middle-attack (unnoticeable passive or active participation in the tunnel-traffic). Even if the normal user cannot read the directory, guessing the full path of the files is not really challenging.

If you start OpenVPN on both endpoints now, your syslog should show no errors and the tunnel is established.

Allowing clients of both nets

In the following, the client net is referred to as 192.168.0.0/24 and the server net is assumed to be 10.0.0.0/8

We use a routed tunnel. It directly connects only the two endpoints for now. Clients of one net cannot reach clients of the other.

To reach clients of the server net, its IP-range has to be announced to the client endpoint. This is done by an entry push "route 10.0.0.0 255.0.0.0" in the server.conf. The client net knows now that traffic to 10.0.0.0/8 has to be directed to the tunnel.
If the server is somehow connected to other networks you wish to traverse the tunnel, you can add a line for each of them.

Now from the client-side all machines of the server's net can be reached. Unfortunately, they cannot answer since they do not know the gateway to send the packets to (if the server is not the default gateway for its net).

My solution is to manually add the route on the default gateway of the server net.

For machines in the client net to use the tunnel, you have to create a directory and to list it in the server.conf: client-config-dir ccdCreate a file with the name of the client (e.g. OpenVPN-Outstation-1) in it for every client net containing the route as plain text: iroute 192.168.0.0 255.255.255.0 So the server knows that traffic to 192.168.0.0 goes to OpenVPN-Outstation-1.

Since machines of the client net should be able to reach clients of the server net, you have to add client-to-client
push "route 192.168.0.0 255.255.255.0"
to the server.conf.

Since in both networks (in my case) the OpenVPN-endpoints are not the default gateways you have to manually add a route there directing traffic for the VPN to the according endpoint and the firewall of course has to accept that.
The Server knows how to reach the opposite part. Other machines try via the default gateway. So a firewall rule like iptables -I FORWARD -s 10.0.0.0/8 -d 192.168.0.0/24 -j ACCEPT is needed.

Client settings

On the client-side the problem is similar. Here my gateway is a Fritz!box and you have to add a route here pointing to the tunneling machine.

In the firewall of the client following rules have to be added: iptables -I FORWARD -d 192.168.0.0/24 -s 10.0.0.0/8 -j ACCEPT
iptables -I FORWARD -s 192.168.0.0/24 -d 10.0.0.0/8 -j ACCEPT

In real world, you may want more restrictive firewall rules if you do not want every remote machine to reach any client machine. The VPN only connects the networks. Restrictions have to be implemented separately.