仮想ネットワーク構築編

以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。

致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。

目次


■
■Part 2 VPN構築編
■

%% 解説ポイント:IPsec、PPTP、トンネル、暗号化、ルーティング
%% 目的:オフィス環境と自宅環境の間にプライベートネットワークを構築し、
%%   各リソースなどを活用する方法を解説


Part1の例では「自社と出向先」という関係をとりあげたが、それに限らず、組
織には支社、営業所、研究所、などといった単位で地理的に離れたところにいく
つかの支所が点在することが多い。接続コストの下がった現在ではどの支所であ
れインターネット接続していて、別支所とのやりとりを電子メイルで手軽で済ま
せられるようになっているだろう。

しかしPart1で触れたように、各支所が独立したLANを構成している場合、互いの
LAN内資源に直接的にアクセスするときには一度インターネットに出てから相手
側のFirewallを通過しなければならないため、情報の漏洩を防ぐための暗号化や、
IPアドレスなどを判断基準としたフィルタリングなどを考慮する必要が出てくる。
このような場合、互いのネットワーク間に新しく専用回線を引くのと同じイメー
ジで、仮想的な回線を構築するのが仮想プライベートネットワーク(Virtual Private
Network; VPN)である。

発展途上期のインターネットは、いくつかの小さなネットワークを少しずつ繋げ
合わせることで発展していた。VPNを構築することは、どこかそれに似ていて、2
点間のIP接続を確立し双方のネットワーク間のルーティングを適切に設定するこ
となど基本的な項目が含まれる。Part2もPart1と同様なるべく設定の様子を目で
確認して進めて行こう。

●個人で使うVPN

VPNの概要説明に入る前に、どのようなことにVPNが求められたのかを考えてみる。
VPNの役目としては、「離れたネットワークを専用線の代わりにむすぶ」という
機能が大きい。地理的に離れたところを自社専用線で接続するにはそれなりのコ
ストがかかる。逆に、VPNを利用すれば物理的回線にかかるコストは削減できる
ものの、組織内で流れるデータを一般のインターネット回線に乗せる危険を回避
するために暗号化処理をほどこしたり、あるいは純粋に多くの外部のネットワー
クを経由して宛先に届く(直結に比べて遠回りする)ため、データ転送速度的に少
し不利になる場合がある。

実際に「業務」で遠隔地ネットワークをプライベートネットワークとして結びつ
けたい場合は、金銭的コスト、管理コスト、要求性能と期待されるスループット
などを総合的に判断して、専用線とVPNのいずれを導入するかを決定することに
なるだろう。このようなときは用意できる機材の範囲で最も高い性能を引き出す
システムを選ぶことになる。


いっぽう、VPNを個人的規模で利用する場合には上記とは少し違ったニーズも見
えて来る。もちろん自宅とオフィス、出先から自宅などを安全に繋ぐという上記
同様のメリットもあるが、それ以外にも友人や親戚との家庭LANで相互接続して
写真を交換したり、あるいは知人の持つ固定IPアドレスを利用して自宅の計算機
でサービスを立ち上げるなどの趣味的な欲求を満たすこともできる。こうした用
途の場合、VPNに求められるものは「高度なセキュリティと性能」よりも「適度
なセキュリティと手軽さ」となる。

今回は主に個人で利用するVPNをとりあげ、ネットワークの仕組みとそれを取り
扱うツールの習得を主眼において解説していきたい。なお、性能を重視する本格
的なVPNの導入方法については、本誌2003年2月号〜5月号 Setting Up FreeBSD 
が詳しいので参考にして欲しい。FreeBSD以外のプラットフォームでも稼動する
VPN システムについても解説されている。



●ポートフォワーディングとVPN

Part1で説明したポートフォワーディングも、離れたホスト間にトンネルを作成
してそこに何らかのパケットを通すという点で共通している。それぞれの性質を
まとめると、

ポートフォワーディング	特定のサービスポートのみの転送
			接続するのは「ローカルポート」と「リモートポート」
			ユーザレベルでも設定可能

VPN			IPアドレス的に離れたホストを接続する
			2つのネットワーク同士の接続も可能
			管理者権限が必要

のようになる。離れた二つのネットワークで情報を密に交換したい場合、どちら
を利用するかを決めるにあたっては、想定される利用形態を吟味する必要がある。
比較してみると、VPNであればTCP/UDPを問わず全てのサービスをトンネル接続で
きるのだが、構築する手間もずいぶん大きいうえ、両端の接続点でのセキュリティ
対策を考慮する必要がある。


●VPNで必要となる基礎技術

VPNは既存のインターネットのパケットにさらにIPデータグラムを閉じ込めて
2点間をむすぶ。既存のインターネットをあたかも物理接続線のように利用して
いる。VPNに限らずインターネットを流れるパケットは、Part1で触れたTCP/IPの
プロトコル階層に応じていくつかのヘッダを付加して届けるようになっている
【図 い】。

---[図 い]------------------------------------------------------------\
↑ アプリケーション層		[送信データ]
| トランスポート層		[送信データ|TCP/UDP]
| インターネット層		[送信データ|TCP/UDP|IP]
↓ネットワークインタフェース層	[送信データ|TCP/UDP|IP|PPP]

%%% 2003年2月号P106 図2 のような図です
----------------------------------------------------------------------/

