追記(2008/01/02)

この追記に関しては「UbuntuでIPv6を無効化」を参照のこと

最近、このメモにいくつかリンクが張られていたので、参考にさせてもらった。
その中で、Ubuntuでは /etc/modprobe.d/blacklist の中に「blacklist ipv6」を追加すればOKというブログがあったので、さっそく試して見た。(「Fedora で IPv6 をスマートに無効化」) これだけでIPv6が止まれば、こちらの方がスマートだ。が、残念ながらFedora 8(今回はFedora 7でなくてFedora 8で実験した)では効かなかった。
/etc/modprobe.conf の「install ipv6 /sbin/modprobe -n -i ipv6」をコメントアウトして、blacklistに「blacklist ipv6」を追加してリブート。lsmodにてipv6のモジュールがロードされていないか確認したところ、残念ながらロードされていた。この辺はディストリビューションによる違いだろうか。(もっとも以前、試したかも知れないが、5ヶ月も前のことで忘れてしまった。確か無線LANのモジュールの設定でblacklistを色々と触っていたのだが、どうも思ったように動作してくれなかった記憶がある。)

余談だが、新しいPCを買ったのでUbuntu 7.10をインストールしてみた。画面まわりのLook&FeelはFedoraよりも洗練されていて良かった。Ubuntu 7.10はVMware Server 2.0の認定ホストOSにもなっているので使いたかったのだが、新しいPCのチップセットIntel G33との相性が悪いらしい。時々、画面が消える(VGAビデオ出力がなくなる)。比較的新しいハードウェア・プラットフォームに関してはやはりFedoraの方が対応が早いかと思って、後ろ髪を引かれながらFedora 8に切り替えた。

追記(2008/01/25) Fedora 8における不具合

現在、Fedora 7の他にFedora 8のマシンを使っているが、上記の方法でIPv6を無効化してある。Fedora 8になって一つだけ問題が出た。(Fedora 7までは無かったのだが。) GNOMEの「ファイヤーウォールの設定」ツールを使ってフィルタ等の設定を行なう際に、最後に「Apply」ボタンを押すが、すると

Configuration failed

/usr/sbin/lokkit -f --enabled --removemodule=nf_conntrack_ftp --port=2049:tcp --port=2049:
udp --port=137:udp --port=138:udp --port=139:tcp --port=445:tcp --addmodule=nf_conntrack_n
etbios_ns --port=443:tcp --port=22:tcp --port=80:tcp --port=111:tcp --port=111:udp --port=
123:tcp --port=123:udp --port=177:udp --port=32770:udp --port=44928:tcp --port=54011:tcp -
 -port=5900:tcp --port=5901:tcp --port=5902:tcp --port=5903:tcp --port=59385:tcp --port=593
85:udp --port=69:tcp --port=69:udp --port=902:tcp

Failed to restart ip6tables.

というようなメッセージが出るようになった。(日本語環境で使っていないので、日本語でどの様な言葉なのかは分からない。)

IPv6のモジュールをロードしていないにも関わらず、無理やりip6tablesを再起動しようとしているようである。勿論、全てのRun Levelでip6tablesはサービスの設定で起動しないようにしてる。無効化しているサービスを無理やり再起動しようとしているので、明らかにバグと思われる。

ちなみに、このメッセージが出てもIPv4の設定はちゃんと変更される。また、ファイヤーウォール設定ツールを終了する際に、「更新が保存されない」旨のメッセージが出るので強制終了させることになるが、それでもIPv4に関しては問題なく設定が保存されている。

どうすればIPv6を無効化できるか

色々なところで紹介されている方法では、実は、IPv6を無効化することが出来なかった。的確にIPv6を無効化する方法を探してみた。

LinuxIPv6を無効にするには、基本的にカーネルの(menuconfig等で)IPv6の機能を指定せずにカーネル再構築をすれば完璧なのだが、カーネルのバージョンが上がる度に再構築するのは手間もかかるし時間もかかるので、できればやりたくはない。

メモリを節約するための重い腰を上げてググってみた。ところが、ディストリビューションによって設定のしかたがまちまちで、Fedora関連でも色々な方法が紹介されている。しかし、実際にやってみてもIPv6が無効になっていないケースが多かった。

