ダイナミックトンネル

(BSD Magazine No.05)

梅本 肇/Hajimu UMEMOTO
ume@mahoroba.org

 IPv6接続する際、ネイティブに接続できれば幸せであるが、多くがIPv6 over IPv4トンネルを使用しているのが現状であろう。
 IPv6 over IPv4トンネルは、特定ルータ間でIPv6パケットをIPv4でラップしてやりとりする技術である。
 使い方は、トンネル両端のルータのIPv4アドレスを指定することで、トンネルを確立する。そして、RIPngなどの経路制御プロトコルでIPv6経路の交換をするなり静的に設定するなりして、経路制御を行うことにより、使用できるようになる。

DTCP

 さて、トンネルを確立させるためには固定したIPv4グローバルアドレスが必要である。これは、動的にIPv4アドレスが割り当てられるダイアルアップやCATVなどの環境では、IPv6できないことを意味している*01)
 この問題を解決するための方法のひとつとして、Trumpet社がDTCP(Dynamic Tunnel Configuration Protocol)を提案している。
 DTCPはIPv4 TCPを使用したプロトコルで、クライアント側からの接続要求により、サーバー側はクライアントのIPv4アドレスに対してトンネルを動的に設定するものである。また、認証にはAPOPに準じた方式を使用する。
 ここで、IPv6 over IPv4トンネルは基本的にIPv4 NATを越えることはできない。DTCPはこの制約を解決するものではないという点には注意願いたい。
 KAMEの配布キットにはRubyで記述されたDTCPサーバーおよびクライアントが含まれており、Rubyをインストールしてあれば、使用できる。
 ただし、最近の*BSDにはKAMEが統合されているが、これらは付いていない。KAMEの配布キットから持って来て、ちょっと修正すれば使用できる。

トンネルタイプ

 DTCPにはトンネルのタイプとして、hostとtunnelonlyがある。
 hostは、IPv6アドレスが1つだけ割り当てられるものである。ちょうどPPPでのダイアルアップを連想していただけると良いだろう(図1)。
クライアント                                      サーバー
---------------------------------------------------------------
接続要求       ---- ユーザ名, トンネルタイプ --->
               <--- +OK, 割り当てIPv6アドレス ---
   |                                                   |
   v                                                   v
トンネル設定                                      トンネル設定
   |                                                   |
   v                                                   v
IPv6アドレス設定                                   IPv6アドレス設定
   |                                                   |
   v                                                   v
デフォルト経路設定
   |
   v
keep-alive     --------------------------------->
(60 秒おき)    <------------ +OK ---------------
   |
   v
終了処理       -------------- quit ------------->  終了処理
               <------------ +OK ---------------
図1 hostトンネルタイプ時の処理の流れ
 tunnelonlyはトンネルの確立だけを行うもので、IPv6アドレスの割り当てや経路制御は行わない。コマンド的にはgifconfigだけを行うと言えばわかりやすいだろうか。IPv6アドレスの割り当てや経路制御は、別途手動で行うか経路制御デーモンなどで行う(図2)。
クライアント                                      サーバー
---------------------------------------------------------------
接続要求       ---- ユーザ名, トンネルタイプ --->
               <------------ +OK ---------------
   |                                                   |
   v                                                   v
トンネル設定                                      トンネル設定
   |                                                   |
   v                                                   v
keep-alive     --------------------------------->
(60 秒おき)    <------------ +OK ---------------
   |
   v
終了処理       ------------- quit -------------->  終了処理
               <------------ +OK ---------------
図2 tunnelonlyトンネルタイプ時の処理の流れ

DTCPの問題点

 DTCPを使用すると、hostタイプのトンネルは簡単に運用できる。しかし、これだとfreenet6がやっているのと何ら変わらないのでおもしろくない。:-)
 やはり、IPv4アドレスが固定でないサイトに対して、IPv6のプレフィックスを割り当てたい。
 このためにはtunnelonlyタイプを使うわけであるが、これがうまく動かない。DTCPを使用すると、gifインターフェイスの状態が動的に変化するので、経路制御デーモンがこの変化に追従できる必要がある。しかし、われわれが使用しているZebraは、まだダイナミックなインターフェイスの変化に追従できない。そのため、新たにトンネルが確立しても、経路情報が流れないのである。
 また、ダイアルアップだと、経路制御プロトコルが流れていると、いつまでたってもリンクが切れないので、不経済であり、運用上の配慮が必要である*02)