これをさらにまとめて一塊の送信データと見なして、さらに各層のヘッダを付加
していって通常のインターネット回線に流すのがVPNのデータ転送の考え方であ
る。これを「カプセル化」といい、各層で、上位層から受け取ったデータの中味に
関与することなく次々と渡して行くので理論的にはこのような繰り返しを幾重に
も続けて行ける。VPNを実現するときには、カプセル化に加えて両端点でのルー
ティングを設定することで、両端ホストの外からは実際に物理回線があるのと同
じイメージで(LANのように)接続できる【図 ろ】。

---[図 ろ]------------------------------------------------------------\



   +---------+           インターネット           +-----------------+
   |NAT(NAPT)|-------- 〜〜〜〜〜     〜〜〜------|  Global address |
   |  ルータ |		Host1からHost2に	  |  Host-2         |
   +----+----+		トンネルが		  +-----------------+
        |		貫通している			    10.1.0.1(private)
    ----+---+---+
       +----+----+
       |(Client) |
       |  Host-1 |
       +---------+
         10.2.0.50
	 (private)

2003年3月号 Setting Up FreeBSD p105 の図
と同様です。
----------------------------------------------------------------------/


実際のVPN構築作業は、トンネルの両端となるホストで Point to Point の接続
を確立し、両ホストの周囲にぶら下がるホストに対して適切なルーティングを行
なうことで成り立っている。

また、構築したVPNを介して通信する場合、本来プライベートネットワークに流れるべき
ものをインターネットに流すことから、接続開始のときの認証(正しいホスト同
士か)と、トンネル路の暗号化を適切に選ぶ必要がある。認証方法や、暗号化の
有無などはVPN接続にどのシステムを使うかによって異なる。


●PPPを使ったVPN接続実験

PPP(Point to Point Protocol)は、通信媒体としてアナログ回線、Ethernet、
ATM、TCP/UDP などが使える柔軟性を持つプロトコルなので、VPNのトンネリング
を確立するためには非常に利便性が高い。まずは、もっとも手軽にVPNを構築で
きる "PPP over SSH" を設定してみよう【コラム は】。SSHを利用することで、通
信路が暗号化されることになり、とくに意識した設定を行なわなくても安全な通
信が確保できるのはメリットの一つである。

---[コラム は]--------------------------------------------------------\

"PPP over SSH" は、SSHコネクションの中にTCP/IPを通すVPNとなる。SSHコネク
ション自体TCPであり、その中にさらにTCPデータグラムを通すことは、良くない
結果をもたらす可能性があることが知られている。

 cf) ・http://sites.inka.de/sites/bigred/devel/tcp-tcp.html
       (Why TCP Over TCP Is A Bad Idea)
     ・本誌 2003年3月号 p112 コラム「VPNを構成する要素の注意点」

簡潔に説明すると、TCPにはパケットの到達性を保証するため、消失パケットを
再送するアルゴリズムが実装されている。実際には「消失した」のか「到達が遅
いだけ」なのかを確実に判別することはできないので、設定したタイムアウト内
に届かないときは、送信元に再送要求を送る。このタイムアウトは実際の回線状
況に応じて変化してゆくのだが、この処理を外側のTCPと内側のTCPで二重に行なっ
た場合、再送要求を必要以上に繰り返す結果をもたらすことがあるというもので
ある。

筆者が個人的に常用している "PPP over SSH" の使用範囲では、通信負荷も極め
て低く、回線的ボトルネックが低速安定(Flets ADSL 1.5Mbps; 実効500Kbps程度) 
のものなので、感知できる遅延は発生していないが、場合によっては大きな遅延
を発生する可能性があることを留意しておいて頂きたい。実際のところ、経路的
にTCPでなければ張れないケースもあるので、状況に応じてTCP, UDP いずれ
を利用するかの判断をすることが必要である。
----------------------------------------------------------------------/

基本となるのはSSH接続であるから、SSHでのリモートホスト接続性を確保してか
らPPPの設定に移る。以下のような方針で作業を行なう。

	・接続の概要は【図 に】の通り片方のホストは全てNAPTルータの中、
	  もう片方は、グローバルIPアドレスを持つゲートウェイホストが1台
	  ある
	・PPPのアクセスはグローバルIPアドレスをもつホスト(図中saturn)で
	  行う。以下、便宜上着信側と表す。
	・「LANその1」側のホスト(図中venus)から着信側サーバに向かって
	  SSHアクセスを開始する。以下、便宜上発呼側と表す。

二つのLANが存在し、互いをVPN接続する。LAN-1 のFirewall内にあるホスト
venusとLAN-2のゲートウェイホストsaturnを PPP over SSHでむすぶ。この設定
にのためには、セキュリティを考慮して次のような設定で行なう。

---[図 に]------------------------------------------------------------\

        LAN-1                                  LAN-2
 +------------------------+             +---------------------------+
 | Private network        |             |                           |
 |  192.168.1.0/24      +------+        |   +-----------+           |
 |---+--------+------->-|NAPT  |----------->+ Global    |           |
 |   |        |         |Router|----------->+ 10.10.10.1|           |
 |+------+  +-------+   +------+        |   | [saturn]  +           |
 ||other |  |[venus]|     | 10.9.9.1    |   +----|------+           |
 |+------+  +-------+     |             | private|192.168.2.1       |
 |         192.168.1.1    |             |        |192.168.2.0/24    |
 +------------------------+             |  +-----+---+------+       |
                                                     |                  
                                                +----+--+            
                                                |client |               
                                                +-------+ ....           

----------------------------------------------------------------------/

	・ともにVPN専用ユーザ権限でpppプログラムを実行する
	・venusからstarunへのSSHログインは公開鍵認証方式とする

この作業の終了後、実際にPPPの接続設定を行なう。以下の作業例で # で終わる
プロンプトはrootでの入力を意味する。

