IPv6 に NAT が無いことの影響

我が家に IPv6 環境がやってきました。フレッツ光ネクストの回線にして、ISP 側に申し込んで、IPoE(いわゆるネイティブ方式)で IPv6 のインターネットにつながりました。

おそらく、多くの一般家庭であれば、今時のルータさえ用意すれば、特段、意識することなく、IPv6 につながる環境になると思います。おうちサーバがあっても、「自宅内は IPv4 で十分」と考えれば、何も問題はありません。

が、一応、北の大地で技術系サラリーマンの端くれとして生活の糧を得ている身としては、おうち LAN でも IPv6 を使わないでどうする、と、無駄な努力をするのでした(^^;

IPv6 とは

なんて話はどうでもよいですね。立派な専門家の方々がたくさん解説を書いています。

NAT が無い

これも割と有名な話だと思います。そもそも、NAT によってグローバルアドレスを延命する、というアイデアが出る前に、「次世代の IP を作らなければ、アドレスが枯渇する」と言われてました*1。

故に、かどうかは分かりませんが、IPv6 には NAT がありません。という事はどういう事かというと、「インターネットに繋ぎたければ、末端の端末、一つ一つに、グローバルアドレスを持つべし」という事になります。

実際、IPv6 に対応したご家庭用ブロードバンドルータで、IPv6 でつながる環境になると、IPv6 のアドレスの自動構成によって、おうちの中の PC にグローバルな IPv6 アドレスが付与されます。その状態で、例えば Google に繋ぐと、どこにも NAT が入らず、グローバルな IPv6 アドレスでつながっています。

個人向けの接続サービスだと、IPv4 アドレスがルータの WAN 側に一個、割り当てられるのが普通ですが、IPv6 の場合は、プレフィックス、つまり、アドレスのネットワーク部が割り当てられます。128 bit の IPv6 アドレスのうち、上位 64 bit のアドレスが ISP から割り当てられ、下位 64 bit は「勝手に付けてよし」という状態です*2。

プライベートアドレス

NAT が無く、普通にグローバルアドレスが PC に割り当てられているのだから、IPv4 のプライベートアドレスのような物は必要ないか、というと、そういうわけでもありません。例えば、サーバのアドレスは固定したい訳ですが、もし、個人向けの安い契約で済ませようとすれば、割り当てられるプレフィックスが変わるたびに、サーバのアドレスを変更する必要があります。固定の契約を結んでも、ISP を変えたら、サーバのアドレスを変更しなければいけません。インターネット側からアクセスするためのサーバならしかたないですが、内部だけで使うサーバもこれではたまりません。

当初は、「NAT は悪だ! だからプライベートアドレスなんて不要だ!」みたいな雰囲気があったのですが、結局、上記のような事を考えると、プライベートアドレスに該当する物が必要、ということで、IPv6 では ULA と呼ばれるアドレス帯が用意されました。

ULA は「fd」で始まるアドレスで、組織統合などがあった場合にも衝突しないように、計算方法を提示されています。また、実際に計算するための Web ページが、BSD 系 OS の IPv6 を実装した Kame プロジェクトにあります。

http://www.kame.net/~suz/gen-ula.html

自分が持っている PC や機器の MAC アドレスを入れれば、48bit のプレフィックスを生成してくれます。これで、IPv4 でのプライベートアドレスを使う事ができ、内部サーバに固定の IPv6 アドレスを割り当てる事ができます。

再び、NAT が無い

IPv4 のプライベートアドレスで内部のネットワークを作り、それでインターネットに接続できたのは、NAT のおかげです。しかし、IPv6 では NAT がありません。このままだと、

  • グローバルのアドレスが割り当てられた物は、インターネットにはつながるけど、ULA を付けた内部のサーバに、直接はつながらない*3。
  • ULA を付けたものは、内部のサーバにはアクセスできるが、インターネットにはつながらない。

ということになります。そもそも、内部のサーバは ULA を付ける訳ですから、じゃぁ、このサーバのアップデートとかはどうするんだ? という事になります。

で、どうするかというと、「どっちのアドレスも付ける」という事になります。IPv6 が「複数のアドレスを持つのが普通」と言う時、通常使うアドレスとリンクローカルアドレスの事を指して解説している事が多いのですが、ULA を使う場合には、「ULA とグローバルの両方のアドレスを持つ」という事になります。IPv4 だと内部のネットワークがプライベートアドレスだけで済んでいたのと、大きな違いになります*4。

Windows 上で、ipconfig で見ると、こんな感じになります。

   自動構成有効. . . . . . . . . . . : はい
   IPv6 アドレス . . . . . . . . . . . : 240b:1234:5678:9abc:def0:1234:5678:9abc(優先)
   IPv6 アドレス . . . . . . . . . . . : fdfe:dcba:9876:5432::beef(優先)
   一時 IPv6 アドレス. . . . . . . . . : 240b:1234:5678:9abc:fedc:ba09:8765:4321(優先)
   リンクローカル IPv6 アドレス. . . . : fe80::123:4567:890a:bcde%11(優先)

上記の例では、プレフィックスは 64 bit で、

  • グローバルなアドレスは、「240b:1234:5678:9abc:def0:1234:5678:9abc」と「240b:1234:5678:9abc:fedc:ba09:8765:4321」
  • ULA は「fdfe:dcba:9876:5432::beef」
  • リンクローカルアドレスは「fe80::123:4567:890a:bcde」

になります。

おうちサーバにグローバルな IPv6 と ULA を付ける

ということで、おうちサーバを IPv6 対応にするには、グローバルなアドレスと ULA の両方を持つように設定する必要があります。

が、ここで落とし穴が。

私のおうちサーバは CentOS なのですが、CentOS で普通に GUI でアドレス設定をしようとすると、

  • 手動で設定すれば、自動構成のアドレスは生成されない。
  • 自動構成のアドレスが生成されるようにすると、手動でアドレスを設定できない。

という状態になります。サーバなので、ULA のアドレスを手動で設定したいのですが、そうすると、自動構成で割り当てられるはずのグローバルなアドレスは付与されない、という状態になります。企業のように、グローバルのプレフィックスが固定の場合は問題ないですが、おうちサーバだと、プレフィックスが変わる可能性があるので、グローバルのアドレスを手動で設定する訳にはいきません。

IPv6 の自動構成アドレスは、ルータが送信する RA(Router Advertisement:ルータ広告)のメッセージを受信し、そのメッセージに含まれるプレフィックスの情報を使って、自分のアドレスを決定します。RA を受信して自動構成アドレスを生成しつつ、固定で ULA を付けたい。IPv4 で例えれば「DHCP と手動設定の両方のアドレスを付けたい」といった感じです。

いろいろ嗅ぎまわったところ、「/proc/sys/net/ipv6/conf/eth0/accept_ra」が 0 な事が分かりました。おそらく、これを 1 にする必要があるだろうと思って、

# echo 1 >/proc/sys/net/ipv6/conf/eth0/accept_ra

として「service network restart」としてみると、0 に戻ってしまいます。

# find /etc/sysconfig/network-scripts/ -type f -exec grep -Hn accept_ra {} \;

とすると、確かに、この値を書き換えているところが見つかります。

これを追いかけると、どうやら IPV6_AUTOCONF が yes なら accept_ra が 1 になるようです。GUI から IPv6 アドレスを手動すると、/etc/sysconfig/network-scripts/ifcfg-eth0 に IPV6_AUTOCONF が no に設定されます。これを yes にすれば良いのですが、今度は NetworkManager が上書きしてしまいます。

ということで、

  • NetworkManager を無効にする。もしくは、インタフェースを NetworkManager の管理外にする*5。
  • /etc/sysconfig/network-scripts/ifcfg-インタフェース名 のファイルで「IPV6_AUTOCONF=yes」とする。

とした上で、ULA の固定アドレスを設定すると、両方のアドレスが割り当てられるようになります。ifcfg-インタフェース名で IPv6 に必要な設定内容はこんな感じになります。

IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6ADDR=fdfe:dcba:9876:5432::1234/64

NetworkManager が残念

NetworkManager が動いていると、あるとき、意図しない設定になっている目に遭って、「サーバだから、そんな物は必要ない」みたいな事を言う人は多いのですが、とはいえ、無線 LAN や VPN のように、ユーザのデマンドで接続する場合には、NetworkManager がある方が便利だし、慣れていない人でも、それなりに設定できるので、個人的には「なら、手なずけてやる」と思って使ってきたのですが、NetworkManager を止めざるを得なかったのは、KVM のホストでブリッジを作った時と合わせて2度目。う〜ん、ちょっと残念。

*1:その頃は IPng (IP next generation) と言われていました

*2:フレッツ光ネクストのネイティブ接続で個人契約の場合。サービスメニューによって変わる可能性が無いわけではないですが、基本、64 bit のプレフィックスと思っていて間違いないと思います。

*3:ルータを介してルーティングすれば接続可能。ルータは割り当てを受けているプレフィックスを持つホストが、内部にいる事を知っているので、ルータの LAN 側に ULA のアドレスを付けるれば、基本的には OK

*4:まぁ、インターネットへの接続は全部、Proxy 経由、という構成もあり得ますが、その Proxy は少なくとも、グローバルなアドレスと ULA の両方を持つ必要があります。

*5:/etc/sysconfig/network-scripts/ifcfg-インタフェース名のファイルで NM_CONTROLLED=no とします。