子羊ルータでVPN (PPP over SSH)を使用する方法について

2001年4月26日初出
2001年8月16日修正

1.概要


 VPNとは仮想プライベートネットワーク(Virtual Private Network)のことで す。インターネットをはさんで、あたかもLAN内でつながっているかのように、 安全でアドレス管理も簡単なネットワークのことです。弊社も扱っております 子羊ルータは、カスタマイズが容易なため、VPNのために利用することができ ます。

 VPNができると、地理的/ネットワーク的に離れたオフィスであっても、す ぐ隣にあるかのように使用することができます。

などに威力を発揮します。

 PPP over SSHの概要を説明しますと、SSH(OpenSSH)で

  1. 途中経路上を暗号化してログインし、
  2. その経路上でプライベートアドレスでのIP接続をPPPによって行なう、
ということになります。PPPoEに対する利点としては、暗号化されていること も重要な点ですが、Ethernetで直接(MACアドレスが見える範囲で)つながっ ている相手とのみ接続できるPPPoEに対して、 というところが大きな違いになります。

 ただし、PPPoEとの共存する場合には、/etc/ppp/optionファイルを修正しな がら動作させなければなりません。こちらでは、VPNを張る際に /etc/ppp/optionファイルをVPN用に置き換え、その直後に元に戻す、というス クリプトにしました。ここでは、VPNの張り方だけを説明していますので、ご 注意ください。

 今回のVPNを実現するには、下記の文章を参考にしました。

http://jf.linux.or.jp/JFdocs/VPN-HOWTO.html

 これ以外にもFreeSWANであるとか、CIPEとかもどんなものか見てみようとは 思ったのですが、IPのプロトコルスタック自身に手を入れることや、相手側の ルータも同様の設定を行なうことが必要になってしまうことで手間がかかりま す。結局一番お手軽なPPP over SSHを使いました。この方法だと相手が子羊ルー タでなくてもいいですし、SSHが子羊に載せられるというのも魅力に感じたわ けです。ただし、これらを搭載すると、16MBでは厳しいです。実際に作業しよ うと思ったら、CF (Compact Flash)を容量の大きいものに載せ替える必要はあ ります。筆者は32MB、および64MBのCFを使用しました。この問題も、NFSを使っ てバイナリファイルを展開することができる人なら回避できるかも知れません。 筆者は16MBでは試していませんのでご容赦ください。

2.事前にそろえるソフトウェア

 使用したソフトは主に、 の各パッケージです。

 PPPは、ワイルドラボ様のPPPoEアップデートパッケージをダウンロードして きたものが使えました。これは現時点でもすごく新しいバージョンのもの (2.4.0b1)ですよね。手元にあった2.3.11と組み合わせて使えるか不安で、最 初は2.4.0b1以降のものを持ってきたりしていましたが、一応2.3.11でも使え ました。

 sudoは、SSHでログインした先ではPPPサーバを起動するのに使用しました。 pppdがsetuidされていれば、ログインシェルの変わりにpppdを起動する方法が 使えるかも知れません。sudoにはセキュリティホールがあるというレポートも 上がっていますが、ネットワークに口を空けて待っているものではないので、 使ってしまいました。

 OpenSSHについては、libz.so.1.0.2(のシンボリックリンクである libz.so.1)を要求しますので、これはRedHatなどのパッケージから、コピー してきて使用しました。また、作業の途中ではrpmパッケージをtgz形式のファ イルに変換するalienというツールを使用しました。

3.作業手順

 実際の作業は、以下のようになります。

3.1.ファイルシステムのリマウント

 以下の作業をCFをノートパソコンなどで操作する場合は特に考えることはな いかも知れませんが、lambルータ上で展開する場合には、

mount -o remount,rw /

などとして、ファイルシステムを書き換えられるようにマウントし直すことが 必要です(ワイルドラボの掲示版ではおなじみの方法かも知れませんね)。

3.2.OpenSSHのインストール

 sshのインストールは、rpmコマンドが使えないので、以下のファイルを alienで展開してlambルータに持っていき、tar zxvf で展開しました。

openssh-askpass-gnome-2.5.1p2-2.6.x.i386.rpm
openssh-clients-2.5.1p2-2.6.x.i386.rpm
openssh-server-2.5.1p2-2.6.x.i386.rpm
openssl-0.9.6-1k.i586.rpm
openssl-devel-0.9.6-1k.i586.rpm
openssl-misc-0.9.6-1.i386.rpm
 これらのrpmは、alien -t でtgz形式に変換して持っていきます。alien自体は インターネット上で入手できます。tarで展開するときは、root権限で、