・VPN専用ユーザの作成

  新しいユーザ vpn (グループvpn)を作ろう。ここでは、vpnユーザのホームディ
  レクトリを /etc/ppp/vpn に設定した。両方のホストで以下のようにしてユーザを
  作成する。

---------NetBSD, Solaris の場合
	グループ vpn の作成
	# groupadd vpn
	  ~~~~~~~~~~~~
	ユーザ vpn の作成
	# useradd -g vpn -d /etc/ppp/vpn vpn
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------Linux の場合
	グループ vpn の作成
	# groupadd vpn
	  ~~~~~~~~~~~~
	ユーザ vpn の作成
	# useradd -g vpn -M -d /etc/ppp/vpn vpn
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	# mkdir /etc/ppp/vpn
	  ~~~~~~~~~~~~~~~~~~
	# chown vpn /etc/ppp/vpn
	  ~~~~~~~~~~~~~~~~~~~~~~
---------FreeBSD の場合
	グループ vpn の作成
	# pw groupadd vpn
	  ~~~~~~~~~~~~~~~
	ユーザ vpn の作成
	# pw useradd vpn -g vpn -d /etc/ppp/vpn
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  混乱を防ぐため、この vpn ユーザの作成は、発呼側/着信側両方とも同じユー
  ザ名、ホームディレクトリで作るのが良いだろう。また、useradd しただけの
  状態では passwd ファイルのパスワードフィールドに * が含まれ、パスワー
  ドによるログインはできないので、このままにしておく。

・SSHによるRSAログインの自動化

  発呼側(venus)で vpn ユーザになり、鍵のペアを作成する。
  パスフレーズは空にする。

  venus# su vpn
         ~~~~~~
  venus% ssh-keygen -t dsa -f ~/.ssh/vpn
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Created directory '/etc/ppp/vpn/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /etc/ppp/vpn/.ssh/vpn.
Your public key has been saved in /etc/ppp/vpn/.ssh/vpn.pub.
The key fingerprint is:
33:64:a5:3c:ac:05:02:f3:e9:17:42:b1:21:76:5c:f7 vpn@venus

  生成された鍵のうち公開鍵(~vpn/.ssh/vpn.pub)を着信側(saturn)の
  ~vpn/.ssh/ の authorized_keys ファイルに保存する(既にある場合は追加)。
  ファイルのコピーには、一度自分の一般ユーザ権限宛への scp を利用するの
  が良いだろう【註 ほ】。

---[※ ほ]------------------------------------------------------------\
vpnユーザで一度着信側ホストにSSH接続することで、~vpn/.ssh/known_hosts ファ
イルができるという副次効果もあるので vpn ユーザのまま scp すると良い。
----------------------------------------------------------------------/


  venus% scp ~vpn/.ssh/vpn.pub <一般ユーザ>@saturn:
	 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The authenticity of host 'saturn (10.10.10.1)' can't be established.
RSA key fingerprint is 75:f1:28:40:3f:fe:24:54:22:b3:3f:40:9a:cd:02:99.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added saturn,10.10.10.1' (RSA) to the list of known hosts.

  (着信側)
  saturn# su vpn
	  ~~~~~~
  saturn% cd
	  ~~
  saturn% mkdir -m 700 .ssh
	  ~~~~~~~~~~~~~~~~~
  saturn% cat ~<一般ユーザ>/vpn.pub  >> .ssh/authorized_keys
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  saturn% chmod 600 .ssh/authorized_keys
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	  (authorized_keys ファイルへの追加が終わったら<一般ユーザ>の
	   vpn.pub ファイルは消す)

  ここまでで、発呼側(venus)の vpn ユーザから、着信側(saturn)にパスフレー
  ズなしでログインできるか確認する。SSHログインには先ほど作った鍵を利用
  する。

  (発呼側のvpnユーザ)
  venus% ssh -i ~/.ssh/vpn saturn
	 ~~~~~~~~~~~~~~~~~~~~~~~~
NetBSD 1.6Q (SATURN) #0: Wed Apr 2 01:56:16 JST 2003

Welcome to NetBSD!

  % whoami
    ~~~~~~
vpn
  % exit
    ~~~~

  もし、パスフレーズやパスワードを聞いて来る場合は

	・双方にインストールされているSSHのプロトコルバージョンの違い
	・authorized_keys ファイルのオーナーとパーミッションなど

  を確認する。無事ログインできたら、さらなる安全のため、この鍵でログイン
  してくることを許可するIPアドレスを絞り込む。着信側(saturn)に作成した
  authorized_keys ファイルの該当行の先頭に from="IPアドレス" という表記
  を追加する。

  (着信側のvpnユーザ)
  saturn% cd ~/.ssh
  saturn% vi authorized_keys

           +---- from="IPアドレス" を行頭に追加
  ---------+-----
  from="10.9.9.1" ssh-dss AAAAB3NzaC1kc3MDDDCBDPxDi48swWrI2w3ss1p7jsnprcXNVC93ossmMiI8xMwadqVQ0MYghrY8W0mG/bIOr32PjhJtC9eBWjHDbGD4P9KsgGHvhHkXGM5bmr1QKPJFd3rRDU8Fn3mVpw3rHKXNw5w+3dN5gRjVh8HB3te6p4Bp4Ovrn13jVruPtjkWCyrnDDDDFQDKsUj0YPguZQF6VzgITqT3FUM+MQDDDIEDm39ZQX7Dh5FOmIendRC3d/gI7YDmUrRDjPz295K0hQpzKBfNEDtZ7xOeJ5yUBvE0DaWJJHEqP3FfpQ3ht5pZXnzktRN3m5mYmyc+pj3NT/Z+NNkXhjOeuyU5V03pJJIJOggDFbKvg7DqP89hr78/wQQkUhWeJw01yDrfdu3HX3cDDDCBDJaOGO7phD9a03BdNtYcwjp+M8R4RGFj6KDdaIEryDvkixE4C4N3chuY/qO+6gtcwduVjYErOqOgHgOD7JzQuhmEfRrrdR+/25H6hQJBFXiE73Th822unqwGt1C5n53P9HMdsj3NO5Xw33+Emmg4r33pqGVzTP35HKQ3F8dsir3P vpn@venus

  from= を追加することで、他のネットワークからはログインできなくなる。



