IPv6ほんとの話(2)

IIJlab newsletter #8
$Id: index.html,v 1.1.1.1 2003/08/28 05:58:03 itojun Exp $
(註: この文章はIIJ社内報11月号の再録です。 一部意味が通らなかったりするかもしれません。 また、一部文章をいじっています)
はたと気づくともう締切です。 時間のたつのははやいもの、もう(執筆時)11月も半ばに近付いてきてしまいました。 ついこないだ正月だと思っていたのに、なんてことでしょう。 とうとう1999年だというのに、町にはエアカーも走っていなければ 地球外生物との出会いもありません。 結構期待していたのに、SFのようにはいきませんね。

前回いくつか入手 可能なIPv6実装を紹介しましたが、遊んでみて頂けたでしょうか? 今回はIPv6アドレスについて少々。 かなり深いテーマがいくつもあるので書ききれているかどうか心配です。 不明の点などありましたら、メイル などでご意見ご質問頂けると嬉しいです。


IPv6アドレス

前回もちょっとだけ出て来ましたが、IPv6アドレスを表記するときは、 16進数4桁を8つ、コロンでつなげて書きます。 例えば、
3ffe:0501:0410:0100:5254:00ff:feda:48bf
なんてのがIPv6アドレスになります。 ちなみに、これはわたしの自宅にある実験マシンのIPv6アドレスです。 ネットワークアドレスを書くときは「アドレス/ネットマスク長」で書きます。 たとえば、IIJ技術研究所が現在使っている実験用ネットワークは、
3ffe:0507:0000:0000:0000:0000:0000:0000/32
です。

いちいち0をたくさん書くのも面倒なので、 0の部分は以下のように省略できます。

  1. 各16進数4桁の部分について、先頭の0は省略してよい。
    つまり「0507」を「507」、「0000」を「0」と 書いてよい。
  2. アドレスの中で1箇所だけ、「0:0:0」と0の続くところを 「::」と略してよい。
このルールに従うと、上記の実験用ネットワークアドレスは
3ffe:0507:0000:0000:0000:0000:0000:0000/32
  ↓ あたまの0を略す
3ffe:507:0:0:0:0:0:0/32
  ↓ 0:0:0を略す
3ffe:507::/32
と書き直すことができます。 これでだいぶ見やすくなりましたね。

IPv4アドレスとIPv6アドレスの違いは、大きくわけて以下の6点あります。

  1. インタフェースにアドレスを最初から複数つけられる
  2. スコープの概念がある
  3. マルチキャストの多用(ブロードキャストはなくなった)
  4. anycastがある
  5. インタフェースIDが入ってる
  6. 最初からCIDRベース、つまり (a)不連続なサブネットマスクはない、 (b)プロバイダベースのアドレス割り当てをする
以下順に述べていきましょう。

1インタフェースに複数のアドレス

IPv4では、多くの場合「インタフェースひとつにつきIPv4アドレスを ひとつしかつけない」という仮定のもとで設計、運用されてきました。 最近はwebのホスティングなどの都合で無理矢理複数のIPv4アドレスを複数 つけることも増えていますが、かなり例外的な処理です。 このため、IPv4アドレスを複数つける場合、 実装によっては本名の「プライマリアドレス」と別名の 「セカンダリアドレス」とかいう区別をさせられたかと思います。 例えばYAMAHA RTシリーズだったら、
ip lan address 210.160.95.110/28
ip lan secondary address 192.168.1.1/24
なーんてことをやったはずです。

IPv6は、最初から複数のIPv6アドレスをインタフェースにつけることを 想定して設計されています。 このため、多くのシステムではプライマリ/セカンダリアドレスの区別がありません。 IPv6スタックを作成するときには、インタフェースには好きなだけいくつでも IPv6アドレスがつけられるように、またパケットを出すときは適切なアドレスを 選んで使うように気をつけてプログラムを書かなければなりません。

スコープ

IPv4アドレスは(プライベートアドレスを除き)全世界で一意のものでした。 例えば、210.160.95.97というIPv4アドレスを持つホストは 世界にひとつしかありません。 IPv6アドレスには、それぞれに「スコープ」が定義されています。 スコープの和訳は「有効範囲」とでもするのがいいんでしょうかね。 IPv6アドレスは「そのスコープ内」で一意です。
link-local scope
fe80::/10ではじまるアドレスはlink-localアドレスと 呼ばれる「あるリンク内でのみ一意」なアドレスです。 これは、ルータのない環境や、neighbor discoveryプロトコルという ARPのかわりのアドレス解決プロトコルなどで使います。 「リンク内でのみ一意」ですので、あるethernet媒体上のfe80::x というホストと、隣のethernet媒体上のfe80::xが同じホストという 保証はありません。
site-local scope
fec0::/10ではじまるアドレスはsite localアドレスと呼ばれる 「組織内で一意」なアドレスです。 隣の会社に、自分の使っているアドレスfec0::xと同じアドレスを持つ ホストがあっても不思議ではありません。 このアドレスは、外部とインターネット接続していない組織で 組織内の通信のためなどに使うことができます。 IPv4のプライベートアドレス、例えば10.0.0.0/8と 対比してもらえるとわかりやすいかもしれません。
global scope
全世界で一意なglobalアドレスには、現在2000::/3ではじまる Aggregatable Global Unicast Address (RFC2374) が使われています。 IIJ技術研究所の使っているネットワーク、 3ffe:0507::/32もこの中にはいっていますね。
RFC2373では、 他にも単一ホスト内の通信のためのnode-local scope、 siteより大きいけどglobaより小さいorganization localが定義されています。 スコープは最大16個まで定義できますが、 普通に使うのは上に挙げた3つでしょう。

