Next Previous Contents

4. Client

Ora esamineremo il lato client. In pratica, quando è usata per permettere l'accesso ad una rete remota, questa linuxbox può facilmente servire come un server Samba (networking con Windows), server DHCP, e anche come server web interno. La cosa importante da ricordare è che questa linuxbox deve essere più sicura possibile, poichè serve tutta la rete remota.

4.1 Il Kernel

Per prima cosa, tu devi avere il ppp compilato nel tuo kernel. Se si vuole permettere a molte macchine di usare il tunnel, allora si ha bisogno di un servizio di firewall e di fowarding. Se il client si indirizza verso una sola macchina, ppp è sufficiente.

4.2 Creare il collegamento

Il collegamento è creato lanciando pppd attraverso un pseudo terminale creato da pty-redir e connesso a ssh. Questo è fatto con una sequenza di comandi simile a questa:

# /usr/sbin/pty-redir /usr/bin/ssh -t -e none -o 'Batchmode yes' -c 
blowfish -i /root/.ssh/identity.vpn -l joe > /tmp/vpn-device
# sleep 10

# /usr/sbin/pppd `cat /tmp/vpn-device`
# sleep 15

# /sbin/route add -net 172.16.0.0 gw vpn-internal.mycompany.com netmask 
255.240.0.0
# /sbin/route add -net 192.168.0.0 gw vpn-internal.mycompany.com netmask 
255.255.0.0

Semplicemente, quello che fa è far girare ssh, redirezionare il suo imput e l'output su pppd. L'opzione passata a ssh lo configura per girare senza caratteri escape (-e), usando il blowfish crypto algorithm (-c), usando la specificazione dell'identità del file (-i), in terminal mode (-t), e con le opzioni 'Batchmode yes' (-o). I comandi di sleep sono usati per estendere l'esecuzione dei comandi così che ogni processo possa completare il suo setup prima che il successivo parta.

4.3 scripting

Naturalmente non vuoi dover digitare i comandi sopra riportati ogni volta che vuoi che il tunnel si attivi. Ho scritto un set di script bash che tengono il tunnel attivo e funzionante. Puoi scaricare il package da qui. Devi solamente scaricarlo e decomprimerlo in /usr/local/vpn. All'interno troverai tre files:

Avrai bisogno di editare lo script vpnd per settare cose come l'username dei client e il nome dei server. Avrai anche bisogno di modificare la sezione starttunnel dello script per specificare quale rete stai usando. Sotto c'è una copia dello script. Noterai che potresti mettere lo script in una directory differente, hai solamente bisogno di cambiare la variabile VPN_DIR.


#! /bin/bash
#
# vpnd: Monitor the tunnel, bring it up and down as necessary
#

USERNAME=vpn-username
IDENTITY=/root/.ssh/identity.vpn

VPN_DIR=/usr/local/vpn
LOCK_DIR=/var/run
VPN_EXTERNAL=vpn.mycompany.com
VPN_INTERNAL=vpn-internal.mycompany.com
PTY_REDIR=${VPN_DIR}/pty-redir
SSH=${VPN_DIR}/${VPN_EXTERNAL}
PPPD=/usr/sbin/pppd
ROUTE=/sbin/route
CRYPTO=blowfish
PPP_OPTIONS="noipdefault ipcp-accept-local ipcp-accept-remote local noauth 
nocrtscts lock nodefaultroute"
ORIG_SSH=/usr/bin/ssh


starttunnel () {
   $PTY_REDIR $SSH -t -e none -o 'Batchmode yes' -c $CRYPTO -i $IDENTITY -l 
$USERNAME > /tmp/vpn-device
   sleep 15

   $PPPD `cat /tmp/vpn-device` $PPP_OPTIONS
   sleep 15

   # Add routes (modify these lines as necessary)
   /sbin/route add -net 10.0.0.0 gw $VPN_INTERNAL netmask 255.0.0.0
   /sbin/route add -net 172.16.0.0 gw $VPN_INTERNAL netmask 255.240.0.0
   /sbin/route add -net 192.168.0.0 gw $VPN_INTERNAL netmask 255.255.0.0
}

stoptunnel () {
   kill `ps ax | grep $SSH | grep -v grep | awk '{print $1}'`
}

resettunnel () {
   echo "reseting tunnel."
   date >> ${VPN_DIR}/restart.log
   eval stoptunnel
   sleep 5
   eval starttunnel
}

checktunnel () {
   ping -c 4 $VPN_EXTERNAL 2>/dev/null 1>/dev/null

   if [ $? -eq 0 ]; then
      ping -c 4 $VPN_INTERNAL 2>/dev/null 1>/dev/null
      if [ $? -ne 0 ]; then
         eval resettunnel
      fi
   fi
}

settraps () {
   trap "eval stoptunnel; exit 0" INT TERM
   trap "eval resettunnel" HUP
   trap "eval checktunnel" USR1
}

runchecks () {
   if [ -f ${LOCK_DIR}/tunnel.pid ]; then
      OLD_PID=`cat ${LOCK_DIR}/vpnd.pid`
      if [ -d /proc/${OLD_PID} ]; then
         echo "vpnd is already running on process ${OLD_PID}."
         exit 1
      else
         echo "removing stale pid file."
         rm -rf ${LOCK_DIR}/vpnd.pid
         echo $$ > ${LOCK_DIR}/vpnd.pid
         echo "checking tunnel state."
         eval checktunnel
      fi
   else
      echo $$ > ${LOCK_DIR}/vpnd.pid
      eval starttunnel
   fi
}

case $1 in
    check)  if [ -d /proc/`cat ${LOCK_DIR}/vpnd.pid` ]; then
               kill -USR1 `cat ${LOCK_DIR}/vpnd.pid`
               exit 0
            else
               echo "vpnd is not running."
               exit 1
            fi ;;

    reset)  if [ -d /proc/`cat ${LOCK_DIR}/vpnd.pid` ]; then
               kill -HUP `cat ${LOCK_DIR}/vpnd.pid`
               exit 0
            else
               echo "vpnd is not running."
               exit 1
            fi ;;

   --help | -h)
            echo "Usage: vpnd [ check | reset ]"
            echo "Options:"
            echo "     check    Sends running vpnd a USR1 signal, telling it 
to check"
            echo "              the tunnel state, and restart if neccesary."
            echo "     reset    Sends running vpnd a HUP signal, telling it to 
reset"
            echo "              it's tunnel connection." ;; 
esac

ln -sf $ORIG_SSH $SSH
settraps
runchecks

while true; do
   i=0
   while [ $i -lt 600 ]; do
      i=((i+1))
      sleep 1
   done
   eval checktunnel
done

4.4 LRP - Linux Router Project

Io attualmente faccio girare questa configurazione su un Pentium 90 con una distribuzione LRP di Linux. LRP è una distribuzione di Linux che stà in un solo floppy disk. Puoi saperne di più a http://www.linuxrouter.org/. Puoi scaricare il mio package LRP per il client VPN da qui. Avrai bisogno pure dei pacchetti ppp che ssh che puoi trovare nel sito di LRP.


Next Previous Contents