無効化できなかった方法

参考のためにやってみてIPv6を無効化できなかった例を書いておくが、今の環境は以下のとおりである。

ネットで良く出てくるのが以下の例である。

/etc/modprobe.conf に次の一行を追加

alias net-pf-10 off

/etc/sysconfig/network の NETWORKING_IPV6 をnoに設定

NETWORKING_IPV6=no

さっそく試してみたが、lsmodで確認するとIPv6のモジュールがロードされている。無効化できていない。ip6tablesも動いている。

無効化できた方法

結局、自分なりに色々と試行錯誤して、/etc/modprobe.conf に次の1行を追加すればIPv6を無効化できた。

install ipv6 /sbin/modprobe -n -i ipv6

この1行を追加するだけでOKだった。 etc/sysconfig/network に「NETWORKING_IPV6=no」は追加していない。上の1行をmodprobe.confに入れただけ。

なお、この方法にたどり着いたのは次のような流れだ。Webで検索すると

alias net-pf-10 off
alias ipv6 off

を追加する、という方法がほとんだった。確かに上記の方法でもIPv6を無効化できた。しかし、このalias行の意味は「alias」の本来の目的からするとちょっと疑問。

alias行はモジュール名に別名を定義するわけで、一般的には論理的なモジュール名と物理的なモジュール名を結びつけるとか、長い名前のモジュール名を短い名前で代用するのに使うらしい。例えば、

alias eth0 b44

という風に、「eth0」という論理的な名前に「b44(Broadcomイーサネットコントローラのドライバ)」を結びつけて「eth0」を活性化する際に実際に「b44」を活性化するということかと思う。(時間がないのでソースを追っていないので、manの記述と直感で書いている。)

では、「off」を指定すると言うのはどういうことか? 「alias ipv6 off」はIPv6のモジュールをロードするときに「off」というモジュールをロードしなさい、とうことにならないか? 実際にブートするとサービスの起動メッセージに

FATAL: Module off not found.

と表示される。「off」というモジュールは存在しないらしい。つまりこの方法はIPv6のモジュールをロードする時にワザとエラーを発生させてロードさせないという方法らしい。(そのため、ipv6でロードが失敗した場合、内部エイリアスのnet-pf-10で再度ロードしようとするためnet-pf-10も「失敗」させなければならないため2行必要になるのだと推測できる。)

副作用がなければ「IPv6を活性化しない」という目的を達成できるわけでこれでも構わない。私も良くお世話になっている「@IT」等にもこの方法を紹介しているので(Fedora CoreでIPv6を無効にするには)かなり一般的な方法として定着しているようだ。もともと今回、改めてIPv6の無効化を試してみようと思ったのはVMwareの「Guest Operating System Installation Guide」を読んでいてゲストOSでIPv6が動いていると都合が悪いこともあるので、IPv6を無効化する方法が書いてあった。例えば、97ページに次のような記述がある。

To disable IPv6 in a virtual machine running Linux

1 If the file /etc/sysconfig/network contains the line NETWORKING_IPV6=yes, change the line to
    NETWORKING_IPV6=no.
2 In the file /etc/modules.conf, add the following lines:
    alias ipv6 off
    alias net-pf-10 off

こういったマニュアルにも「alias lpv6 off」が紹介されている。(でも、これをやるとFatal errorメッセージが出ることは書かれていない。)

この方法でも特に不都合があるわけではない。しかしFatal errorが出るのは私としては気持ち悪い。(Fatal errorと言っても実質Warning程度の話ではあるが。)

そこで、modprobe.confとmodprobeのman pageを読んでみた。modprobeの-n (--dry-run)オプションでipv6モジュールをロードした"つもり"にさせれば良いのでは?と思い、試したところでエラーメッセージも出ないし、実際にipv6モジュールがロードされないのでIPv6の機能も無効化できた。この方法が「正解」かどうかは分からない。今のところ副作用は出ていない。alias offよりは気分的には良い。

最近、流行りの方法(2009/02/13)

最近、ネットを見ているとIPv6を無効化する方法として、/etc/modprobe.confに

install ipv6 /bin/true

