IPv4機能の無効化はどこまでできる?
FreeBSD, Linux, Windows でIPv4無効化設定をやってみた。
散々ノウハウが流通しているIPv6の無効化ではなくて IPv4の無効化 。無効化にも
■プロコルスタック上での対処
- カーネルからIPv4プロトコルスタックの機能を排除して一切使わない
- IPv4プロトコルスタックは機能しているが、インターフェイスにIPv4アドレスを付与しない
- 有効なIPv4アドレスは付いているけどIPv6を優先して利用する。(デフォルトでそうなっているはずのRFC6724のアドレス選択ポリシ)
■アプリケーション(DNSリゾルバ)の対処
- アプリ/リゾルバにA RRをクエリさせない
■DNSキャッシュサーバの対処
- (AAAAフィルタでなくて) Aフィルタ[1]する
など、いろいろあるが、どのぐらいできそうか試してみた。
FreeBSD 11.0-RELEASE
カーネルからIPv4プロトコルスタックを完全削除可能
Qiita掲載の記事 "FreeBSDのsrc.conf"から src.conf(5)
をみて、ソースからのFreeBSD再構築時に指定できるオプションに、 WITHOUT_INET_SUPPORT
があることに気づいた。
/etc/src.conf```
WITHOUT_INET_SUPPORT=yes
を書き加え、かつカーネルコンフィグ (`/usr/src/sys/amd64/conf/GENERIC`) から `options INET` を
options SCHED_ULE # ULE scheduler
options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
options IPSEC # IP (v4/v6) security
options TCP_OFFLOAD # TCP offload
options SCTP # Stream Control Transmission Protocol
.
.
コメントアウトしてカーネルを再構築する。
cd /usr/src/sys/amd64/conf
config GENERIC
cd ../compile/GENERIC
make cleandepend
make depend
make
make install
作り直したカーネルで再起動すると、lo0インターフェイスから127.0.0.1が消え、socket(AF_INET,...) システムコールを呼んでも、errno = EPROTONOSUPPORT が返ってくる。IPv4スタックがカーネルからきれいに消えてくれて気持ちよい。
ちなみに、デフォルトで起動する sendmail_submit が標準設定だとローカルホスト(127.0.0.1)を指すので、
Starting sendmail_submit.
554 5.3.0 host "localhost" unknown: Address family not supported by protocol family
を吐いて立ち上がらなかったが、 `/etc/mail/freebsd.submit.mc` を見ると
dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:::1]
FEATURE(msp',
[127.0.0.1]')dnl
と書いてあり、IPv6 onlyで使うことも考慮はされていた。
## ipfw が使えなくなる (2017.1.12追記)
IPv4のコードに強く依存しているようで、ipfwが利用不可となる。フィルタリングの他、ユーザランド動くpppd, natdなどのためのdivert, altq, dummynet などが影響を受ける。代替手段としてはpfは使える様子。
# Ubuntu 16.04 LTS (Linuxカーネル3.3.0)
カーネルからIPv4機能を削除できなかった。
カーネルコンフィグの依存関係は
TCP/IP Networking [*]
--> The IPv6 protocol <*>
の従属の関係になっていて、TCP/IP Networking (=IPv4)を丸ごと外すことができるが、IPv6も外れてしまう。IPv6を活かしつつ、IPv4だけを消し去ることは簡単ではないようだ。
ちなみにIPv6の無効化は```
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
とか、RHEL/CentOS系ならipv6モジュールロードの無効化、grubオプションでの無効化などいろいろ方法があるのだが、どれもそれに相当するIPv4無効化設定が見当たらない。
カーネルからIPv4スタックの機能を排除できなかったが、ループバックアドレス以外のIPv4アドレスは付与しないことでIPv4無効化相当の効果は得られるし、デフォルト動作でIPv6が優先されるのでおそらく問題は出ないと思う。ループバックインターフェイス inet 127.0.0.1/8 の付与が残ってしまったり、ping 127.0.0.1 は機能してしまう点など残骸を気持ち悪いと感じかもしれないが (ループバックアドレスは ip addr del 127.0.0.1/8 dev lo
で消すのもあり)。
Windows 10
C:\>netsh interface ipv4 uninstall
管理者権限でuninstallして再起動するとIPv4スタックが機能しなくなった。Loopback Pseude-Interface-1 の 127.0.0.1 も機能してないし、ipconfig の出力からもIPv4アドレスに関する情報が全て消えてくれる。
C:\>ping 127.0.0.1
IP ドライバーにアクセスできません。一般エラーです。
C:\>ping ::1
::1 に ping を送信しています 32 バイトのデータ:
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms
.
.
と期待した動作となる。
一方、ネットワークアダプタのプロパティを開いて、アダプタにバインドしたプロトコルの
- インターネット プロトコル バージョン4 (TCP/IPv4)
- インターネット プロトコル バージョン6 (TCP/IPv6)
IPv4のチェックを設定を外す方法だけでは、そのアダプタにIPv4アドレスがつかなくなって、ipconfigの出力からもIPv4アドレスが消えてくれる。実効上無効化できたことと等しいが、Loopback Pseude-Interface (127.0.0.1) は生き続けて通信はできるので、プロトコルスタックとしての機能は生き続けたままである。127.0.0.1 は
netsh interface ipv4 delete address interface="Loopback*" address=127.0.0.1
でアドレスを消すことはできる。
おしまいに
ほとんどの場合IPv6が優先されるので、古い実装(IPv4)があっても有害となることは無いと思う。。なのでIPv4が廃れても、当分の間は実装されたまま放置の気がする。そのうち
-
やっぱり古い実装(IPv4)は有害だ!と言う場面が現れ、"IPv4 無効化" ワードが検索が流行り始めたり
-
害はなくても
127.0.0.1
を見て「なんだこの変な数字は?!」とIPアドレスと認識できない世代が現れる一方、年寄りが「このアドレスなつかし~」と言い出したり。
そんな時代が来ればいいと思う。
参考資料
[1] [WIDEプロジェクト, Live with IPv6 Working Group 2012 年度活動報告]
(http://member.wide.ad.jp/tr/wide-tr-live-with-ipv6-wg-report-2012-01.pdf)