Notices


Reply
Thread Tools
Posts: 10 | Thanked: 1 time | Joined on Feb 2007
#1
I did a writeup on installing the OpenVPN applet and an Ubuntu bridged server. Wanted to share in case anyone was looking to do something similar:

http://geekyschmidt.com/2010/02/27/o...ll-ubuntu-9-10
 

The Following User Says Thank You to oneguynick For This Useful Post:
Posts: 74 | Thanked: 34 times | Joined on Jan 2008
#2
Hi oneguynick I am Niv Vaizer ,

How to automate openvpn connection

Motivation
This is a tutorial of how to establish vpn connection that will react to access point change and will shutdown openvpn at home. it will also re-establish connection when moving from a cellular internet connection (3g or gprs) to wifi and vs versa.

I am using openvpn here in layer-2 which means,
I managed to get avahi and UPNP working over openvpn.
So my home music collection appear on my N900 media player, with no configuration.

Here are the steps I took:
1. install dbus-scripts and openvpn

2. second we need to listen-in to dbus messages , reporting network changes. so I added the file /etc/dbus-scripts.d/openvpn :
Code:
#This script will run openvpn when away from home. so I can still 
# access my network. but will close openvpn at home.
/etc/openvpn/dbus.openvpn * * com.nokia.icd status_changed *
3. next here is the script that will be run every time the network status changes /etc/openvpn/dbus.openvpn . Now as we dont want openvpn to be invoked when you are connected directly to the home lan , we use the HOME_ID string. pls save the files created up to now, and see what number your home access point gives. As I use three access points I am using three ID numbers:
  • 78967400-a235-4a4e-91d2-9ca80c250247
  • b4419dd9-5dca-4ca6-bba8-eaba34668e9a
  • cb5d0bdf-a8e7-4bda-ad88-641e893580ef
please fix it according to your saved connections.

Code:
#!/bin/sh 
# /etc/openvpn/dbus.openvpn
# This script is invoked by dbus-scripts when connection changes
# state.
                                                                             
LOG=/var/log/dbus.openvpn.log
STATUS_FILE=/var/log/dbus.openvpn-status
DAEMON="/etc/init.d/openvpn"
DHCP_CLIENT="/etc/init.d/udhcpc"
NAME="dbusScriptsOpenvpn"
DESC="Sipn openvpn daemon up and down by dbus-scripts"
CONN_STATE="/tmp/openvpnConnected"
# Connection serial in saved connection database 
CONN_ID=$5
#$6 is GPRS or WLAN_INFRA or WLAN_ADHOC
TYPE=$6
STATUS=$7
HOME_ID='78967400-a235-4a4e-91d2-9ca80c250247 b4419dd9-5dca-4ca6-bba8-eaba34668e9a cb5d0bdf-a8e7-4bda-ad88-641e893580ef'
args() {
	date  >>$LOG
        Count=0
        for arg in "$@*" ; do
                Count=$(( $Count + 1 ))
                echo -n "$Count : $arg" >>$LOG
        done                
}
args $@
#current connection state is "connected"
if test -f "$CONN_STATE" ; then
	case "$STATUS" in
		CONNECTED)
			flag=1
			for id in $HOME_ID ; do
				if test "x$CONN_ID" = "x$id" ; then
					echo "Home lan sensed. killing openvpn"  >>$LOG
					$DAEMON stop >>$LOG
					$DHCP_CLIENT stop >>$LOG
					rm -f $CONN_STATE
					flag=0
					break
				fi
			done
			if test $flag == 1 ;then
				if ! grep -q $TYPE $CONN_STATE 2>/dev/null; then
					#leave openvpn figure out a NIC change $DAEMON restart >>$LOG
					echo $TYPE > $CONN_STATE
					#else see above $DAEMON restart >>$LOG
				fi
			fi
		;;
		IDLE)
			echo "current state is connectd and I got Idle msg"  >>$LOG 
			echo "type is $TYPE"  >>$LOG 
			if grep -q $TYPE $CONN_STATE ; then
				echo "current connection went idle , killing openvpn"  >>$LOG
				$DAEMON stop >>$LOG
				$DHCP_CLIENT stop >>$LOG
				rm -f $CONN_STATE
			fi
		;;
		SCAN_START|SCAN_STOP|CONNECTING|DISCONNECTING)
		;;
		*)
			echo "Error: got this status: $STATUS while being connected" >>$LOG
	esac