を追加するというのがいくつか見られた。確かに“何もしない”という意味では“install ipv6 /sbin/modprobe -n -i ipv6”より短くてお手軽かも知れない。その意味ではワザとエラーを起こさせる“alias ipv6 off”も同じなのでだけど。

追記(2009/02/14) カーネルを再構築した場合

/etc/modprobe.confでIPv6のモジュールをロードするのは抑制できるが、カーネルそのものを再構築してIPv6の機能を削った場合、(当然IPv6のモジュールも生成されないわけだから)/etc/modprobe.conf に“install ipv6 /sbin/modprobe -n -i ipv6”などと書いてあると起動時にエラーメッセージがでる。その場合は、/etc/modprobe.confから該当行を削除すればいい。

追記(2008/03/03) 環境変数 NETWORKING_IPV6 について

/etc/sysconfig/network の NETWORKING_IPV6 をnoに設定

NETWORKING_IPV6=no

しても、IPv6の無効化は出来ないが、この変数はちゃんと設定しておいた方が良い。/etc/modprobe.confで無効化した場合、モジュールが読み込まれないのでIPv6は機能しないが、アプリケーションによってはこの環境変数を見てIPv6が動いているかどうか判断するものがあるようである。

たまたま、Fedora 6のマシンの設定を変更していて、/etc/modprobe.confで無効化すると、ブートの際、iptablesサービス起動の時に「このカーネルIPv6オプションを指定しないで作られているのではないか」といった趣旨のメッセージが出た。/etc/sysconfig/network の NETWORKING_IPV6 をnoに設定したらメッセージが出なくなった。

ちなみに、Fedora 8ではこの変数を設定してもGNOMEの「ファイヤーウォールの設定」ツールは文句を言ってくる。この辺、一貫性に書けるのはLinuxの宿命か。

しかし、なぜIPv6が有効になっているのか

日頃思うのだけど、IPv6とか、ほとんどの人が使わない機能がデフォルトで有効になっているのか不思議だった。しかも単に有効になているだけならまだしもip6tablesも動くし、FirefoxIPv6を優先にパケットを投げるのでメモリも消費するし動作も遅くなる。Linuxの利用環境でIPv6を利用できる人はどれ位なのだろう、また、その中でIPv6を使っている人はどれくらいなのだろう? メモリとかCPUリソースをかを使わないのであれば盲腸の様に、そこにあっても構わないが、庶民のパソコンでは無効になっている方がありがたい。

最初は政治的な意図があるのかと疑っていたが、良く考えるとFedoraIPv6に限らず、搭載している機能はデフォルトで有効になっているのを基本としているようだ。例えば、avahiとかsendmailbluetooth、Smart Cardなどなど。一般ユーザがあまり使わない機能やそのハードウェアを搭載しているPCが少ない機能もデフォルトで有効になている。それはWindowsと同じでどんな環境でインストールしても直ぐに使えるようにということらしい。

まぁ、それはそれで良いとは思うが。だったら「サービスの設定」などのツールで簡単に無効化できるようにしておきべきかと思う。最近は仮想マシン上で作業をするようになって来たので、1GBのメモリでは十分とは言えず、できる限り要らない機能は外しているが、カーネルを再構築するのも手間がかかるのでIPv6だけはそのままにしていた。

installコマンド行について(メモ)

/etc/modprobe.confに

install ipv6 /sbin/modprobe -n -i ipv6

を追加したが、man pageによると「modprobeは、通常はカーネルにモジュールを登録するが、installコマンドを記述すると、代わりにここで指定されたcommand を実行する。」とある。

そこでinstallコマンド行で明示的に/sbin/modprobeコマンドを呼び出すが-n (--dry-run)オプション付きで実行する。-nオプションは「実際にモジュールを登録したり削除したりする以外の、全ての処理を行なう。」そうで、つまり「やったふり」をしてくれる。

ただし、-nだけだと、呼び出されたmodprobeコマンドは再度/etc/modprobe.confを参照しようとして無限ループに落ち込むらしい(?)。そのために-i (--ignore-install)オプションを付けて/etc/modprobe.confのinstall行を無視するようにする。(-iオプションなしで起動してみたが、無限ループに落ち込むことはなかった。多分、呼び出した自分自身の行くらいは無視する気の利いた機能はあるのだろう....。)