#!/bin/sh # Automagical vpnc wrapper for FreeBSD to establish a VPN tunnel and routes # # Copyright 2003-2004, Daniel Roethlisberger # All rights reserved. # # Redistribution and use, with or without modification, are permitted # provided that the following conditions are met: # 1. Redistributions must retain the above copyright notice, this list of # conditions and the following disclaimer. # 2. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # $Id: vpnc-wrapper,v 1.10 2004/05/12 13:39:37 roe Exp $ # This script automatically detects your default gateway by looking at your # route tables. It is designed to be run manually after network connectivity # is up, and a working default route is set. It assumes that the VPN gateway # is reachable via the default gateway. # # This script does not need to know any IP addresses or interface names. # You should only need to configure vpnc with the correct address of the # VPN gateway in vpnc.conf -- this script will grep it from there. # # This script does not modify /etc/resolv.conf in any way. Depending on # your setup, you might need to do that manually. # # Exit status of 1 indicates permanent errors (eg., configuration problems) # Exit status of 2 indicates temporary errors (eg., no default route found) # Tested with: # FreeBSD # - 5.2-RELEASE to 5.2.1-RELEASE-p6 # - 5.1-RELEASE # - 4.9-RELEASE # vpnc # - 0.2-rm+zomb-pre8 + libgcrypt-1.2.0 # - 0.2-rm+zomb-pre7 + libgcrypt-1.1.91 # - 0.2-rm+zomb-pre6 + libgcrypt-1.1.12 # Known bugs and limitations: # - This script assumes that you want to route everything through the # VPN tunnel. This implies that there is only a single vpnc tunnel # connected at any given time, and the script will enforce that. # For more sophisticated routing, such as only routing a certain # subnet through the VPN tunnel, you might find it easier to use # vpnc.sh from the security/vpnc port as a starting point. # configuration PREFIX=/usr/local VPNC=vpnc DEFAULT_CONF=$PREFIX/etc/$VPNC.conf SBIN_VPNC=$PREFIX/sbin/$VPNC PIDFILE=/var/run/$VPNC.pid # end of configuration ############################################################################ # Don't touch anything below this line unless you know what you're doing... SELF=`basename -- $0` SELF=${SELF:-$0} DEFAULT_IFTUN=tun0 # ./configure for the system we run on # as a side effect, this ensures that the script is adapted to accomodate # for the particular flavour of BSD we run on. please send me required diffs. sysver=`uname -sr` case "$sysver" in FreeBSD\ 5.*) PING_OPTS="-n -t 3 -o" ;; FreeBSD\ 4.*) PING_OPTS="-n -t 3" ;; *) echo "${SELF}: Your system is not supported yet ($sysver)!" >&2 echo "Please edit the script and submit necessary patches. Aborting..." >&2 exit 1 ;; esac # must be superuser if [ `id -u` -ne 0 ]; then echo "${SELF}: Need superuser privs! Aborting..." >&2 exit 1 fi # check on system binaries SBIN_ROUTE=`which route 2>/dev/null` SBIN_ROUTE=${SBIN_ROUTE:-/sbin/route} SBIN_PING=`which ping 2>/dev/null` SBIN_PING=${SBIN_PING:-/sbin/ping} SBIN_KLDSTAT=`which kldstat 2>/dev/null` SBIN_KLDSTAT=${SBIN_KLDSTAT:-/sbin/kldstat} SBIN_KLDLOAD=`which kldload 2>/dev/null` SBIN_KLDLOAD=${SBIN_KLDLOAD:-/sbin/kldload} for binary in $SBIN_VPNC $SBIN_ROUTE $SBIN_PING $SBIN_KLDSTAT $SBIN_KLDLOAD; do if [ ! -x $binary ]; then echo "${SELF}: Cannot run $binary! Aborting..." >&2 exit 1 fi done # check config file CONF="${2:-$DEFAULT_CONF}" if [ ! -r $CONF ]; then echo "${SELF}: Cannot read $CONF! Aborting..." >&2 exit 1 fi # get tunnel interface IFTUN=`cat $CONF|awk '/^Interface name / { print $3 }'|head -1` IFTUN="${IFTUN:-$DEFAULT_IFTUN}" # get VPN gateway VPNGW=`cat $CONF|awk '/^IPSec gateway / { print $3 }'|head -1` if [ "x$VPNGW" = "x" ]; then echo "${SELF}: No VPN gateway in $CONF! Aborting..." >&2 exit 1 fi # get pid from pidfile, if any PID=`cat $PIDFILE 2>/dev/null` # do the work case "$1" in start) ps -p $PID >/dev/null 2>&1 && { echo "${SELF}: $VPNC is already running! Aborting..." >&2 exit 2 } ROUTER=`$SBIN_ROUTE -n get default|awk '/gateway:/ { print $2 }'` if [ "x$ROUTER" = "x" ]; then echo "${SELF}: Cannot find default gateway! Aborting..." >&2 exit 2 fi $SBIN_PING $PING_OPTS $VPNGW >/dev/null || { echo "${SELF}: Cannot ping VPN gateway $VPNGW! Aborting..." >&2 exit 2 } if [ "x`$SBIN_KLDSTAT|grep if_tun`" = "x" ]; then $SBIN_KLDLOAD if_tun fi echo "${SELF}: Starting $VPNC daemon..." && $SBIN_VPNC --pid-file $PIDFILE $CONF && echo "${SELF}: Changing route table..." && $SBIN_ROUTE add -host $VPNGW $ROUTER && $SBIN_ROUTE delete default && $SBIN_ROUTE add default -interface $IFTUN && echo "${SELF}: done." ;; stop) ps -p $PID >/dev/null 2>&1 || { echo "${SELF}: $VPNC is not running! Aborting..." >&2 exit 2 } ROUTER=`$SBIN_ROUTE -n get $VPNGW|awk '/gateway:/ { print $2 }'` if [ "x$ROUTER" = "x" ]; then echo "${SELF}: Cannot find route to $VPNGW! Aborting..." >&2 exit 2 fi echo "${SELF}: Killing $VPNC daemon..." && kill `cat $PIDFILE` && echo "${SELF}: Changing route table..." && $SBIN_ROUTE delete default && $SBIN_ROUTE add default $ROUTER && $SBIN_ROUTE delete -host $VPNGW && echo "${SELF}: done." ;; kill) echo "${SELF}: Trying to kill the $VPNC daemon process..." kill `cat $PIDFILE` echo "${SELF}: Removing default route..." $SBIN_ROUTE delete default echo "${SELF}: done. You will have to restore the default route manually." ;; *) echo "Usage: ${SELF} {start|stop|kill} [config-file]" >&2 exit 1 ;; esac