#current connection state is "not connected"
else	case "$STATUS" in
		CONNECTED)
			#if connected to home access point dont run openvpn
			if test "x$CONN_ID" = "x$HOME_ID" ; then
				echo "Home lan sensed. leaving not connected"  >>$LOG
			else
				echo "Starting $DESC:" >>$LOG
				$DAEMON start >>$LOG 
				#if [ "$?" -ne 0 ];then 
					echo $TYPE > $CONN_STATE
				#fi
			fi
		;;
		SCAN_START|SCAN_STOP|CONNECTING|DISCONNECTING)
		;;
		*) 
			echo "Error in calling /etc/openvpn/dbus.openvpn" >>$LOG
	esac
fi


#	wget http://www.whatismyip.com -T 10 -O - -o /dev/null
#		if [ "$?" -ne 0 ];then 
#			$DAEMON stop >>$LOG
#			echo "failed to access inet"  >>$LOG
#		fi	
exit 0
4. as I am using openvpn in layer-2 there are two more changes I made. first I edited the openvpn init script to call a dhcp client, /etc/init.d/openvpn :
Code:
#!/bin/sh -e

### BEGIN INIT INFO
# Provides:          openvpn
# Required-Start:    $network $remote_fs $syslog
# Required-Stop:     $network $remote_fs $syslog
# X-Interactive:     true
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Openvpn VPN service
### END INIT INFO

# Original version by Robert Leslie
# <rob@mars.org>, edited by iwj and cs
# Modified for openvpn by Alberto Gonzalez Iniesta <agi@inittab.org>
# Modified for restarting / starting / stopping single tunnels by Richard Mueller <mueller@teamix.net>

. /lib/lsb/init-functions

test $DEBIAN_SCRIPT_DEBUG && set -v -x

DAEMON=/usr/sbin/openvpn
DESC="virtual private network daemon"
CONFIG_DIR=/etc/openvpn
test -x $DAEMON || exit 0
test -d $CONFIG_DIR || exit 0

# Source defaults file; edit that file to configure this script.
AUTOSTART="all"
STATUSREFRESH=10
if test -e /etc/default/openvpn ; then
  . /etc/default/openvpn
fi

start_vpn () {
    if grep -q '^[	 ]*daemon' $CONFIG_DIR/$NAME.conf ; then
      # daemon already given in config file
      DAEMONARG=
    else
      # need to daemonize
      DAEMONARG="--daemon ovpn-$NAME"
    fi

    if grep -q '^[	 ]*status ' $CONFIG_DIR/$NAME.conf ; then
      # status file already given in config file
      STATUSARG=""
    elif test $STATUSREFRESH -eq 0 ; then
      # default status file disabled in /etc/default/openvpn
      STATUSARG=""
    else
      # prepare default status file
      STATUSARG="--status /var/run/openvpn.$NAME.status $STATUSREFRESH"
    fi

    log_progress_msg "$NAME"
    STATUS=0

#echo "running $DAEMON -- $OPTARGS --writepid /var/run/openvpn.$NAME.pid $DAEMONARG $STATUSARG --cd $CONFIG_DIR  --up "/etc/init.d/udhcpc start"  --down "/etc/init.d/udhcpc stop" --config $CONFIG_DIR/$NAME.conf --script-security 2 --up-delay"
    start-stop-daemon --start --quiet --oknodo \
        --pidfile /var/run/openvpn.$NAME.pid \
        --exec $DAEMON -- $OPTARGS --writepid /var/run/openvpn.$NAME.pid \
        $DAEMONARG $STATUSARG --cd $CONFIG_DIR \
        --config $CONFIG_DIR/$NAME.conf || STATUS=1
}

#	--script-security 2 --up-delay --up "/etc/init.d/udhcpc start" \ 
stop_vpn () {
 start-stop-daemon --stop --quiet \
                --exec /usr/sbin/openvpn --pidfile $PIDFILE
  
kill `cat $PIDFILE` || true
  rm -f $PIDFILE
  rm -f /var/run/openvpn.$NAME.status 2> /dev/null
}

