Persistent VPNC Connections

This post describes a quick way to set up persistent VPNC connections in Ubuntu.

VPNC is an open source client that allows you to connect to Cisco VPN concentrators without the usual Cisco VPN software.  Often it is faster than the Cisco VPN client itself.

One major drawback of vpnc though is that it does not keep connections up indefinitely.  Should the connection fail or time out, the connection will not come up again.

Here I present a quick solution that adds an init script to vpnc.  The init script takes the usual start and stop commands and keeps the connection persistent using some other trickery.

To accomplish this, we exploit the fact that VPNC runs a script when the tunnel is torn down.  We can use this script to re-launch VPNC and thus keep the connection running.

There is one catch though.  We can’t simply re-run vpnc in the script, otherwise we could potentially run in to race conditions, resource conflicts and other nasty surprises as the tunnel is being torn down while the script is running.

To avoid this situation, I’ve written a quick shell script that re-invokes vpnc after a 5 second delay.  The script is called by the vpnc disconnection script and placed in the background.  This allows the connection to be torn down in time for the script to run and reestablish the connection.

VPNC by default runs the following script both when the connection is established and when it is being torn down:

/etc/vpnc/vpnc-script

On Ubuntu/Debian, the script is split futher into two other scripts; one for connection and one for disconnection.  If your distribution does not have this split, have a look at the Ubuntu copy.  Basically there is an environment variable called $reason which is either pre-connect, connect or disconnect.  You can use this to put an if statement together to differentiate the reason.

In Ubuntu/Debian the disconnection script is placed in the following location:

/etc/vpnc/vpnc-script-disconnect-action

In the above file, place the following contents:

#!/bin/sh

if [ ! -e /var/run/vpnc/disconnect ]; then
    bash /etc/vpnc/reconnect-script &
fi

Then create a file called /etc/vpnc/reconnect-script, and paste the following contents:

#!/bin/bash

sleep 5

. /etc/default/vpnc

for c in ${CONFIG}; do
    vpnc-connect ${c} &
done

Now create the file /etc/init.d/vpnc and paste in the following contents:

#!/bin/bash

. /lib/lsb/init-functions

case "$1" in
    start)
        log_begin_msg "Starting vpnc connections..."
        . /etc/default/vpnc

        rm -f /var/run/vpnc/disconnect
        . /etc/vpnc/reconnect-script
    ;;

    stop)
        log_begin_msg "Stopping vpnc..."
        touch /var/run/vpnc/disconnect
        vpnc-disconnect &
        log_end_msg $?

    ;;

    restart)
        log_begin_msg "Restarting vpnc..."
        vpnc-disconnect &
        log_end_msg $?
esac
exit 0

Now create the configuration file.  The configuration file is basically a list of .conf files for vpnc to start.  Create the file /etc/default/vpnc and paste in the following contents:

#!/bin/bash

# place all the conf files you want started in the variable CONFIG
CONFIG[0]="/etc/vpnc/my_company.conf"

# For example, the next configuration file would be declared as such:
#CONFIG[1]="/etc/vpnc/another.conf"

Now make sure all the scripts are executable:

chmod a+x /etc/vpnc/reconnect-script /etc/vpnc/vpnc-script-disconnect-action /etc/init.d/vpnc

Now, you simply invoke VPNC like you would any other init script:

/etc/init.d/vpnc start

When the tunnel is torn down, the connection should hopefully re-establish.  When you no longer want the connection, run the following:

/etc/init.d/vpnc stop

Comments are closed.