次のページ 前のページ 目次へ

4. クライアント

さてクライアントの方を調べてみましょう。実際、リモートネットワークに対して 常にアクセスを許すときには、この箱は簡単に Samba(Windows ネットワーク)サーバ、 DHCP サーバ、それから内部のウェブサーバにできます。 覚えておかなくてはならない重要なことは、この箱はリモートネットワーク全体で 動作するのですから、可能な限り安全であるべきだということです。

4.1 カーネル

重要なものから先に話しておくと、あなたはカーネルの中で ppp を有効にして おく必要があります。もし複数のマシンに対してトンネルの使用を許そうと しているのであれば、ファイアウォール、フォワーディングも有効にしておく 必要があります。 クライアントが単一のマシンであるなら、ppp だけで十分です。

4.2 リンクを確立する

リンクは、擬似端末を通して動作している pppd によって生成されます。 (その擬似端末は)pty-redir によって生成され、ssh に接続 されています。これは次に示すようなコマンド列によって実現されます -

# /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

単にこれがやるのは ssh を実行し、その入出力を pppd にリダイレクト するということです。ssh に渡されるオプションは、それをエスケープ キャラクタなしで動作し (-e) 、 blowfish 暗号化アルゴリズム を使い (-c)、指定した認証ファイルを使って (-i)、ターミナルモードで (-t)、 さらに 'Batchmode yes' オプションつきで (-o) 実行するよう設定します。 sleep コマンドは、それぞれがその次のコマンドの実行前に起動を完了 できるように、コマンドの実行の間隔をあけるために使用されます。

4.3 スクリプトを書く

もちろん、あなたはトンネルを通過させたいときに、その都度それらのコマンドを 入力したくはないでしょう。私はトンネルをそのまま通れるようにしておく ような bash スクリプトのセットを書きました。パッケージは ここからダウンロードできます。ダウンロードして /usr/local/vpn に 伸長してください。その中には 3 つのファイルがあります -

クライアントのユーザ名やサーバの名前というようなことを設定するためには vpnd を編集する必要があるでしょう。また利用している ネットワークを指定するために、スクリプトの starttunnel セクションを編集 する必要もあるでしょう。以下はあなたに喜んで読んでもらうための、スクリプトの コピーです。スクリプトは別なディレクトリに入れておくことができ、 そのためには 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 ルータプロジェクト

実際、私はこの環境を Linux の LRP ディストリビューションが走る pentium 90MHz の上で動作させています。LRPは 1 枚のフロッピーディスクに収まり、 起動する Linux ディストリビューションです。これ以上のことについては http://www.linuxrouter.org/ で学ぶことができます。 私の VPN クライアント用の LRP パッケージは、 ここから ダウンロードできます。それから ppp および ssh パッケージも LRP サイト から得る必要があるでしょう。


次のページ 前のページ 目次へ