#!/bin/sh # #!F:ctrlsit-ip6 # #!P:/usr/local/sbin # #!S:root:root 550 # #!D:Server program, called from "triggersit-ip6", to activate tunnels #!D: on a IPv6 tunnelserver for tunnelendpoints with no static IPv4 address # # Features: extra logfile, multi user and multi tunnel support # Security: called by ssh via sudo # #!C:Copyright 1997-2000 Peter Bieringer # # Changes to # 1.20: Options now in UNIX style, logging with time&date # root can now add or delete user tunnels, but no route for himself # 1.21: Minor correction (renaming variables) # 1.22: Missing config is reported # Start of implementing a test function for valid IPv4 addresses (todo...) # 1.24: Improvement of the logging output, infolog & infoconf now with # only displaying user related information (security) # 1.30: New option: deloldtun (delete old tunnels) # This option is useful to delete tunnels to endpoints which are set # over a timelimit. # Trigger 'ctrlsit-ip6 -c deloldtun' from cron every hour. # i.e. "1 * * * * /usr/local/sbin/ctrlsit-ip6 -c deloldtun" # New option handling # New option: quiet # New lock filenames # IPv6 test before starting # 20000722: Review, remove minor bugs, add major file checks # make it standalone (no longer needs any IPv6 function # libary) # add option '-ipv6' to specify an IPv6 address for # 'tunnel alive' tests # add a new command: deldowntun (delete down tunnels) # call this script with this option by cron, it will # delete down tunnels, tested with ping: # IPv4: always, IPv6: if address specified # 20001007: Fix "whoami" trouble (old mechanism do not work anymore) # # ToDo # * IPv4 destination address test for more security # (user depending) #---------------- need to review below this line (user options) # Here you have to set the file in which user and IPv6 prefix is stored # In this file for each user prefixes are stored (several possible!) IP6TUNNEL_USERCONF="/etc/sysconfig/ctrlsit-ip6.conf" # Here you have to set the directory for the information of existing tunnels IP6TUNNEL_LOCK="/var/lock" # Here you have to define the prefix of the lock file # Look in /etc/init.d which script delete which lock files at startup IP6TUNNEL_LOCKPREFIX="LCKtunnelip6" # Here you have to define the maximum minutes a tunnel is up IP6TUNNEL_MAXTIME="180" # Here you have to set a filename for logging IP6TUNNEL_LOG="/var/log/ctrlsit-ip6.log" # Specify binary 'route' (must be IPv6 enabled) BIN_ROUTE="/sbin/route" # Specify binary 'ifconfig' (must be IPv6 enabled) BIN_IFCONFIG="/sbin/ifconfig" # Specify binary 'ping' BIN_PING="/bin/ping" # Specify binary 'ping6' (must be IPv6 enabled) BIN_PING6="/usr/sbin/ping6" # Specify binary of 'whoami' BIN_WHOAMI="/usr/bin/whoami" #---------------- normally nothing to change below this line #set -x ## Subroutines # Logging subroutine function log () { LOGDATE=`date '+%b %_d %H:%M'` echo "$LOGDATE $LOGNAME: $*">>$IP6TUNNEL_LOG } # Help subroutine function help() { cat <&1 | grep -q "(IPv6)"; then echo -e "\a '$BIN_IFCONFIG' (net-tools) not compiled for IPv6 - stop!" exit 2 fi if ! $BIN_ROUTE -? 2>&1 | grep -q "(IPv6)"; then echo -e "\a '$BIN_ROUTE' (net-tools) not compiled for IPv6 - stop!" return 2 fi ## Not the real beginning # WhoAmI if [ ! -z $SUDO_USER ]; then VAL_WHOAMI="$SUDO_USER" else VAL_WHOAMI=`$BIN_WHOAMI` fi if [ -z "$VAL_WHOAMI" ]; then echo -e "\a Result of 'whoami' is empty - very strange!" exit 1 fi printout "\a\n" printout "Hello '$VAL_WHOAMI', here is the IPv6 tunnel server for IPv4 tunnelendpoints\n" printout "Your arguments are (# = default):\n" printout "User:" if [ -z "$OPTION_USER" ]; then OPTION_USER=$VAL_WHOAMI printout "#" fi printout "$OPTION_USER " printout "Command:" if [ -z "$OPTION_CMD" ]; then OPTION_CMD="new" printout "#" fi printout "$OPTION_CMD " printout "IPv4 address:$OPTION_IP4 " printout "Debug:" if [ -z "$OPTION_DEBUG" ]; then OPTION_DEBUG="0" printout "#" fi printout "$OPTION_DEBUG" printout "\n" # Logging given options log "usr:$OPTION_USER cmd:$OPTION_CMD IPv4:$OPTION_IP4 dbg:$OPTION_DEBUG" # Test for user & root if [ "$VAL_WHOAMI" != "$OPTION_USER" -a "$VAL_WHOAMI" != "root" ]; then echo "You are not root, so you can't set another user then yourself - goodbye!" log ">You are not root, so you can't set another user then yourself!" exit 1 fi # Switch by command case "$OPTION_CMD" in deldowntun) # only root can do this! if [ ! "$VAL_WHOAMI" = "root" ]; then echo "You're not allowed to call 'deldowntun' - goodbye!" log ">You're not allowed to call 'deldowntun'" exit 1 fi printout "Hi root, you want to delete down tunnels...\n" log ">Root wants to delete down tunnels" find $IP6TUNNEL_LOCK -maxdepth 1 -name $IP6TUNNEL_LOCKPREFIX.* | while read file; do user=`echo $file | awk -F/ '{ print $NF }' | sed s/^$IP6TUNNEL_LOCKPREFIX.//g` if [ ! $[ $OPTION_DEBUG & 1 ] = 0 ]; then printout " Found (open) tunnel for '$user'\n" fi VAL_IPV4ADDR=`head -1 $file | awk '{ print $1 }'` VAL_IPV6ADDR=`head -1 $file | awk '{ print $2 }'` if [ -z "$VAL_IPV4ADDR" ]; then # should never happen, delete instantly $0 -c del -u $user -q continue fi # Run an IPv4 ping test first if [ ! $[ $OPTION_DEBUG & 1 ] = 0 ]; then printout " Test IPv4 connection to $VAL_IPV4ADDR\n" fi VAL_ERROR=`$BIN_PING -q -n -c 5 $VAL_IPV4ADDR | grep "%" | awk -F% '{ print $1 }' | awk '{ print $NF }'` if [ ! $[ $OPTION_DEBUG & 2 ] = 0 ]; then echo " Packet loss: $VAL_ERROR %" fi if [ "$VAL_ERROR" = "100" ]; then # tunnel endpoint not reachable through IPv4, delete instantly printout " Oh, tunnel to '$user' has no IPv4 connection anymore, delete it\n" log ">Tunnel to '$user' without IPv4 connection anymore, delete it" $0 -c del -u $user -q continue else if [ ! $[ $OPTION_DEBUG & 1 ] = 0 ]; then printout " IPv4 connection works\n" fi fi # If an IPv6 address specified, run an IPv6 ping test if [ ! -z "$VAL_IPV6ADDR" ]; then if [ ! $[ $OPTION_DEBUG & 1 ] = 0 ]; then printout " Test IPv6 connection to $VAL_IPV6ADDR\n" fi VAL_ERROR=`$BIN_PING6 -q -n -c 5 $VAL_IPV6ADDR | grep "%" | awk -F% '{ print $1 }' | awk '{ print $NF }'` if [ ! $[ $OPTION_DEBUG & 2 ] = 0 ]; then echo " Packet loss: $VAL_ERROR %" fi if [ "$VAL_ERROR" = "100" ]; then # tunnel endpoint not reachable through IPv4, delete instantly printout " Oh, tunnel to '$user' has no IPv6 connection anymore, delete it\n" log ">Tunnel to '$user' without IPv6 connection anymore, delete it" $0 -c del -u $user -q continue else if [ ! $[ $OPTION_DEBUG & 1 ] = 0 ]; then printout " IPv6 connection works\n" fi fi fi done exit 0 ;; deloldtun) # only root can do this! if [ ! "$VAL_WHOAMI" = "root" ]; then echo "You're not allowed to call 'deloldtun' - goodbye!" log ">You're not allowed to call 'deloldtun'" exit 1 fi printout "Hi root, you want to delete old tunnels...\n" log ">Root wants to delete old tunnels" find $IP6TUNNEL_LOCK -maxdepth 1 -name $IP6TUNNEL_LOCKPREFIX.* -mmin +$IP6TUNNEL_MAXTIME | while read file; do user=`echo $file | awk -F/ '{ print $NF }' | sed s/^$IP6TUNNEL_LOCKPREFIX.//g` printout " Oh, '$user' matched time limit\n" log ">Matched time limit for '$user', so delete tunnel" $0 -c del -u $user -q done; exit 0 ;; new) # root can't setup tunnels! if [ "$OPTION_USER" = "root" ]; then echo "You can't make tunnels for 'root', choose option '-u user' - goodbye!" log ">You can't make tunnels for 'root'!" exit 1 fi # IPv4 address is needed if [ -z "$OPTION_IP4" ]; then echo "Needed IPv4 address isn't given - goodbye!" log ">Needed IPv4 address isn't given!" help exit 1 fi ;; del) # root can't setup tunnels! if [ "$OPTION_USER" = "root" ]; then echo "You can't delete tunnels for 'root', choose option '-u' - goodbye!" log ">You can't delete tunnels for 'root'!" exit1 fi ;; infosit0) # Display routes relating to sit0 log ">send routing table relating to sit0" $ROUTE6 | grep sit0 exit 0 ;; inforoute) # Display routes log ">send routing table" $ROUTE6 exit 0 ;; infolog) # Display lastlogs if [ "$OPTION_USER" = "root" ]; then # root gets a lot of information log ">send lastlog" echo "Last part of the logfile:" tail -40 $IP6TUNNEL_LOG else # anybody else only its own log ">send lastlog relating to '$OPTION_USER'" echo "Last part of the logfile relating to '$OPTION_USER':" cat $IP6TUNNEL_LOG | grep "$OPTION_USER:" | tail -20 fi exit 0 ;; infoconf) # Display config if [ "$OPTION_USER" = "root" ]; then # root gets all the information log ">send configuration" echo "Complete configuration file:" cat $IP6TUNNEL_USERCONF else # anybody else only its own log ">send configuration relating to '$OPTION_USER'" echo "Part of the configuration file relating to '$OPTION_USER':" cat $IP6TUNNEL_USERCONF | grep "^$OPTION_USER" fi exit 0 ;; help) # Display help log ">send help" echo "Help:" help exit 0 ;; *) echo "Command $OPTION_CMD isn't understood - goodbye!" log ">Command $OPTION_CMD isn't understood!" help exit 1 ;; esac # Test if config file exists if ! [ -f $IP6TUNNEL_USERCONF ]; then echo "Fatal error: missing '$IP6TUNNEL_USERCONF' - stop!" log ">Fatal error: missing '$IP6TUNNEL_USERCONF'" exit 1 fi; # Test for existing old tunnels test_ip4user $OPTION_USER $OPTION_IP4 || exit 1 # Test for existing old tunnels printout " Now a test for an old tunnel set to you..." if [ -f $IP6TUNNEL_LOCK/$IP6TUNNEL_LOCKPREFIX.$OPTION_USER ]; then printout "\aexists!\n" # Get Old IP Address IP4_OLD=`cat $IP6TUNNEL_LOCK/$IP6TUNNEL_LOCKPREFIX.$OPTION_USER | awk '{ print $1 }'` printout " Your old IPv4 address was: $IP4_OLD\n" printout " Now remove old tunnels\n" grep "^$OPTION_USER" $IP6TUNNEL_USERCONF | while read dummy ip6prefix ; do printout " Your prefix was: $ip6prefix\n" $BIN_ROUTE -A inet6 del $ip6prefix gw ::$IP4_OLD dev sit0 # Logging log ">delete tunnel $ip6prefix gw $IP4_OLD" done # Remove sign rm -f $IP6TUNNEL_LOCK/$IP6TUNNEL_LOCKPREFIX.$OPTION_USER else printout " none - ok!\n" log ">no tunnel to delete!" fi # No Old Tunnels To This Account if [ "$OPTION_CMD" = "del" ]; then printout " Nothing more to do - goodbye!\n" exit 0 fi $BIN_IFCONFIG sit0 up printout " Now setting up tunnels for you:\n" # Look for prefixes in the conf file and set tunnels with them grep "^$OPTION_USER" $IP6TUNNEL_USERCONF | while read dummy ip6prefix ; do printout " Your prefix will be: $ip6prefix\n" $BIN_ROUTE -A inet6 add $ip6prefix gw ::$OPTION_IP4 dev sit0 # Logging log ">create tunnel $ip6prefix gw $OPTION_IP4" if [ ! -z $OPTION_IPV6 ]; then printout " You also specified an IPv6 address: $OPTION_IPV6\n" log ">specified IPv6 address $OPTION_IPV6" fi done # Put a sign for later echo "$OPTION_IP4 $OPTION_IPV6" >$IP6TUNNEL_LOCK/$IP6TUNNEL_LOCKPREFIX.$OPTION_USER printout "\nHave fun - goodbye!\n"