case "$1" in
start)
  log_daemon_msg "Starting $DESC"

  # autostart VPNs
  if test -z "$2" ; then
    # check if automatic startup is disabled by AUTOSTART=none
    if test "x$AUTOSTART" = "xnone" -o -z "$AUTOSTART" ; then
      log_warning_msg " Autostart disabled."
      exit 0
    fi
    if test -z "$AUTOSTART" -o "x$AUTOSTART" = "xall" ; then
      # all VPNs shall be started automatically
      for CONFIG in `cd $CONFIG_DIR; ls *.conf 2> /dev/null`; do
        NAME=${CONFIG%%.conf}
        start_vpn
	sleep 5
	/etc/init.d/udhcpc start 
      done
    else
      # start only specified VPNs
      for NAME in $AUTOSTART ; do
        if test -e $CONFIG_DIR/$NAME.conf ; then
          start_vpn
        else
          log_failure_msg "No such VPN: $NAME"
          STATUS=1
        fi
      done
    fi
  #start VPNs from command line
  else
    while shift ; do
      [ -z "$1" ] && break
      if test -e $CONFIG_DIR/$1.conf ; then
        NAME=$1
        start_vpn
      else
       log_failure_msg " No such VPN: $1"
       STATUS=1
      fi
    done
  fi
  log_end_msg ${STATUS:-0}

  ;;
stop)
  log_daemon_msg "Stopping $DESC"
  if test -z "$2" ; then
    for PIDFILE in `ls /var/run/openvpn.*.pid 2> /dev/null`; do
      NAME=`echo $PIDFILE | cut -c18-`
      NAME=${NAME%%.pid}
      stop_vpn
      log_progress_msg "$NAME"
    done
  else
    while shift ; do
      [ -z "$1" ] && break
      if test -e /var/run/openvpn.$1.pid ; then
        PIDFILE=`ls /var/run/openvpn.$1.pid 2> /dev/null`
        NAME=`echo $PIDFILE | cut -c18-`
        NAME=${NAME%%.pid}
        stop_vpn
        log_progress_msg "$NAME"
      else
        log_failure_msg " (failure: No such VPN is running: $1)"
      fi
    done
  fi
  log_end_msg 0
  ;;
# Only 'reload' running VPNs. New ones will only start with 'start' or 'restart'.
reload|force-reload)
 log_daemon_msg "Reloading $DESC"
  for PIDFILE in `ls /var/run/openvpn.*.pid 2> /dev/null`; do
    NAME=`echo $PIDFILE | cut -c18-`
    NAME=${NAME%%.pid}
# If openvpn if running under a different user than root we'll need to restart
    if egrep '^[[:blank:]]*user[[:blank:]]' $CONFIG_DIR/$NAME.conf > /dev/null 2>&1 ; then
      stop_vpn
      sleep 1
      start_vpn
      log_progress_msg "(restarted)"
    else
      kill -HUP `cat $PIDFILE` || true
    log_progress_msg "$NAME"
    fi
  done
  log_end_msg 0
  ;;

# Only 'soft-restart' running VPNs. New ones will only start with 'start' or 'restart'.
soft-restart)
 log_daemon_msg "$DESC sending SIGUSR1"
  for PIDFILE in `ls /var/run/openvpn.*.pid 2> /dev/null`; do
    NAME=`echo $PIDFILE | cut -c18-`
    NAME=${NAME%%.pid}
    kill -USR1 `cat $PIDFILE` || true
    log_progress_msg "$NAME"
  done
  log_end_msg 0
 ;;

restart)
  shift
  $0 stop ${@}
  sleep 1
  $0 start ${@}
  ;;
cond-restart)
  log_daemon_msg "Restarting $DESC."
  for PIDFILE in `ls /var/run/openvpn.*.pid 2> /dev/null`; do
    NAME=`echo $PIDFILE | cut -c18-`
    NAME=${NAME%%.pid}
    stop_vpn
    sleep 1
    start_vpn
  done
  log_end_msg 0
  ;;
