OpenVPN
Intro
This isn't a general howto on VPN technology, it isn't even a howto on OpenVPN. You can find those kind of things elsewhere, and hopefully the references I include contain some useful pointers to suitable sites. This is the story of a particular problem I wanted to solve. If you're trying to set up a bridged OpenVPN system perhaps this will be of use to you. Or perhaps it won't. I'm sure when I want to do this again in six months time it'll be of use to me though! :) I needed to access a remote LAN in a small office elsewhere. My main wish was to get direct access to a CVS repository on one of the servers there, but I also thought it would be nice to be able to use a local Windows client to browse shared directories on a remote Windows server.
The 'lab'
Since I could only travel occasionally to the remote site, first of all I set up a 'lab' to try to encounter as many of the problems as I could before deploying. Since I don't have two adsl lines, I couldn't fully simulate the final system, so this was what I started with:
PC A 192.168.3.102 | | 192.168.3.103 pc B 192.168.4.103 | | 192.168.4.33 pc C
My intent was to make the 192.168.3.x subnet equivalent to the Internet, and 192.168.4.x equivalent to the remote LAN, protected by a firewall running in pc B. At this point all 3 PCs had no software installed and each had the BIOS set to boot first from the CD drive.
Why Xubuntu
Why not? :) I'm a fan of Ubuntu, especially since the release of Dapper in June 2006, which worked much more smoothly for me than Breezy before it. And because I'm generally working on slower hardware with less memory, I like Xubuntu. No doubt many other distros would work at least as well for this experiment. The 192.168.3.x subnet was also connected to a router to the Internet (not shown in the diagram). A connection to the Internet probably wasn't essential, it's just the way that I'm used to doing it. So first I installed Xubuntu on pc A and pc B, using the alternate 6.06.1 CD.
Why OpenVPN
OpenVPN (
) seems to me elegant and modular. I had a free choice of which software to use. Obviously if both ends of the link had not been under my control I would have had to look at whatever vpn technology was needed to connect to an existing server. But, in chorus with so many other people on the 'net, I'm not an expert, Do Your Own Research! :)
Why bridging, not routing
I'm not at all sure whether I made the right choice here. Routing is described by others as a more scalable solution, but, with just one client connecting to a rather small and underutilised LAN, scalability was of little importance to me. My impression is that you should only resort to a bridged VPN if you find that you can't do what you want with routing. And maybe my failure to do what I wanted with routing was only due to my incompetence, not something fundamental. Still, now that it's working, so far I'm happy with it.
Installing Openvpn
Below I've given command line instructions just because it's easier to describe it that way. Of course you can do this with Synaptic if you prefer a gui. First step was on pc A:
$ sudo apt-get install openvpn
Obviously you need the openvpn package! Later I'll return to why you also need openssl and bridge-utils.
$ sudo apt-get install openssl bridge-utils
Creating certificates
You don't need to create certificates. Some months back I tried using the Windows version of OpenVPN to do what I wanted and on that occasion I used static keys because I was discouraged by the complexity of certificates. I was wrong. Certificates are surprisingly easy. Read
http://openvpn.net/howto.html#pki
if you want more detail. Perhaps gui tools are available for this, but the command line version is easy enough. I started by copying the files for generating the certificates, not wishing to overwrite the original ones. I could have copied them anywhere, but I felt a directory under /etc/openvpn would be sensible.
$ sudo -i # cd /etc/openvpn # mkdir easy-rsa # cd easy-rsa # cp -p -v /usr/share/doc/openvpn/examples/easy-rsa/2.0/ .
(Mention cockup of pkitools.gz instead of pkitools -- needs gunzip) (Mention what happens if you're not psychic and therefore don't realise you need to install openssl)
Installing a firewall
This step is purely for the lab experiment. In the real world pc B is a router. (Add notes on installing Firestarter on pc B)
Installing Xubuntu on pc C
Now that Firestarter was installed, the 192.168.4.x network could reach the Internet through pc B, so I was now ready to install Xubuntu on pc C. With Xubuntu installation complete, this pc was now ready to play the role of the remote server. To make the experiment as realistic as possible, I wanted to do as much as possible on pc C remotely, pretending the keyboard and screen weren't on the next desk! So I installed an SSH server.
$ sudo apt-get install openssh-server
This listens on port 22. To access it from "outside", in other words the 192.168.3.x network, I needed to get Firestarter to forward port 22 to pc C. With that done, I could log in to pc C from pc A, using ssh. From here onwards I never needed to have direct access to pc C.
Setting up the server
$ sudo apt-get install openvpn
/etc/openvpn/server.conf:
port 1194 proto udp dev tap0 ca keys/ca.crt cert keys/server.crt key keys/server.key # This file should be kept secret dh keys/dh1024.pem server-bridge 192.168.4.33 255.255.255.0 192.168.4.41 192.168.4.80 keepalive 10 120 persist-key persist-tun status openvpn-status.log verb 3
Now for the dangerous bit, where I risked losing contact with pc C. First I saved a copy of the file I was about to modify and created a new version.
# cd /etc/network # cp -p -v interfaces interfaces.old # cp -p -v interfaces interfaces.new
I then modified interfaces.new, adding the 2nd part for openvpn (the first part I left as it was). /etc/network/interfaces.new:
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address 192.168.4.33 netmask 255.255.255.0 network 192.168.4.0 broadcast 192.168.4.255 gateway 192.168.4.103 # dns-* options are implemented by the resolvconf package, if installed dns-nameservers 192.168.4.103 # added for openvpn auto br0 iface br0 inet static address 192.168.4.33 netmask 255.255.255.0 network 192.168.4.0 broadcast 192.168.4.255 bridge ports eth0 tap0 gateway 192.168.4.103 dns-nameservers 192.168.4.103 pre-up /usr/sbin/openvpn --mktun --dev tap0 pre-up ifconfig eth0 0.0.0.0 up pre-up ifconfig tap0 0.0.0.0 up pre-up brctl addbr br0 pre-up brctl addif br0 eth0 pre-up brctl addif br0 tap0 ifconfig br0 192.168.4.33 netmask 255.255.255.0 broadcast 192.168.4.255 post-down ifconfig eth0 0.0.0.0 down post-down ifconfig tap0 0.0.0.0 down post-down brctl delif br0 eth0 post-down brctl delif br0 tap0 post-down brctl delbr br0 post-down /usr/sbin/openvpn --rmtun --dev tap0
(Need more here about overwriting interfaces with interfaces.new and rebooting)
Setting up the client
client dev tap proto udp remote 192.168.3.103 1194 resolv-retry infinite nobind persist-key persist-tun ca keys/ca.crt cert keys/client102.crt key keys/client102.key ns-cert-type server log openvpn.log verb 3
Troubleshooting
Hopefully for you this will Just Work. But I didn't get do all the settings correctly (late night? too much coffee?) and had to find out why. Apart from desk checking everything while engaging brain, the method that gave me some clues was to add 'cipher none' at both ends (to turn off encryption), ensure there was no comp-lzo compression at both ends and install and run Ethereal (known these days as WireShark
). Watching the actual packets and figuring out who's not listening to who can be very revealing!
Adding Windows servers and clients
Deploying on the remote site, part 1
Safety net
(Needs details of how I shot myself in the foot when I tried to deploy on the remote system and found that some kind of safety net is a Good Idea) No need to do this if the server is local. This is to try to recover if networking gets hosed. Root terminal, crontab -e
0 3 * * * /root/rollback
This runs at 3am every morning. Obviously if you're impatient you can set this to run more often (at one stage I had it running every 30 minutes) but don't have it running so often that it reboots again before you have a chance to adjust it! Tip: make sure the clocks on the various machines you're running are set to within at least a minute or so, so you don't get nasty surprises, scripts running when you don't expect. Of course, if you use an ntp time server they'll be much more accurate than this. In /root a script file:
#!/bin/bash # script to be run to return system to a good state, e.g. with crontab echo `date` rollback >>/root/rollback.log /root/genreport echo `date` "copy backed up files" >>/root/rollback.log # cp -v -r -p /etc.bak /etc >>/root/rollback.log # above doesn't work, it creates /etc/etc.bak/... # so do the copies individually for now cp -v -p /etc.bak/network/interfaces /etc/network/interfaces >>/root/rollback.log echo "---------- (rebooting)" >>/root/rollback.log /sbin/shutdown -r now
This script in turn runs a useful script, genreport, which saves the state of the networking, which hopefully will be useful afterwards for diagnosing the problem. genreport:
#!/bin/bash # script to report current status echo `date` genreport >>/root/rollback.log echo "route -een >>/root/rollback.log" >>/root/rollback.log route -een >>/root/rollback.log echo "-----" >>/root/rollback.log echo "netstat -an >>/root/rollback.log" >>/root/rollback.log netstat -an >>/root/rollback.log echo "-----" >>/root/rollback.log echo "ifconfig >>/root/rollback.log" >>/root/rollback.log ifconfig >>/root/rollback.log echo "-----" >>/root/rollback.log echo "cat /etc/network/interfaces >>/root/rollback.log" >>/root/rollback.log cat /etc/network/interfaces >>/root/rollback.log echo "-----" >>/root/rollback.log echo "----------" >>/root/rollback.log
The rollback script also copies the saved version of /etc/network/interfaces which I keep in /etc.bak/network/interfaces. It then reboots the server.
Deploying on the remote site, part 2
I now have a bridged vpn running, using an Xubuntu server on the remote site (where there are also Windows servers on the LAN) and I'm able to access these servers from my own clients (both Xubuntu and W2K) even including Windows network browsing of shared files.
References
(Good here? Or include as appropriate within the text??)
- http://gentoo-wiki.com/HOWTO_OpenVPN_Server_for_Ethernet_Bridging_with_Server_Certificates Good description though rather Gentoo oriented in parts
Step by step guide to easy-rsa, the first step in setting up a vpn (assuming you're using certificates)
Mentioned in that thread, haven't viewed yet:
- http://mia.ece.uic.edu/~papers/volans/openvpn1.html
- http://deb.riseup.net/networking/openvpn/
- http://www.batcom-it.net/index.php?option=com_content&task=view&id=32&Itemid=41
- http://www.skippy.net/trac/wiki/OpenVPN
- http://www.packtpub.com/page/OpenVPN:_Building_and_Integrating_Virtual_Private_Networks_Table_of_Contents
- http://www.informit.com/articles/article.asp?p=605499&seqNum=2&rl=1
- http://openvpn.net/papers/BLUG-talk/2.html What is a VPN and how is it different from other security software?