#!/bin/sh -x
# 
# usage: $0 [stop]
# si pas d'argument, le script (tue et) (re)lance le tunnel
#
# Maintenu via: http://dgeos.net/2007/07/04/tunnel-ssh
#
# Tunnel ssh vers un serveur 
#  - qui autorise les tunnels
#  - qui natte (?)
# Il faut etre:
#  - en root sur le serveur (?)
#  - en root (sudo, su) en local
# 
# Pour que chacun aie des tunX/IP's differents:
# *SVP* incrementez (vim:CTRL+A) les
# - numeros de tunX
# - IP's
# *MAINTENANT* (pour le prochain) ...

# options
#   SERVEUR
# l'IP(v6?) du serveur
#SERVEUR=IP de la passerelle
SERVEUR=4.3.2.1
# numero d'interface tunX distant - Un par tete !
# A METTRE A JOUR MAINTENANT ET ICI (CTRL+A)
REMOTE_TUN_NR="101"
# IP du tunnel la bas - idem
# A METTRE A JOUR MAINTENANT ET ICI (CTRL+A)
REMOTE_TUN_IP="192.168.0.1"
# reseaux accessibles via le serveur
# IPV4_ROUTES_THERE=0.0.0.0/0
IPV4_ROUTES_THERE="192.168.0.0/24"

#   LOCAL
# numero d'interface tunX local 
# A METTRE A JOUR MAINTENANT ET ICI (CTRL+A)
LOCAL_TUN_NR="101"
# IP ici
# A METTRE A JOUR MAINTENANT ET ICI (CTRL+A)
LOCAL_TUN_IP="192.168.0.2"
# eventuels reseaux a faire router au serveur pour ici
IPV4_ROUTES_HERE=""

SYSTEM=$(uname -s)
# REM_SYSTEM=$(ssh root@${SERVEUR} uname -s)
REM_SYSTEM="FreeBSD"
# fin config

# TODO: routage IPv6...
#
# initialisations
DEF_GW=$(netstat -rn --inet | grep '^0\.0\.0\.0' | awk '{print $2}')
DO_SSH_IPV6=0
DO_LOCAL_ROUTES=0
SUDO=""

# systeme
case $SYSTEM in
  *BSD)
    GW=""
    ;;
  Linux)
    GW="gw"
    ;;
  default)
    GW="gw"
    ;;
esac


case $REM_SYSTEM in
  *BSD)
    RGW=""
    ;;
  Linux)
    RGW="gw"
    ;;
  default)
    RGW="gw"
    ;;
esac

# ssh-askpass
if [ -x "$(which ssh-askpass 2>/dev/null)" ]; then
  if [ -n "$DISPLAY" ]; then
    export SSH_ASKPASS=$(which ssh-askpass)
  fi
fi

if [ "$(id -u)" -ne "0" ]; then
  if [ -x "$(which sudo 2>/dev/null)" ]; then
  	SUDO=$(which sudo)
  else if [ -x "$(which su 2>/dev/null)" ]; then
	SUDO=$(which su)
  else
	echo "Pas root, pas de sudo et pas de su. C'est trop ;)"
  fi
fi

if [ "$1" = "stop" ]; then
  exec $SUDO pkill -f 'ssh.*tun'$LOCAL_TUN_NR
fi

# IPv6 ?
if [ $(echo $SERVEUR|grep -e '[0-9a-fA-F]\{1,4\}:\(\([0-9a-fA-F]\{1,4\}\)\{0,1\}:\)\{1,\}' | wc -l) -gt 0 ]; then
  DO_SSH_IPV6=1;
elif [ $(echo $SERVEUR|grep -e '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' | wc -l) -gt 0 ]; then
  sudo /sbin/route add -host $SERVEUR $GW $DEF_GW
fi

# construction de la commande locale
COMMANDE="ssh -f"
if [ "$DO_SSH_IPV6" -eq "1" ]; then
  COMMANDE="$COMMANDE -6"
fi
COMMANDE="$COMMANDE $SERVEUR -w $LOCAL_TUN_NR:$REMOTE_TUN_NR"

REMOTE_CMD="/sbin/ifconfig tun$REMOTE_TUN_NR $REMOTE_TUN_IP $LOCAL_TUN_IP"
if [ -n "$IPV4_ROUTES_HERE" ]; then
  DO_LOCAL_ROUTES=1
  for localnet in $IPV4_ROUTES_HERE; do
    REMOTE_CMD="$REMOTE_CMD; /sbin/route add $localnet $LOCAL_TUN_IP"
  done
fi

# tuer l'ancien (if any)
eval $SUDO pkill -f 'ssh.*tun'$LOCAL_TUN_NR

eval $SUDO $COMMANDE \"$REMOTE_CMD\" || exit 1

sleep 4

eval $SUDO /sbin/ifconfig tun$LOCAL_TUN_NR $LOCAL_TUN_IP pointopoint $REMOTE_TUN_IP

for network in $IPV4_ROUTES_THERE; do
  eval $SUDO /sbin/route add -net $network $GW $REMOTE_TUN_IP
done

if [ $DO_LOCAL_ROUTES -gt 0 ]; then
  eval $SUDO /sbin/iptables -t nat -A POSTROUTING -o br0 -s $REMOTE_TUN_IP -j MASQUERADE
  eval $SUDO /sbin/sysctl net.ipv4.forwarding=1
fi