status)
  GLOBAL_STATUS=0
  if test -z "$2" ; then
    # We want status for all defined VPNs.
    # Returns success if all autostarted VPNs are defined and running
    if test "x$AUTOSTART" = "xnone" ; then
      # Consider it a failure if AUTOSTART=none
      log_warning_msg "No VPN autostarted"
      GLOBAL_STATUS=1
    else
      if ! test -z "$AUTOSTART" -o "x$AUTOSTART" = "xall" ; then
        # Consider it a failure if one of the autostarted VPN is not defined
        for VPN in $AUTOSTART ; do
          if ! test -f $CONFIG_DIR/$VPN.conf ; then
            log_warning_msg "VPN '$VPN' is in AUTOSTART but is not defined"
            GLOBAL_STATUS=1
          fi
        done
      fi
    fi
    for CONFIG in `cd $CONFIG_DIR; ls *.conf 2> /dev/null`; do
      NAME=${CONFIG%%.conf}
      # Is it an autostarted VPN ?
      if test -z "$AUTOSTART" -o "x$AUTOSTART" = "xall" ; then
        AUTOVPN=1
      else
        if test "x$AUTOSTART" = "xnone" ; then
          AUTOVPN=0
        else
          AUTOVPN=0
          for VPN in $AUTOSTART; do
            if test "x$VPN" = "x$NAME" ; then
              AUTOVPN=1
            fi
          done
        fi
      fi
      if test "x$AUTOVPN" = "x1" ; then
        # If it is autostarted, then it contributes to global status
        status_of_proc -p /var/run/openvpn.${NAME}.pid openvpn "VPN '${NAME}'" || GLOBAL_STATUS=1
      else
        status_of_proc -p /var/run/openvpn.${NAME}.pid openvpn "VPN '${NAME}' (non autostarted)" || true
      fi
    done
  else
    # We just want status for specified VPNs.
    # Returns success if all specified VPNs are defined and running
    while shift ; do
      [ -z "$1" ] && break
      NAME=$1
      if test -e $CONFIG_DIR/$NAME.conf ; then
        # Config exists
        status_of_proc -p /var/run/openvpn.${NAME}.pid openvpn "VPN '${NAME}'" || GLOBAL_STATUS=1
      else
        # Config does not exist
        log_warning_msg "VPN '$NAME': missing $CONFIG_DIR/$NAME.conf file !"
        GLOBAL_STATUS=1
      fi
    done
  fi
  exit $GLOBAL_STATUS
  ;;
*)
  echo "Usage: $0 {start|stop|reload|restart|force-reload|cond-restart|status}" >&2
  exit 1
  ;;
esac

exit 0

# vim:set ai sts=2 sw=2 tw=0:

5. I need to start a dhcp client after openvpn connection is established (cause I am using bridging mode) , /etc/init.d/udhcpc :
Code:
#!/bin/sh
#
# openvpn custom dhcp cilient Start and stop 
#

#PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin      
DAEMON=/sbin/udhcpc                                                    
NAME=udhcpc                                                     
DESC="Openvpn dhcp client"                                                      
# $2 is passed by openvpn with the device created ie tap0
if [ x == x"$2" ] ; then
	DEVICE=tap0
else
	DEVICE=$2
fi

PIDFILE="/var/run/$NAME.$DEVICE.pid"
SCRIPT="/etc/openvpn/udhcp.script"
test -x $DAEMON || test -x $SCRIPT || exit 0

# --now Exit with failure if a lease cannot be obtained. 
if [ -z "$DAEMON_OPTS" ] ; then
  DAEMON_OPTS="--now --no-zeroconf -i $DEVICE -s $SCRIPT --pidfile=$PIDFILE"
#  DAEMON_OPTS="--no-zeroconf -i $DEVICE -s $SCRIPT --pidfile=$PIDFILE"
fi

#set -e exit if a simple command exits with non zero

case "$1" in
  start)
	echo -n "Starting $DESC for $DEVICE: "                         
        echo " params: $DAEMON_OPTS "          
	while [ ! -d /sys/class/net/$DEVICE ] ; do
 		echo " $DEVICE missing so lets wait" 
		sleep 1
	done
	if ! test -f "$PIDFILE" ; then
	while true ; do
		start-stop-daemon --start \
		--pidfile "$PIDFILE" \
		--exec $DAEMON -- $DAEMON_OPTS
		if test $? -eq 0 ;then
			break
		fi		
		sleep 1
	done
	fi
        echo "$NAME."                  
	;;
  stop)
	echo -n "Stopping $DESC: "
	if test -e "$PIDFILE" ; then
		start-stop-daemon --stop --quiet --pidfile "$PIDFILE" 
		#kill `cat $PIDFILE` || true
		#rm -f $PIDFILE
	fi
	echo "$NAME."
	;;
  reload|restart|force-reload)
	#
	#	If the "reload" option is implemented, move the "force-reload"
	#	option to the "reload" entry above. If not, "force-reload" is
	#	just the same as "restart".
	#
	echo -n "Restarting $DESC: "
	start-stop-daemon --stop --quiet --pidfile \
		"$PIDFILE" --exec $DAEMON
	sleep 1
	start-stop-daemon --start --quiet \
	--pidfile "$PIDFILE"\
	    	--background --make-pidfile \
	    --exec $DAEMON -- $DAEMON_OPTS
	echo "$NAME."
	;;
  *)
	N=/etc/init.d/$NAME
	# echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
	echo "Usage: $N {start|stop|restart|force-reload}" >&2
	exit 1
	;;
esac

exit 0

Last edited by niv; 2010-05-19 at 20:44.
 
