I was first introduced to OpenVPN through IPCop OpenVPN has been a great tool for me. It allows quick and easy AND secure connections to remote networks. By using a VPN, I can use my laptop with confidence, even in an un-trusted or dangerous network. (disclaimer, DefCon is a special case - VPN helps, but is no guarantee...)
But I have two "beefs" with OpenVPN.
- First, I have yet to see it work properly with NetworkManager (or it's KDE equivalent). Network Manager reports that it supports OpenVPN, but it does NOT support the .pk12 certificates that IPCop generates. A browse of the web will find info on how to extract the keys and certs needed to set up Network Manager. I've tried these and they have never ever established a connection for me.
- Second is the need to manually connect a session. This stems from the first flaw above - no nice simple GUI without replacing my existing (and otherwise perfectly capable) networking tool. The only method I knew to establish a connection was to call "openvpn" from the command line. But this approach does not provide a clean method to manage the VPN connection if you are calling a script to start the connection and then do other work.
I've heard rumblings for some time that there was another way to handle making the connections and today I finally had the chance to investigate and automate things.
My scenario is pretty simple. When my workstation is on, I need access to a remote network to facilitate backups and development efforts. I was using this command:
sudo openvpn --config /home/sgrover/vpn/vpn1.ovpn
And the .ovpn file contains something like this (auto-generated by IPCop):
#OpenVPN Server conf tls-client client dev tun proto udp tun-mtu 1400 remote 188.8.131.52 1194 pkcs12 /home/sgrover/vpn/certs/mycert.p12 cipher BF-CBC verb 3 ns-cert-type server
And in a script that would then do work with the connection, I would use the command like this:
sudo openvpn --config /home/sgrover/vpn/vpn1.ovpn & sleep 20 /path/to/custom/script
All I'm doing here is calling the exact same command, but then returning control to the shell (via the & character). Then wait for a short bit while the connection is (hopefully) established. Then call my script to do more work.
The flaw with this approach is that by returning control to the shell, you no longer have control of the connection. But if you DON'T do that, the options to automate calling your action script becomes more complex.
For the record, DO NOT USE THE ABOVE METHODS! There is a cleaner way.
I learned today after a little research that I've been doing it wrong. More to the point, I was using one method that did work, but there is a much better way. And it is very simple as well. Here's the process:
- Copy your .ovpn file to /etc/openvpn. Give it a .conf extension instead of .ovpn. (i.e. sudo cp vpn1.ovpen /etc/openvpn/vpn1.conf)
- Edit the copied .conf file (aka the .ovpn file). Change the "pkcs12" line to reflect the correct absolute path to your certificate (the *.p12 file).
- Start the connection:
sudo /etc/init.d/openvpn start vpn1
Note that the "vpn1" should match the name of your config file without the .conf extension.
- Run ifconfig to verify you have a connection - you should see a "tun0" adapter with an IP address.
- Stop the connection with the same command to start it, except replace the word "start" with "stop".
(NOTE: I'm using a KUbuntu 9.10 based workstation. Your paths may be different if you are using Slackware, Gentoo, Red Hat, SuSE, Mandriva, or some other flavor of Linux.)
At this point, you are done with regards to getting your connection automated. OpenVPN will look into the /etc/openvpn directory for any .conf files and establish those connections WHEN THE SYSTEM STARTS. Or when "/etc/init.d/openvpn start" is run without specifying a particular config file.
You can change this "ALL connections" feature by editing the /etc/default/openvpn file and adding a line with
Where "vpn1" and "vpn2" are the configuration files you want started automatically. (Use the same argument you would to the start command.)
There is one gotcha that bit me. My certificate required a password to access it. This prevents the automated routines from executing properly - the service account is not running in an interactive shell so cannot get a password. For now, I've changed my connection to NOT require a password for the certificate. While this is not ideal, it is still fairly secure. If you know of a way to make this work WITH the password, please let me know!
But, even if you choose to use the password protected certificate, this method is STILL better than what I was using earlier. When you start the connection, you'll be prompted for the password and returned to the command prompt. But now you have full control over the connection.
The only other problem I can see is that my automated scripts need to change a little to not worry about first establishing a connection. But this means I can treat these scripts like any other script now, and schedule cron jobs even. Life gets easier, AND follows the Unix programming principles - do one thing and do it well. In this case establishing a connection is off-loaded to a system intended for this, while my scripts can focus more on the tasks at hand - rsync'ing directories, development tasks, etc.