複数アドレスとスコープ

さて、各インタフェースには複数アドレスがつけられます。 インタフェースにスコープの異なる複数のアドレスをつけると、 いままでできなかったような使い方ができます。

IPv4では、各インタフェースに単一のIPv4アドレスしか つけられない実装が多かったので、 組織全体にグローバルアドレスを割り振るか、 組織全体にプライベートアドレスを割り振るかの選択しかできませんでした。 つまり、外部と直接通信できるホストとそうでないホストを組織内に 混在させることができませんでした。 IPv6では、スコープつきのアドレスがありますので、以下のようにすれば 組織内に両者のホストを混在させることができます。

このようにすれば、プライベートアドレスを使用した場合よりも柔軟な セキュリティポリシが実現できます。 通信の機密性や認証が必要なら、 IPv6では実装義務になっているIPsecを組み合わせればよいでしょう。

このように、スコープルールを導入したおかげでより柔軟にネットワークを 構成できる可能性がありますが、 そのぶんDNSデータベースやルータでの経路管理が面倒になります。 期待させておいてなんですが、site localアドレスはまだまだ議論の的です。 どのくらい使いものになるかは今後の議論と実装次第でしょう。

ちなみに、NATの話。 IPv6では「スコープつきアドレス+IPsec+フィルタ」を活用し、 NATをなくそう、ということになっています。 NATは、IPヘッダの中身やftpなどの上位プロトコルのペイロードの中身を書き換えたり しなければならないので、IPsecと非常に仲が悪い技術です。 また、上位プロトコルのペイロードの中身を書き換える、ということは、 新しいプロトコルが出るたびにNATの改造をしなければならない、ということを 意味しています。 雨後のたけのこのようにストリーミング系プロトコルが出て来たり、 ゲームなど用に仕様非公開のプロトコルが増えたりしている昨今、 NATを使い続けるのは非現実的だと思います。

マルチキャストとanycast

IPv6のアドレスには、1対1通信のためのユニキャストアドレス、 1対多通信のためのマルチキャストアドレスに加え、 anycastアドレスというのが用意されています。 ブロードキャストはなくなって、マルチキャストの一部にとりこまれました。

マルチキャストアドレスはff00::/8ではじまります。 マルチキャストにもやっぱりスコープがあって、 スコープは16進数の4桁目で決めます。 ff02::/16で始まるアドレスはlink-local scope multicastアドレスと 呼ばれ、「あるリンク内向けのマルチキャスト」のために使われます。 192.168.1.255みたいなブロードキャストはなくなりましたので、 そのかわりにリンク内の全ノード向けのマルチキャストアドレス、 ff02::1を使います。 IPv4ではマルチキャストは(ビデオデータ配送などを除けば) あまり活用されていませんでしたが、 IPv6では基本仕様でもマルチキャストが多用されています。 IPv6ではマルチキャストを実装しないとethernetアドレスの解決もできません。

anycastアドレスは、ネットワーク上のサーバ探索を楽にするために導入された アドレスです。 anycastアドレスを複数のノードに割り振っても構いませんが、 anycastアドレス行きのパケットはどれか1台のノードだけに届き、 他のノードには届きません。 たとえば、全てのネームサーバにあるanycastアドレスを割り振っておいたとします。 そのanycastアドレス宛にパケットを投げれば「一番近所のネームサーバ」だけに パケットが届きます。 このアドレスについても考えないといけないことはたくさんあります。 例えば、anycastアドレスは現在のところパケットのソースアドレスには 使えないので、anycastアドレスに向かってTCP接続をすることはできません。 つまり、ネームサーバにanycastアドレスを割り振っても、 zone transferをすることはできませんし、 UDPパケットサイズを越えるような返答を送ったりすることもできません。 このへんについても早晩解決しなければならないでしょう。

インタフェースID

RFC2374に 従うIPv6アドレス割り当て法では、 各ホストに割り当てられるIPv6アドレスは、実際には上位64ビットの 「ネットワークプレフィクス」部分と、下位64ビットの「インタフェースID」 部分に分けられます。 例えば、うちの自宅の実験マシンのIPv6アドレスは、
  プレフィクス		インタフェースID
