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
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.) - ./clean-all
- ./build-ca
EnterOpenVPN-CA
or another big with fate name as common name here.
and then:
- ./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) ./build-dh and move dh2048.pem to /etc/openvpn (see also server.conf).
Client certificate
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.
In fact, I have seen networks unexpectedly expanding over several branch offices
(in different cities or even some in the same big city)
and other private extensions (chief's network, subchief's-network and the like)...
Of course the name must be unique for each client.
But now, my boss can print anything on any printer in any of his offices in the world 😀.
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.
Converting to PFX
Some Clients (like Android) cannot use CRT and KEY Files but need PFX instead. This can be done by
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 endpoint 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 in /etc/openvpn (e.g. ccd) 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.x 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.
OpenVPN for Windows
While going on vacation, I wanted my laptop to connect to my VPN
Note that this is a different situation, things have changed. Meanwhile the server is in my cellar. So this is about connecting a Windows PC to the server.
The first step: download and install OpenVPN Connect for Windows.
This prooved more tricky than I expected since the Windows client wants a .ovpn file for configuration.
In the documentation they say, edit the .ovpn file. But on my Linux server there was no .ovpn file, nowhere! After some research I found that it is simply the client.conf! On Linux systems the file has the extension .conf, on Windows systems .ovpn but it is the same file! So just rename the client.conf to client.ovpn and you're almost done!
Well, almost. The tricky thing is that you cannot just specify the certificate and key files but they have to be embedded into the client.ovpn.
After some research, I found you have to comment out the lines
cert client.crt
key client.key
and replace them by XML like statements like
(paste the content of ca.crt here)
</ca>
<cert>
(paste the content of client.crt here)
</cert>
<key>
(paste the content of client.key here)
</key>
But still it did not work since I also have a ta.key! The error message was TLS Error: cannot locate HMAC in incoming packet. Well, comment out the line
and do like before but this line has a parameter! I needed lots of time to find out that you'll have to insert a line
before the
(paste the content of ta.key here)
</tls-auth>
and then it worked!
Don't know why they make it so hard for their users... Maybe it is written somewhere in the docs but you will hardly find it, at least I didn't.