・PPPのクライアントとサーバの設定

  ここまでの作業で "PPP over SSH" の基盤となる "over SSH" が完成した。次
  はPPPによる接続の設定のみである。PPPの実装は数多く存在するが、Paul
  Mackerras らによる pppd (NetBSD, Linux, Solaris等)と、かつて iij-ppp
  で知られていた FreeBSD user-ppp のいずれかの実装であれば、Unixユーザの
  ほとんどが利用できるだろう。

  ここでは、PPP実装として pppd と FreeBSD user-ppp(以下 user-ppp) を利用
  して、サーバ/クライアントそれぞれの設定を行なう方法について手順を追っ
  て行こう。



・通信デバイスとしてコマンドを指定する方法(発呼側)

  ダイヤルアップによるPPPでは、デバイスとしてモデム(COMポート)などを利用
  する。pppd と user-ppp ではモデム以外にもいろいろなものを指定できる。
  PPP over SSH の場合は SSH を利用してリモートホストのpppサーバプログラ
  ムを起動する「コマンド」を指定する。

  【pppdの場合】
  pppdではptyオプションで起動スクリプトを指定する。ptyを含めたほかのオプ
  ション指定をファイルに保存してそれを読み込めるので、今回はそれを利用す
  る。デバイスとしてスクリプトを利用し接続時のネットワークインタフェース
  のIPアドレスを指定する場合、以下のようなファイルを作成する(これを
  /etc/ppp/vpn/vpn-saturn とする)。

----------[ /etc/ppp/vpn/vpn-saturn (2行) ]---------------------------
	pty <スクリプト>
	192.168.1.1:192.168.2.1
	----+-----  -----+-----
            |		 →saturn側のIPアドレス
	    →→ venus側のIPアドレス
----------------------------------------------------------------------


  「pty <スクリプト>」 により、スクリプトを起動してその標準入出力を利
  用して通信路を確保する。この<スクリプト>にはサーバ側のpppプログラム
  を起動するコマンドラインを書いておく。またインタフェースアドレスは互い
  に区別できれば何を付けても良いが、通常互いのプライベートネットワーク側
  のインタフェースのアドレスを付けておく。良くある間違いとしては、着信側
  (待ち受け側)のグローバルIPアドレスを書いてしまうものがあるが、PPPの発
  呼に使うアドレスへのルーティングがPPPセッション確立によって上書きされ
  て通信できなくなるのでこれは避ける。

  【user-pppの場合】
  user-ppp では /etc/ppp/ppp.conf にデバイスの指定を書く。ppp.conf は標
  準でサンプルが付いているのでそのファイルとオンラインマニュアル ppp(8)
  を参照して書き方を理解して欲しい。ppp.conf の大まかな書式は

	セクション名:
	   各種パラメータの設定

  となっている。たとえば、この設定で作成する接続の名前を vpn とし、その
  接続に利用するデバイスをコマンドに指定したいときは以下のようなエントリ
  を作成(追加)する。

	vpn:
	  set device !<スクリプト>
	   :
	   :

  また、デバイスとしてコマンドを利用する場合に必要となる代表的なパラメー
  タの設定を含めると以下のようになる。

	vpn:
            allow user vpn			# 許可するユーザを vpnに
            set device !<スクリプト>		# 起動するコマンド
	    set timeout 0			# タイムアウトなし
            set log phase chat connect lcp ipcp command # 採取するログの指定
            set dial				# chat script なし
            set login				# login script なし
            set ifaddr 192.168.1.1 192.168.2.1	# インタフェースのアドレス
            set server /var/tmp/loop.2 "" 0177	# pppctlで使用


・vpnを特権グループに加える(発呼側にpppdを使う場合)
  
  今回の接続ではSSHによる認証だけを行ない、pppレベルでの認証は行なわない。
  これには pppd を特権モードで動かす必要がある。pppdのグローバルオプショ
  ンファイル /etc/ppp/options に以下の1行を追加する。

	privgroup	vpn

  また、いくつかのLinuxの場合、pppdは一般ユーザ権限からはデフォルトでは
  利用できないようになっている。この場合は、pppdの起動を root 権限で行な
  うか、pppdにsuid-rootする。

	# chmod u+s /usr/sbin/pppd

  suid-root する場合にも /etc/ppp/options ファイルに privgroup の設定が
  なければ vpn ユーザには十分な権限が与えられないので options ファイルへ
  の記述は省略できない。


