From FreeBSDwiki
Jump to: navigation, search

OpenVPN is a very useful open source, cross platform Virtual Private Networking tool. It uses SSL encryption (dynamic or 2048-bit static shared key), can use LZO stream compression, and is blindingly fast as well as much more secure compared to typical industry standard IPSEC + DES or IPSEC + 3DES solutions. Better yet, it's so simple it can be run entirely from the command line.


To build it on a FreeBSD machine, just:

cd /usr/ports/security/openvpn
make install clean

it's that easy. Actually doing anything with it will require a little more work. There are many MANY ways to do this, but this one's useful, simple, and clean.

First, generate yourself a private key file and chmod it so that only its owner can read it:

ph34r# openvpn --genkey --secret /usr/local/etc/openvpn.key
ph34r# chmod 400 /usr/local/etc/openvpn.key

Starting OpenVPN

Now you'll need a command to start it with. It can be done purely from the command line - and in fact, in one sense, that's exactly what we're going to do - but to make our lives a little easier, we'll actually use command line stuff from a shell script in /usr/local/etc/rc.d. So place this - or something similar - in your /usr/local/etc/rc.d:


case "$1" in
       # VPN subnets are contained in 10.10.x.x /
       # port range forwarded through the router is 4900-4982 
       # first make sure the TAP module is loaded
       kldload if_tap 

       # now ensure IP forwarding is enabled
       /sbin/sysctl -w net.inet.ip.forwarding=1

       # Now, make sure there are enough tun* / tap* devices in /dev
       cd /dev
       /bin/sh MAKEDEV tap0 tap1 tap2 tap3 tap4 tap5 tap6 tap7 tap8 tap9

       # Finally, open up for business.
       # A tunnel numbered [x] is configured as follows:
       # device tun[x], port (4900 + [x]), network 10.10.(10 + [x])
       # Client machine is always .2, server is always .1

       # note - ping-restart on server end with disconnected clients
       # seems to be the problem resulting in exhausted mbufs.  Trying
       # ping-restart on client end only and hoping for the best.

       # 0. Server side - dynamic VPN
       /usr/local/sbin/openvpn \
       --dev tap0 --port 4900 --ifconfig \
       --tun-mtu 1500 --tun-mtu-extra 32 --mssfix 1450 --key-method 2 \
       --secret /usr/local/etc/openvpn.key --ping 1 &

#        # 1a. Client side - persistent VPN
#        /usr/local/sbin/openvpn \
#                --dev tap1 \
#                --remote \
#                --secret /usr/local/etc/openvpn.key \
#                --key-method 2 \
#                --port 4901 \
#                --ifconfig \
#                --route \
#                --tun-mtu 1500 --tun-mtu-extra 32 \
#                --fragment 1300 --mssfix \
#                --persist-tun --persist-key --resolv-retry 86400 \
#                --ping 10 --ping-restart 15 \
#                --verb 4 --mute 10 &

       # 1b. Server side - persistent VPN
       /usr/local/sbin/openvpn \
               --dev tap1 \
               --secret /usr/local/etc/openvpn.key \
               --key-method 2 \
               --port 4901 \
               --ifconfig \
               --route \
               --tun-mtu 1500 --tun-mtu-extra 32 \
               --fragment 1300 --mssfix \
               --persist-tun --persist-key --resolv-retry 86400 \
               --ping 10 --ping-restart 15 \
               --verb 4 --mute 10 &

       # end section

       killall openvpn
       echo "Usage: `basename $0` {start|stop}" >&2

exit 0

Don't forget to chmod 755 /usr/local/etc/rc.d/ to make sure you can execute it.

What you've got there is a setup (which can be started up or stopped like any other rc.d script - /usr/local/etc/rc.d/ start or stop) which provides for two tunnels - one coming from a Windows machine, probably a laptop or something (labeled "dynamic VPN"; more on that in a minute) and one (labeled "persistent VPN") from another BSD or other *nix machine.

All we'll do on the other *nix box is copy over the openvpn.key we created on this machine, copy over this same script, comment out the:

  • # 1b. Server side - persistent VPN section
  • uncomment the # 1a. Client side - persistent VPN side
  • and fire it up.

Once the scripts have been started on both machines (obviously you'll need a routeable IP address for at least the machine on the "server" side), presto, you've got a tunnel!

Obviously this article is unfinished, but work beckons. More later. is a webmin module for controlling the openvpn (and CA-related tunnels), if you're not all CLI-hardcore like Jimbo.

Personal tools