トンネルタイプの新設

 この問題を解決するために、KAME付属のdtcps/dtcpcを改造し、トンネルタイプtunnelrouteを追加した*03)
 サーバー側でユーザー毎の割り当てIPv6アドレスをDB化しておき、トンネルを張った際に、接続ユーザーに応じてスタティックルーティングを行う(図3)。
クライアント                                      サーバー
---------------------------------------------------------------
接続要求       ---- ユーザ名, トンネルタイプ --->
               <------------ +OK ---------------
   |                                                   |
   v                                                   v
トンネル設定                                      トンネル設定
   |                                                   |
   v                                                   v
デフォルト経路設定                                 経路設定
   |                                                   |
   v                                                   v
keep-alive     --------------------------------->
(60 秒おき)    <------------ +OK ---------------
   |
   v
終了処理       -------------- quit ------------->  終了処理
               <------------ +OK ---------------
図3 tunnelrouteトンネルタイプ時の処理の流れ
 DTCPではIPv4コネクションが切れる、あるいはkeep-aliveメッセージが一定時間届かないと、トンネルの回収処理を行う。hostあるいはtunnelonlyであればこれで十分である。しかし、tunnelrouteでは動的にIPv4アドレスが変化するなどの要因でトンネルが使用できなくなった際に、タイムアウトを待つまで経路情報が残ってしまうため、すぐに再接続できない。
 これを避けるために、同一ユーザーからの再接続要求があった場合、経路情報が残っていれば削除するようにしている。

DTCPサーバーの起動

 DTCPは認証にAPOPに準拠した方法を使用している。KAMEの実装では、まさに、ユーザーDBはpopperのをそのまま流用しており、ユーザー登録はpopauthコマンドで行う。
 DTCP用のユーザーはUNIXアカウントである必要はないが、/etc/passwdに登録されていないとpopauthが受け付けてくれないので、ダミーで登録しておく必要がある。
 あとは、単にdtcpsを起動すれば、tunnnelonlyタイプで運用できる。
 hostタイプのトンネルを許可する場合、dtcpsの引数に割り当てIPv6アドレスのプレフィックスを指定する。
 tunnelrouteタイプを許可するには、/usr/local/v6/etc/routetableを用意する。routetableはユーザー名と割り当てIPv6プレフィックスの対である(リスト1)。
リスト1 routetableの例
user1	3ffe:505:ff19::/48
user2	3ffe:505:ff22::/48
user3	3ffe:505:ff26::/48
user4	3ffe:505:ff02:8000::/64
 dtcpsは空いているgifインターフェイスを探して使用する。これだと、静的なトンネルと混在する際に若干不便なので、われわれは、dtcpsが使用するgifインターフェイスの範囲を-iオプションで指定できるように改造して使用している。
 なお、dtcpsはgifconfigなどのコマンドを呼び出すので、正しくIPv6対応したコマンドが呼び出されるようPATHに注意する必要がある。
 KAMEを用いてIPv6化している場合の起動スクリプトの例をリスト2に示す。
リスト2 dtcps起動スクリプトの例
#!/bin/sh

PATH=/usr/local/v6/sbin:/usr/local/v6/bin:$PATH
if [ -x /usr/local/v6/sbin/dtcps ]; then
    echo -n ' dtcps'
    dtcps -i 'gif7[0-9]' 3ffe:505:ffff:8000::
fi

おわりに

 DTCPを導入することによって、ダイアルアップでも6boneにつながることができるようになった。しばらく前まではIPv6するにはパッチを当てたり結構面倒であったが、最近は多くのプラットフォームが標準でIPv6を使用できるようになって来ている。やっぱりIPv6するには外の世界とつながらないと面白くないだろう。これまで参加したくても参加できずに指を加えていた方々も、どんどん参加しよう。


*01) ネイティブにIPv6をサポートしたPPPを使えば良いじゃないかという意見は、まだまだ普及していないので却下。:-)
*02) 当然である。だが、筆者が初めてIPv6接続した際、このことに気付かず、しばらく放置してしまった。翌月のNTTの請求書を見るのが恐かった。^^;
*03) http://www.imasy.or.jp/~ume/ipv6/dtcp/に置いてあります。


All Rights Reserved, Copyright (C) 2001 Hajimu UMEMOTO
Last Modified Aug 23, 2001
ume@mahoroba.org