・外部からのPPP接続を受ける方法(着信側)

  【pppdの場合】
  SSH接続の着信に適したオプションを指定しやすいよう、オプションファイル
  を作成しておくと良い。

	(着信側)
	saturn# su vpn
		~~~~~~
	saturn% cd
		~~
	saturn% vi vpn-option
		~~~~~~~~~~~~~
	(以下の内容で vpn-option ファイルを作成)

	noauth                  # 認証を省略(SSHで行うので)
	notty                   # ttyデバイスを要求しない


  着信時にpppdを起動するときはこのオプションファイルを指定して、

	/usr/sbin/pppd file vpn-option

  と起動することになる。

  【user-pppの場合】
  /etc/ppp/ppp.conf ファイルに、待ち受けに適したエントリを作成する。


	vpn-in: 
		allow user vpn 
		set timeout 0 
		set log phase chat connect lcp ipcp command 
		set escape 0xff 

  着信時にpppdを起動するときはこのエントリを指定して、

	/usr/sbin/ppp -direct vpn-in

  と起動することになる。


・発呼スクリプトの作成

  再度発呼側の設定に戻ろう。pppコネクション開始時に利用するスクリプトを
  作成する。着信側で利用しているPPP実装が pppd か user-ppp かによってコ
  マンドラインが異なるので、着信側で利用するソフトウェアに応じてスクリプ
  トの中味を決定する。ここでは、いずれの場合も発呼スクリプトを connect
  として例示する。

	(発呼側の作業)
	venus% touch /ppp/vpn/connect
	       ~~~~~~~~~~~~~~~~~~~~~~
	venus% chmod +x /etc/ppp/vpn/connect
	       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	venus% vi /etc/ppp/vpn/connect
	       ~~~~~~~~~~~~~~~~~~~~~~~
	(ファイルの内容は以下のようにする)

  【着信側が pppd の場合】
#!/bin/sh
exec ssh -x -i /etc/ppp/vpn/.ssh/vpn saturn /usr/sbin/pppd file vpn-option

  【着信側が user-ppp の場合】
#!/bin/sh
exec ssh -x -i /etc/ppp/vpn/.ssh/vpn saturn /usr/sbin/ppp -direct vpn-in

  発呼側で user-ppp を利用する場合は、作成したスクリプトをデバイスとして
  指定する。/etc/ppp/ppp.conf に先ほど作成した vpn エントリのところを

	vpn:
	  set device !/etc/ppp/vpn/connect
	      :
	      :

  とする。pppdで発呼する場合はコマンドラインから指定する。

・発呼

  以上で準備は整ったので、実際に接続を開始する。
  【pppdの場合】

	venus% pppd file /etc/ppp/vpn/vpn-saturn
	       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  【user-pppの場合】

	venus% ppp -ddial vpn
	       ~~~~~~~~~~~~~~

  pppdの場合は ppp0 インタフェース、user-pppの場合は tun0 インタフェース
  を確認する(以下の説明ではppp0とする)【註 へ】。

	venus% ifconfig ppp0
	       ~~~~~~~~~~~~~
ppp0      リンク方法:Point-to-Pointプロトコル  
          inetアドレス:192.168.1.1 P-t-P:192.168.2.1 マスク:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:31 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
          衝突(Collisions):0 TXキュー長:3 
          RX bytes:1350 (1.3 Kb)  TX bytes:1703 (1.6 Kb)

	saturn% ifconfig ppp0
		~~~~~~~~~~~~~
ppp1: flags=8051 mtu 1500
        inet 192.168.2.1 -> 192.168.1.1 netmask 0xffffff00
        inet6 fe80::240:45ff:fe04:623%ppp1 ->  prefixlen 64 scopeid 0x4

---[※ へ]------------------------------------------------------------\
pppインタフェースの利用状況により、ppp1, ppp2… などとなる。
----------------------------------------------------------------------/

  互いの通信に成功すれば "PPP over SSH" の設定は完了する。
%%%%%%この ping の段落省略候補です。

	venus% ping -c 1 192.168.2.1 
	       ~~~~~~~~~~~~~~~~~~~~
PING 192.168.2.1 (192.168.2.1) 送信元 192.168.1.1 : 56(84) bytes of data.
64 バイト応答 送信元 192.168.2.1: icmp_seq=0 ttl=255 時間=9.001ミリ秒

--- 192.168.2.1 ping 統計 ---
送信パケット数 1, 受信パケット数 1, パケット損失 0%
Round-Trip 最小/平均/最大/mdev = 9.001/9.001/9.001/0.000ミリ秒

	saturn% ping -c 1 192.168.1.1
		~~~~~~~~~~~~~~~~~~~~~
PING 192.168.1.1 (192.168.1.1): 56 data bytes
64 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=12.935 ms

----192.168.1.1 PING Statistics----
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 12.935/12.935/12.935/0.000 ms


・ルーティングの設定

  この接続により、venusとsaturnは LAN-1 と LAN-2 のゲートウェイホストと
  なった【図 と】。

---[図 と]------------------------------------------------------------\
VPNのみに注目したネットワーク構成

  +----- LAN-1 ------+              +------ LAN-2 -----------+
  |  192.168.1.0/24  |		    |    192.168.2.0/24      |
  |                  |		    |                        |
  |  -+-     +-----+ |		    | +---------+      -+-   |
  |   |      |venus| |		    | |saturn   |       |    |
  |   +------+     --------------------         +-------+    |
  |   |      |     --------------------         |       |    |
  |   |      +-----+ |		    | +---------+       |    |
  |   +              |		    |                   |    |
  |   |              |		    |                   |    |
  |   |              |		    |                   +    |
  |                  |		    |                   |    |
  |                  |		    |                        |
  +------------------+		    +------------------------+