Posts: 74 | Thanked: 34 times | Joined on Jan 2008
#3
6. Now lets add a udhcpc script that doesnt change that keeps the default gateway but routes upnp ports home. /etc/openvpn/udhcp.script :
Code:
#!/bin/sh
# udhcpc script to use with OSSO ICd
# this is ment to allow connection to a bridged vpn server
# and to secure traffic only to the vpn subnet.
# Other traffic like www.google.com , will travel out of gprs0

RESOLV_CONF="/var/run/resolv.conf.$interface"
LEASE_PARAMS=/var/run/dhcp-params.openvpn.conf

[ -n ${RESOLV_CONF} ] && touch ${RESOLV_CONF}
case "$1" in

static | bound | renew)
	[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
	[ -n "$subnet" ] && NETMASK="netmask $subnet"

	if [ "$1" = renew ]; then
	    if [ -f $LEASE_PARAMS ]; then
		head -1 $LEASE_PARAMS | grep "^${interface} ${ip} ${router} ${subnet} ${domain} ${dns}$" > /dev/null
		if [ $? -eq 0 ]; then
		    exit 0
		fi
	    fi
	fi

	/sbin/ifconfig $interface $ip $BROADCAST $NETMASK

	if [ -n "$router" ]
	then
	    if netstat -rn | egrep "^0.0.0.0 *${router} .*${interface}$" > /dev/null
	    then
		:
	    else
	        while /sbin/route del default gw 0.0.0.0 dev $interface > /dev/null 2>&1 
		do
		  :
		done
		echo -n "Removed default route for " >&2
		echo "$interface: $ip/$subnet broadcast $broadcast" >&2
		# dont route default via vpn /sbin/route add default gw $router dev $interface
		# route upnp via vpn
		/sbin/route add -net 239.0.0.0 netmask 255.0.0.0 dev  $interface
		#if [ $? != 0 ]; then
		#    echo -n "Failed to set up default route for " >&2
		#    echo "$interface: $ip/$subnet broadcast $broadcast" >&2
		#fi

	    fi
	fi

	for ns in $dns
	do
	  if egrep "^nameserver[\t ]*${ns}" $RESOLV_CONF > /dev/null
	  then
	      continue
	  else
	      echo -n > $RESOLV_CONF.tmp
	      [ -n "$domain" ] && echo domain $domain >> $RESOLV_CONF.tmp
	      for i in $dns
	      do
		echo nameserver $i >> $RESOLV_CONF.tmp
	      done

	      mv $RESOLV_CONF.tmp $RESOLV_CONF

	      # Clear dnsmasq cache after getting new nameservers
	      kill -SIGHUP `pidof dnsmasq`
	      break
	  fi
	done

	/usr/bin/dbus-send \
	    --system \
	    --dest=com.nokia.icd \
	    /com/nokia/icd/autoconf \
	    com.nokia.icd.autoconf.autoconf_changed \
	    string:$interface string:DHCP string:CONNECTED

	if [ "$1" = bound -o "$1" = renew ]; then
	    echo "${interface} ${ip} ${router} ${subnet} ${domain} ${dns}" > $LEASE_PARAMS
	fi
	;;
deconfig)
	/sbin/ifconfig $interface 0.0.0.0
	rm -f $LEASE_PARAMS > /dev/null
	/usr/bin/dbus-send \
	    --system \
	    --dest=com.nokia.icd \
	    /com/nokia/icd/autoconf \
	    com.nokia.icd.autoconf.autoconf_changed \
	    string:$interface string:DHCP string:DISCONNECTED
	;;
esac
please remark if anything is missing.
Niv

Last edited by niv; 2010-05-18 at 19:42.
 
Posts: 10 | Thanked: 1 time | Joined on Feb 2007
#4
Do you find that the battery life is impacted by the process at all?
 
Posts: 74 | Thanked: 34 times | Joined on Jan 2008
#5
yes I have reason to belive this does uses more battery power, in a noticible mannar.
I am now trying to merge this with openvpn applet.
As I am new to using python's gui, it will take me time.
but this will be a nice addition.
 
Posts: 306 | Thanked: 106 times | Joined on Feb 2010
#6
Thanks for this script niv. I specified my gprs connection name "3" in HOME_ID (see below) but still the openvpn connection is being initiated. Does the script only work for wifi?

HOME_ID='d0b8bdcf-1ec0-4a5b-8880-f9d9058e1501 3'
__________________
------------------------------------------------------------------
Voice choppy on sip calls
Please vote for bug number 10388
 
Reply


 
Forum Jump


All times are GMT. The time now is 20:47.