# cd /
# tar zxvf openssh-clients-2.5.1p2.tgz usr/bin/*
(#はプロンプトです)などとすると、/usr/bin/以下のものだけを取り出すこ とができ、マニュアルなどは展開しないので、ディスクを節約できます。もち ろん、大容量のCFを使っている場合は関係ありません。

 このままだと、sloginなどを実行しようとすると、libz.so.1がないなどと 言われるはずです。実際には、以下のエラーメッセージです。

ssh: error in loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory

 この場合は、RedHatなどのパッケージからlibz.so.1をもらってきて、 /usr/lib/などに置けばいいです。

3.3.sudoの設定

 sudoは、上記OpenSSHをインストールしたように、sudoのrpmパッケージから tgzファイルを作り、tarで展開することでインストールします。
他のマシンにて:
alien -t sudo-1.6.3p3-0k1.i586.rpm

LAMBルータ上にて:
cd /
tar zxvf sudo-1.6.3p3-0k1.i586.tgz
とします。

 これができたら、PPPのサーバ側、クライアント側双方でppp専用のユーザを useraddコマンドなどで追加し、パスワードを(passwdコマンドで)設定して おきます。その後、/etc/sudoersにて、そのユーザがpppdを実行できるように しておきます。

pppuser host1 = NOPASSWD: /usr/sbin/pppd, /home/pppuser/route

などとします。ここで、pppuserはpppdを実行するユーザ、host1はマシン名 (この場合は、pppdを実行するLAMBルータ自身のマシン名)を表します。

3.4.PPPの設定

 PPPは、PPPoEのパッケージをワイルドラボ様のページに従ってインストール します。PPPの設定ファイルは、PPPoEのパッケージアップロードを行なうと各 種設定がすでに記入されています。が、どこが問題かわかりませんが、筆者の 試した環境ではそのままではPPP接続を行なうことができませんでした。 VPN-HOWTOに記載されているとおり、/etc/ppp/optionファイルにて、
proxyarp
noauth
という2行の記述を行なうことで、PPP接続ができるようになりました。 noauthの指定は、sshで認証を行っていることが前提であり、この場合は危険 ではありません。

 この/etc/ppp/optionファイルは、コマンドの実行時のオプションではオー バライトされるものではないため、注意が必要です(実際のpppoeでの設定が 必要な場合は、pppoe用のファイルをバックアップしておき、VPNの処理が終了 したら元に戻すと言うような工夫が必要になります)。ここはあくまで、PPP で一対一で接続するときの方法です。

 これらのインストールおよび設定ができたら、

ssh -o 'Batchmode yes' -t -l ppp $TARGET_HOST sudo /usr/sbin/pppd
を実行してみましょう。これで、pppdからの応答である、文字化けした文字列 がズラズラと表示されたら、サーバ側では正しくPPPが動作しています。

 最終的に、PPP over SSHの接続は以下のようなスクリプトで実行できます。
#!/bin/sh

TARGET_HOST='xxx.xxx.xxx.xxx'
LOCALIP='yyy.yyy.yyy.yyy'
LOCALSUB='yyy.yyy.yyy.0'
REMOTEIP='zzz.zzz.zzz.zzz'
REMOTESUB='zzz.zzz.zzz.0'

echo setting up vpn.

/usr/local/vpn/pty-redir /usr/sbin/ssh -o 'Batchmode yes' -t -l ppp -i /home/pppuser/.ssh/ppplink.id $TARGET_HOST sudo /usr/sbin/pppd 2> /tmp/vpn-device

TTYNAME=`cat /tmp/vpn-device`
if [ ! -z $TTYNAME ] ; then
	sleep 5s
	/usr/sbin/ssh $TARGET_HOST /usr/sbin/pppd $TTYNAME $LOCALIP:$REMOTEIP noauth
	sleep 5s

	/usr/local/vpn/pty-redir /usr/sbin/ssh -o 'Batchmode yes' -t -l ppp -i /home/pppuser/.ssh/ppplink.id $TARGET_HOST sudo /home/pppuser/route.sh
	/usr/bin/sudo /sbin/route add -net $REMOTESUB gw $REMOTEIP ppp0
else
	echo FAILED!
	logger "vpn setup failed"
fi
 実際には、この中で使用するホスト名やroute.shなどのスクリプトは必要に 応じて記述しておく必要があります。また、-iオプションを使ってパスワード なしでpppuserがログインするようにしていますが、このオプションの使い方 はOpenSSHのマニュアル等をご覧下さい。

 VPN-HOWTOで記されているように、確かに、これらの手順でVPNを使用するこ とができるようになります。また、サブネットがVPNを使用しない場合のマス カレードの設定は、ipchainsのドキュメントを見て設定してください(LAMBルー タの場合はウェブで設定できますね)。

4.ルーティングテーブル設定上の注意

 PPP over SSHの注意点としては、PPPのサーバ(リモート)側、クライアン ト(ローカル)側、双方の属するサブネット自体はVPNではルーティングでき ない、ということです。
というVPNを作りたいとき、
サブネットx	61.xxx.xxx.xxx/27
サブネットy	61.yyy.yyy.yyy/27
の範囲に属するアドレスは、VPNではルーティングできません。というのも、 最初にsshでコネクションを張るとき、61.yyy.yyy.yyyから61.xxx.xxx.xxxへ、 というふうに、インターネットを通って(グローバルアドレスを使って)コネ クションを張っているはずです。その状態で、VPNが張れたからといって、以 下のようにルーティング設定を行なってしまうと、VPNの中身を運ぶべきsshの パケットがインターネット上を通って61.xxx.xxx.xxxまで到達できないことに なってしまうからです。
悪い例)
61.yyy.yyy.xxxにて、
route add -net 61.xxx.xxx.0 netmask 255.255.255.224 gw 192.168.100.254 ppp0
 正しくは、以下のように設定することになります。
良い例)
61.yyy.yyy.yyyにて:
route add -net 192.168.100.0 netmask 255.255.255.0 gw 192.168.100.254 ppp0

61.xxx.xxx.xxxにて:
route add -net 192.168.200.0 netmask 255.255.255.0 gw 192.168.200.254 ppp0
 VPNを使用するときは、あくまで、ルータの下位のサブネット同士をつなげ ることができるだけだ、ということを理解しましょう。

 ここさえ注意すれば、その他の点は、VPN-HOWTOに書いてあるとおりで問題 なくVPNを実現できるでしょう。

5.まとめ

 暗号化通信をしないまま、複数の拠点を結んで作業するのはなかなか勇気の いるものです。今後ともLAMBルータがビジネスにも役に立つといいですね。子 羊という、カスタマイズのできる製品が存在しているからこそ、活用できる方 法です。ぜひトライしてみてください。
Amulet Logo
当サイトは、AMULET開発部の情報サイトです。
Copyright (c) 2001 AMULET Inc.
 
AMULETのトップページへ