----------------------------------------------------------------------/

  両ホスト配下となるマシンから互いのネットワークへのルーティングを張れば
  LAN-1 と LAN-2 に属するホスト同士で互いに通信できる。

  【LAN-1側から】

	(*BSD, Solaris の場合)
	venus# route add -net 192.168.2.0 -netmask 255.255.255.0 \
		192.168.2.1
	(Linuxの場合)
	venus# route add -net 192.168.2.0/24 gw 192.168.2.1

  【LAN-2側から】

	(*BSD, Solarisの場合)
	venus# route add -net 192.168.1.0 -netmask 255.255.255.0 \
		192.168.1.1
	(Linuxの場合)
	venus# route add -net 192.168.1.0/24 gw 192.168.1.1

  これらのルーティング情報の追加は、pppのセッション確立時に自動で行なう
  ことができる。pppdの場合は /etc/ppp/ip-up の名でスクリプトを作っておけ
  ば、

	/etc/ppp/ip-up インタフェース  デバイス  速度 \
		       ローカルIPアドレス  リモートIPアドレス  \
		       IPパラメータ

  という6つの引数で起動されるので、第5引数を利用すればよく、user-pppの場
  合は /etc/ppp/ppp.linkup に

	vpn:
	   add 相手ネットワーク HISADDR

  と書いておけば、HISADDRの部分がリモート側のIPアドレスに置換されてルー
  トが追加される。これらのスクリプトの呼ばれ方については pppd(8), ppp(8) 
  を参照して欲しい。

  また、VPN構築以前にすでに venus, saturn をゲートウェイとして利用してい
  る場合は不要だが、パケットフォワーディングを行なうように確認する。

	【FreeBSD, NetBSD】
	# sysctl -w net.inet.ip.forwarding=1

	【Linux】
	# sysctl -w net.ipv4.ip_forward=1


	-	-	-	-	-	-	-	-	-

●PPTPを使ったVPNの構築

  クライアントPCを離れた場所にあるLANに繋ぐ場合は、必ずしもクライアント
  PCがUnixでない場合がある。このような場合はPPTPを利用するのが良い。
  PPTP(Point to Point Tunneling Protocol; cf. RFC2637)は、Microsoftも参
  加して仕様を策定していることもあって MS-Windows からも利用できる。

  拠点となるLANのUnixホストでPPTPサーバを起動しておけば、Windowsクライア
  ントからもPPTP接続が可能となる。PPTPを実現するものはいくつかあるが、今
  回は幅広いシステムで利用可能な PoPToP を紹介する。


・PoPToPの導入

  今回動作確認したPoPToPのアーカイブ名は pptpd-1.1.3.tar.gz で【コラム 
  る 参照】、OS付属のパッケージ導入システムなどを利用してもすぐにインス
  トールできるだろう。Linuxであればソースからのコンパイルも容易だ。

	# tar zxpf pptpd-1.1.3.tar.gz
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
	# ./configure --prefix=/usr/local
	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	# make all install
	  ~~~~~~~~~~~~~~~~
  FreeBSDは ports カテゴリ net/poptop にて make

	# cd /usr/ports/net/poptop
	# make all install

  NetBSD は pkgsrc カテゴリ net/poptop にて make

	# cd /usr/pkgsrc/net/poptop
	# make all install

  NetBSD pkgsrc の PoPToP のベースは pptpd-1.0.1 だが、automake,
  autoconf の最新版がインストールされているシステムなら、
  pptpd-1.1.3 も

	# LIBS=-lintl ./configure  〜〜configureのオプション〜〜

  によりインストール可能である。

--[ コラム る PoPToP PPTP のバッファオーバフロー問題 ]---------------------\

2003年4月9日時点で PoPToP の 1.1.4-b3/1.1.3-20030409 より古いものに
remote exploit の可能性があることが指摘されている。Linuxでのみ
バッファオーバーフローの可能性がある模様だ。

cf.) PoPToP PPTP server remotely exploitable buffer overflow
http://archives.neohapsis.com/archives/bugtraq/2003-04/0144.html

これはパケットヘッダに含まれる、パケットサイズを表す16ビット値に0か1を埋
め込まれた場合、そのパケットをread(2)するときにスタックを溢れさせる巨大
な読み込みを発生させてしまうというものである。pptpd-1.1.4-b3 と
pptpd-1.1.3-200304-9 では修正されている。

上記URLにある【リスト を】のパッチを当てるか、Project PoPToP のWebページ
http://sourceforge.net/projects/poptop/ より最新版を入手してそちらをイン
ストールする方が良いだろう。

執筆時以降、より新しい勧告があるかもしれないので、Project PoPToP のペー
ジを確認するよう気をつけて欲しい。


----[ リスト を]----------------------------------------------------------
--- ctrlpacket.c.old 1999-12-23 23:43:33.000000000 +0200 
+++ ctrlpacket.c 2003-04-09 18:58:21.000000000 +0300 
      -254,8 +254,8  
         } 
         /* OK, we have (at least) the first 2 bytes, and there is data waiting */ 
         length = htons(*(u_int16_t *) packet); 
