同じIPv6アドレスなのに書き方が違う? RFC 5952 の正規化規則を読む
IPv6アドレスは0の省略の仕方や大文字小文字の違いで、同じアドレスでも複数の書き方ができてしまいます。RFC 5952 が定める「正規の表記」のルールを、具体例とともに整理します。
同じアドレスでも書き方が何通りもある
IPv6アドレスは128bitの数値を16bitずつ8組に分け、コロンで区切った16進数で表記します。たとえば 2001:0db8:0000:0000:0000:0000:0000:0001 というアドレスは、0が連続する部分を :: で1回だけ省略できるというルールのおかげで 2001:db8::1 のように短く書けます。ところがこの省略ルールには選択の余地が残っていて、同じアドレスでも次のようにいくつもの書き方が成立してしまいます。
| 書き方 | 内容 |
|---|---|
2001:0DB8:0000:0000:0000:0000:0000:0001 |
すべて展開し、16進数を大文字で表記 |
2001:db8:0:0:0:0:0:1 |
各組の先頭の0だけ省略 (:: は未使用) |
2001:db8::1 |
連続する0の組を :: で省略 |
2001:DB8::1 |
:: は使うが16進数は大文字 |
これらはビット列としては完全に同じアドレスですが、文字列としては異なります。ログの検索、ファイアウォールのルール比較、設定ファイルの差分確認などを文字列ベースで行うと、表記が揃っていないだけで「違うアドレス」として扱われてしまう問題が起こります。
RFC 5952 が定める4つの規則
IPv6アドレスの基本的な表記規則そのものは RFC 4291 (IP Version 6 Addressing Architecture) で定義されていますが、RFC 4291 は上記のような複数の書き方をいずれも許容しています。これに対し、IETFが2010年に公開した RFC 5952 (A Recommendation for IPv6 Address Text Representation) は、ログや設定ファイルで一貫した表記を得るための「推奨される正規の表記」を1つに定めました。主な規則は次の4つです。
- 16進数は小文字で書く (
a-f。大文字のA-Fは使わない) - 各組の先頭の0は省略する (
0db8ではなくdb8と書く) - 連続する0の組のうち最長のものを
::で1回だけ省略する。同じ長さの候補が複数あれば、最も先頭 (左側) にあるものを優先する - 省略できる0の組が1つだけの場合は
::を使わない (例:2001:db8:0:1:1:1:1:1は2001:db8::1:1:1:1:1にはせず、0の組をそのまま0と書く)
3番目の規則にある「同じ長さなら左側を優先」という点は見落とされがちです。たとえば 2001:db8:0:0:1:0:0:1 のように、長さ2の0の組が2か所(3〜4組目と6〜7組目)にある場合、省略できるのはどちらか一方だけです。RFC 5952 に従うと、左側の組を省略した 2001:db8::1:0:0:1 が正しい表記になります。
展開表記との往復で確認する
この正規化規則が本当に適用されているかを確かめる一番確実な方法は、短縮表記を一度すべて展開し、規則どおりに圧縮し直した結果が元の表記と一致するか比較することです。IPv6 アドレス 短縮表記⇔展開表記 変換ツールでは、入力したアドレスを展開表記と RFC 5952 準拠の短縮表記の両方で表示するため、手元のログや設定ファイルに書かれた表記がすでに正規化されているかをその場で確認できます。
まとめ
- IPv6アドレスは0の省略の仕方や大文字小文字の違いで、同じアドレスでも複数の書き方が成立する。
- RFC 4291 は表記のルールそのものを定めるが、どの書き方を使うかまでは強制しない。
- RFC 5952 は「小文字」「先頭0の省略」「最長の0の組を1回だけ
::で省略 (同じ長さなら左側優先)」「1組だけの0は省略しない」という4規則で、ログ比較やルール突合に適した「1つの正規の表記」を定めている。
RFC 5952 の原文 (英語) は IETF の RFC Editor サイトで公開されています。https://www.rfc-editor.org/rfc/rfc5952