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.
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"
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.
- cd /etc/openvpn/easy-rsa2.
- . ./vars
(the "." before "./vars" is essential! Without it vars will be executed in a subshell and could not export variables.)
Enter OpenVPN-CA as common name here.
- ./build-key-server server
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).
Important note: we are still working on our server!
- . ./vars
- ./build-key OpenVPN-Outstation-1
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
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.
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.