- if (length > PPTP_MAX_CTRL_PCKT_SIZE) { 
- syslog(LOG_ERR, "CTRL: Control packet > PPTP_MAX_CTRL_PCKT_SIZE (length =
%d)", length); 
+ if (length <= 10 || length > PPTP_MAX_CTRL_PCKT_SIZE) { 
+ syslog(LOG_ERR, "CTRL: 11 < Control packet (length=%d) < ", length); 
                 /* we loose sync (unless we malloc something big, which isn't a good 
                  * idea - potential DoS) so we must close connection (draft states that 
                  * if you loose sync you must close the control connection immediately) 
--------------------------------------------------------------------------

---------------------------------------------------------------------------/

  PoPToP の PPTP サーバプログラムは pptpd である。pptpd は 1723/tcp にて
  PPTP 接続を受け、バックエンドとしてpppdを起動してPPTP接続を確立する。
  起動時に使用する主な設定ファイルは二つで、pptpd自身が参照するもの(通常
  pptpd.conf)と、pppdを起動するときに引数として渡すもの(通常
  options.pptpd)である。単純な設定では、それぞれ以下のようにする。



--------[ /etc/ppp/pptpd.conf ]---------------------------------------
option	/etc/ppp/options.pptpd
----------------------------------------------------------------------

--------[ /etc/ppp/options.pptpd ]------------------------------------
name pptpd			# chap-secretsに使用するサーバ名
proxyarp
+chap
#mppe-128			# mppe対応パッチをあてたpppd
#mppe-stateless			# の場合有効化
#+chapms-v2			# chapmsパッチを当てたpppdの場合有効化
----------------------------------------------------------------------

  この例のように認証方式にCHAPを使用する場合は /etc/ppp/chap-secrets ファ
  イルにユーザ名とパスワードを記録する。

--------[ /etc/ppp/chap-secrets ]-------------------------------------
#ユーザ名	サーバ名	パスワード	IPアドレス
taro		pptpd		michadameyo	*
----------------------------------------------------------------------


  FreeBSD ports からインストールした場合(./configure --with-bsdppp で
  makeした場合)は、バックエンドとして user-ppp を起動する。このとき、
  /etc/ppp/ppp.conf に "pptp" というエントリを要求するので以下のように作
  成する。

         pptp:
           set speed sync
           enable chap

  認証に用いる情報は /etc/ppp/ppp.secret に、

	ユーザ名 <TAB> パスワード

  という書式で記述しておく。

・Windowsクライアントからの接続

  Windows2000/XP などからサーバに接続してみよう。「ネットワークとダイヤ
  ルアップ接続」あるいは「マイネットワーク」から「新しい接続の作成」を選
  択する。

---[図 と]------------------------------------------------------------\
新しい接続ウィザード

%img img-02.png
----------------------------------------------------------------------/

  VPN接続を選ぶ。
---[図 ち]------------------------------------------------------------\
新しい接続ウィザード: ネットワーク接続の種別→VPN

%img img-03.png img-04.png
----------------------------------------------------------------------/

  接続名を決めて、サーバとなるホストアドレス(ホスト名)を入れて設定完了で
  ある。
---[図 り]------------------------------------------------------------\
新しい接続ウィザード: 接続名→VPNサーバの選別

%img img-05.png img-06.png
----------------------------------------------------------------------/

  新しい接続のアイコンが現れるので、それをクリックし、ユーザ名とパスワー
  ドを入れると接続を開始する。

---[図 る]------------------------------------------------------------\
新しい接続: 

%img img-10.png
----------------------------------------------------------------------/

  このとき、サーバ側で /var/log/messages を監視しておくと接続に失敗した
  場合の原因が分かるだろう。

【註 ぬ】
---[※ ぬ]------------------------------------------------------------\
実運用ではmppeによる暗号化通信も入れるのが望ましいだろう。この場合バック
エンドとなる pppd をmppe対応にすればよい。今回筆者の環境では特定のOS間で
しか利用できなかったため紹介を見送った。
----------------------------------------------------------------------/

・Unixクライアントからの接続

  UnixホストからもPPTP接続が可能である。
  http://pptpclient.sourceforge.net/
  にある pptpclient は Linux, FreeBSD, NetBSD に対応した PPTP 接続クライ
  アントソフトである。ソースからのコンパイルも簡単で、以下の手順で終了す
  る(Linux, NetBSD)。

	# tar zxpf ppp-linux-1.2.0.tar.gz
	# cd ppp-linux-1.2.0
	# make all install

  FreeBSDは ports/net/pptpclient からインストールするのが簡単だろう。

	# cd /usr/ports/net/pptpclient
	# make all install

  pptpclient でインストールされる pptp コマンドは、PPTPサーバへのコネク
  ション(1723/tcp)を開いた後バックエンドでpppクライアントプログラムを起
  動する。pptp の起動は以下の書式で行う。

	# pptp  PPTPサーバ  [pptpオプション]  [pppオプション]

  バックエンドで起動するpppクライアントのための設定も必要で、pppdの場合
  は最低限認証用の設定が必要である。認証にCHAPを利用する場合は
  /etc/ppp/chap-secrets ファイルに認証情報を書く。この場合はPPTPサーバ
  (pptpd)の場合と同じでよい。もし、chap-secrets ファイルに

	taro	*	himitsu		*

  などと書いた場合は

	# pptp PPTPサーバ user taro

  とする。FreeBSDの ports からインストールした pptp
  の場合はバックエンドに user-ppp を起動するのでこの場合
  /etc/ppp/ppp.conf に

	pptpclient:
	  set authname <認証ユーザ名>
	  set authkey  <パスワード>
	  set timeout 0

  といったエントリを作成して

	# pptp PPTPサーバ pptpclient

  のように起動する。



--[ コラム VPNを利用した Global IP アドレスの確保とその注意点 ]------------\

VPNは「プライベート」なネットワークを接続することが主な目的だが、これを
「グローバル」なIPv4アドレスで行なうおもしろい使用例がある。

自宅のコンピュータを利用して自分だけのWWWサーバを上げたいものの、固定IP
アドレス発給サービスが利用できないような場合、これまではいわゆる
「Dynamic DNSサービス」を利用して、「www.自分のドメイン」といったホスト
名を動的に更新しながら使う方法が用意されてる。IPアドレスが変わってしまっ
た場合には、更新依頼をネームサーバに送ることでしばらくのちには新しいIPア
ドレスを引けるようになる。この間ホスト名とIPアドレスの対応が取れていない
時間が発生するが、WWWサービスの場合はつながるようになるまで待っていても
らえば良いだけで重大な問題は起きない。しかし、メイルサーバなどはそのホス
トに対して外部からメッセージを送ることになるので、もした別のホストがSMTP
接続を受けてしまったら、本来届いてはいけない人のホストにメッセージを送り
つけることになり、場合によっては深刻な問題を引き起こす。このためメイルサー
バを上げたい場合にはどうしても固定IPアドレスが必要となる。

このようなときに、他者の持つ固定グローバルIPアドレスをVPNで自宅まで伸ば
すことで、実質的に固定IPアドレスサーバとしてふるまわせることができる。
http://www.interlink.or.jp/myip/ などがその一例で、PPTPを利用して固定グ
ローバルIPアドレスを、非固定グローバルIPアドレスのホストに伸ばして来るこ
とができる。

  〜〜〜|〜〜〜〜〜                  〜〜|〜〜〜〜〜
        |                                |回線を契約しているプロバイダA
   +----+------------+                  [+]
   |                 |                   |e.f.g.h
   |                 |                   |     +------------+
   |                 -----------------+  |     |            |
   |               [h.j.k.l]    VPN   |  |     |            |
   |プロバイダBの持つ-------------+   |  |NAPT |            |
   | ネットワーク    |            |   |  |a.b.c.d自宅サーバ |
   |                 |            |   |  +[fxp0]            |
   |                 |            |   +---------            |
   |                 |            |     x.y.z.w             |
   |                 |            |     [tun0]              |
   |                 |            +-------------            |
   |                 |                         |            |
   +-----------------+                         +-----+------+
                                                     |    自宅LAN
   非固定 グローバルIPアドレス  a.b.c.d     +------+-+-------+---------+
    固定  グローバルIPアドレス  x.y.z.w            |         |
                                             [Client PC2]  [Client PC2]....


自宅サーバは、外部と直接つながっているIPアドレス a.b.c.d と、VPNでつながっ
ている x,y.z.w の二つを持つことになる。このときに必要な要件は以下のよう
になる。

	・PPTP接続を構築すること
	・外部からきた固定グローバルアドレスへの接続にはVPN側に
	  パケットを返す
	・(サーバを含めた)内部LANから出ていくパケットは実際の回線
	  (非固定側)から出て行くようにする

VPNによるもう一つのIPアドレスを引き込む前は、自宅ホストの defaultroute 
は実際に回線契約をしているプロバイダAのアドレスとなっているはずである(図
中 e.f.g.h)。ここにVPNで生じた新しいインタフェースアドレスx.y.z.w 宛のパ
ケットが来た場合その返しパケットも本来の defaultroute である e.f.g.h か
ら出て行こうとするが、プロバイダAはソースアドレス(この場合 x.y.z.w)が自
己管轄下にないものなのでフィルタリングアウトして葬り去られることになる。
つまり全く別のネットワークから x.y.z.w のいずれかのポートに接続しても、
返りパケットが来ないので通信できないように見える。

では、自宅ホストの defaultroute をVPN側に向ければ良いかというと、その場
合自宅LANから出るパケットが全てVPN経由で出て行くので行きも返りもプロバイ
ダAとプロバイダBを経由することになって無駄になる。

このような場合、自宅サーバ上の実対外接続インタフェース(図中fxp0)から出て
行こうとする、ソースアドレスが x.y.z.w のものだけをVPN側にフォワードして
やることで問題は解決する。たとえば IP Filter の場合、ipfに次のルールを渡
せば良い。

	pass out quick on fxp0 to tun0:h.j.k.l. from x.y.z.w to any

同様に FreeBSD IPFW の場合は、

	ipfw add fwd h.j.k.l ip from x.y.z.w to any

とする。

このような問題は回線を2本以上引いてマルチホームを実現するときにも起こり
得る問題である。一般向けの回線接続料が安価になってきたので自宅にADSLを引
く場合に、あとから引いた回線のグローバルアドレスに外部から接続しても反応
が返らないことがある。これも同様に、返しパケットのソースアドレスを見て、
副回線のグローバルアドレス発のパケットは副回線側に返すようにするとよい。

--------------------------------------------------------------------------/




●まとめ

VPNを構築して遠隔ネットワークをむすべば、ほぼ全てのサービスを互いに利用
できるようになる。ここで最も気をつけるべきことは、相手側のLANをどの程度
信頼できるかという点である。もし、オフィス内に部外者が簡単にネットワーク
に繋げるダムハブなどが放置してあったりするのではまったく「プライベート」
は守れない。個人同士で使う場合でも相手側に自由接続できる無線LANが解放さ
れていたらVPNを通じたこちらも同じ危険度になる。そんな状態では通信路を暗
号化しても認証手順を強化しても意味がない。VPNを構築するときは、VPNの部分
だけでなく、両端ネットワークを含めた総合的な安全性を考えなければならない。

そうした性質をふまえたうえで、自らの手でVPNを構築することは実際にVPNによっ
てもたらされる恩恵ももちろんだが、設定作業を通じて多くの基礎知識が得られ
るところにも意味がある。まずは自宅にある2台のUnixホスト同士を繋げるとこ
ろから始めてみてはいかがだろうか。


%%%% Local Variables:
%%%% buffer-file-coding-system: euc-jp
%%%% End:


yuuji@example.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]