3ffe:0501:0410:0100 + 5254:00ff:feda:48bf
  ↓
3ffe:0501:0410:0100:5254:00ff:feda:48bf
のようにできています。 インタフェースIDの部分はethernetアドレスや乱数で生成されます。 衝突検出機構もありますので、インタフェースIDが衝突することはありません。 また、各サブネットのサブネットマスクは、64ビット固定になっています。

サブネットマスクが固定されたことで、 ネットワーク設計にかなり大きな変化が起きるはずです。 IPv4では、「このネットワークには何台の機器を繋ぐか」を あらかじめ予想してサブネットマスクを決めていました。 たとえば、「10台くらいしか繋がないから/28にしよう」とか 「30台くらい繋ぐから/27欲しい」とか。 もし予想の台数を越えてしまったら、サブネットマスクを増やしたり 減らしたりといった作業が必要になっていました。
IPv6では(すくなくとも RFC2374で 決まっている範囲では) サブネットマスクとインタフェースIDとの間を固定長で 切り分けているので、このような苦労はなくなります。 アドレスの側には制限がありませんので、 各サブネットにはネットワーク媒体の許す限り機器を繋ぐことができます。 現在のIPv4ネットワークの構成法よりもルータの数は少なくて 済むのではないかと思います。 そのかわり、MACアドレス学習の賢いethernetスイッチを買ったり、 最近御無沙汰しているラーニングブリッジに再登場願うことになるかもしれません。

インタフェースIDのビット数を大きくとってあるおかげで、 IPv6ではホストの自動設定が楽になっています。 IPv4のDHCPは結構複雑な状態遷移のあるプロトコルですが、 IPv6では状態のない簡単なとりきめでホストの自動設定ができます。 ルータはサブネットに関する情報を一定時間ごとに広告します。 ホストは聞こえた情報と自分のインタフェースIDを組み合わせて勝手に アドレスを設定できます。 このプロトコルはstateless address autoconfigration (RFC1971) と呼ばれています。 これについてはまた次回以降詳しく述べます。

しかし、128ビットのアドレス幅のうち半分をインタフェースIDに使うのは、 ちょっと無駄使いかなあ、という気もします。 RFC2374よりも 大枠を決めている RFC2373では、 将来もうすこし違った形のアドレス割り当てをすることも可能なように 書かれています。 困ったら RFC2374ベースの 割り当てをやめて次の割り当て法を考えればよいのでしょう。

CIDR

現在、IPv4ではCIDRベースのアドレス割り当てが行われています。 すなわち、以下のようなことが行われています。 IPv6の場合もこれはそのまま適用されますが、 IPv4の場合よりもアドレスつけかえを楽にしようという試みがいくつかなされています。

前述のとおり、 インタフェースに複数のIPv6アドレスを割り当てることができますので、 ある組織はふたつ以上のプロバイダからアドレスを買うことができます。 例えばある組織がプロバイダをA社からB社に乗り換える場合、 以下のようにすればなめらかな移行ができるはずです。

  1. プロバイダAとの接続はそのままにしておいて、 プロバイダBとも接続する
  2. 組織内のノードに、プロバイダAからのIPv6アドレスと プロバイダBからのIPv6アドレスを両方つける
  3. じょじょにプロバイダAからのIPv6アドレスを外していく
  4. 全部外せたら、プロバイダAとの契約を打ち切る
「じょじょに」というところと、「組織内へのアドレス配布」の 手間が問題になりますが、どちらについても解決策は提案されています。

IPv6では、前述のようにルータがサブネットの情報を広告します。 この際に、サブネットのアドレスプレフィクスと同時に「プレフィクスの寿命」が 配布されます。 プレフィクスの寿命は、各ホストのアドレスの寿命を決めます。 このため、広告するプレフィクスの寿命をただしく制御すれば、 徐々にプロバイダAのアドレスが使われないようにしむけることができます。
あとは組織内のルータにどうやってプロバイダBのIPv6アドレスを配るかですが、このために router renumberingプロトコルというのが提案されています。 このプロトコルは、組織内のルータについているIPv6アドレスを全部まとめて つけかえてしまうためのプロトコルです。

こんな風に話がうまくいけば苦労はしないわけですが(笑)、 今後の実験に期待していてください。 router renumberingプロトコルについては、 いまのところ実装も経験も非常に少ないのが難点です。


今回はIPv6アドレスについて、たくさん脱線しながら説明しました。 アドレス構造の説明だけでもこれだけ書かないといけないのに、 この先どうやって説明していこうか結構不安を感じます。 明日は明日の風が吹く...
というわけで、また次回。

(IIJ技術研究所 はぎの(いとう)じゅんいちろう)


IIJlab / playground
Copyright(C) 1998 by Internet Initiative Japan Inc. All rights reserved.
Unauthorized reproduction/redistribution is strictly prohibited. Absolutely no warranty.