IPv4のみのネットワークを勝手にIPv6対応にする実験


この内容を自分の管理していないネットワークで行うのはやめましょう

概要

IPv6の勉強中、IPv4からの移行期のための技術として、Teredoというものがあることを知った。
IPv6パケットをUDP/IPv4パケットでカプセル化してトンネルを作ることで、間にIPv4のみのネットワークが挟まっていてもIPv6でのインターネット接続を可能にするらしい。

もしかして、IPv4でのみインターネット接続できる環境下で、Teredo接続している端末が、自分がIPv6ゲートウェイであるとRAを流してIPv6パケットを転送すれば、そのネットワークに繋がっている他の端末もIPv6でインターネット接続できるのでは?

ものは試しにやってみた。

手順

環境

+------------+
|the Internet|
+------+-----+
       | ※インターネット接続はIPv4のみ
+------+-----+
|   IPv4 GW  |
+------+-----+
       |
       +---------------+
       |               |
+------+-----+  +------+-----+
|   Host A   |  |   Host B   |
+------------+  +------------+

  • Host A:
    • 本記事の主役(いわゆる野良RA)
    • teredoクライアント
    • 勝手にRAをネットワーク内に送信
    • OSはUbuntu Server 18.04.2 (今回はLXDで作成)
  • Host B:
    • 動作テスト用端末
    • Ubuntu ServerとWindows 10を用意
    • IPv4/IPv6デュアルスタック
  • IPv4 GW:
    • IPv4のみに対応したルータ(今回の環境ではRTX810を使ったが、IPv6関連機能はOffにしている)

Host Aは念の為特権コンテナとして作成した。

lxc launch images:ubuntu/18.04 TEREDO -c security.privileged=true

ネットワーク設定

netplanで設定ファイルを下記のように設定。
IPv6アドレスだけ固定する。再起動時にmiredoが起動に失敗するので、IPv4アドレスも固定。

/etc/netplan/99_config.yaml
network:
    ethernets:
        eth0:
            dhcp4: false
            dhcp6: true
            addresses:
            - 192.168.100.254/24
            - fc01:0:0:2::1/64
            gateway4: 192.168.100.1
            nameservers:
                addresses:
                    - 8.8.8.8
    version: 2

設定を反映する。

netplan apply

次にパケット転送を有効にしておく。

/etc/sysctl.conf(追記/コメントアウト)
net.ipv6.conf.all.forwarding = 1
sysctl -p

radvdのインストール

まずradvdの設定ファイルを作成。

/etc/radvd.conf
interface eth0 {
  AdvSendAdvert on;
  MinRtrAdvInterval 3;
  MaxRtrAdvInterval 10;
  AdvOtherConfigFlag on;

  prefix fc01:0:0:2::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;
  };
};

radvdをインストールし、自動起動するように設定。

apt install radvd
systemctl enable radvd

isc-dhcp-serverの設定

IPv6でDNSサーバを通知する方法は、RAに含めるRDNSSと、DHCPv6に含める方法の2つがあるが、今回はDHCPv6を採用。
(AndroidはDHCPv6に非対応で、RDNSSを使うらしい)

isc-dhcp-serverをインストールし、IPv4側のDHCPサービスを無効化。

apt install isc-dhcp-server

systemctl stop isc-dhcp-server
systemctl disable isc-dhcp-server

設定ファイルのうち、isc-dhcp-serverの下記部分をコメントアウト/記入。

/etc/default/isc-dhcp-server
DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf
DHCPDv6_PID=/var/run/dhcpd6.pid
INTERFACESv6="eth0"

DHCPv6用設定ファイルのdhcpd6.confに下記を追加。
以下で通知しているのはGoogle Public DNSのIPv6アドレス。

/etc/dhcp/dhcpd6.conf
subnet6 fc01:0:0:2::/64
{
  option dhcp6.name-servers 2001:4860:4860::8888;
}

DHCPv6サーバを起動する。

systemctl enable isc-dhcp-server6
systemctl start isc-dhcp-server6

teredoクライアントのインストール

Ubuntuではteredoクライアントのパッケージ名はmiredo。

apt install miredo

インストール後、ip ateredoというネットワークデバイスが追加されていることを確認。

iptablesの設定

まずはiptablesをインストール。

apt install iptables

eth0に入ってきたIPv6パケットをNAPTをかけてteredoに転送するよう設定。

ip6tables -A FORWARD -i eth0 -o teredo -j ACCEPT
ip6tables -A FORWARD -i teredo -o eth0 -j ACCEPT
ip6tables -t nat -A POSTROUTING -s fc01:0:0:2::/64 -o teredo -j MASQUERADE

永続化のため、iptables-persistentをインストール。
インストール中に、「現在のIPv6設定を保存するか?」という問いが出るので、Yesと回答。

apt install iptables-persistent

確認

同じネットワークにいる別のマシン(Host B)から、IPv6でインターネット接続できることを確認。

$ ping6 www.google.com
PING www.google.com(nrt20s01-in-x04.1e100.net (2404:6800:4004:806::2004)) 56 data bytes
64 bytes from nrt20s01-in-x04.1e100.net (2404:6800:4004:806::2004): icmp_seq=1 ttl=57 time=508 ms
64 bytes from nrt20s01-in-x04.1e100.net (2404:6800:4004:806::2004): icmp_seq=2 ttl=57 time=9.43 ms
64 bytes from nrt20s01-in-x04.1e100.net (2404:6800:4004:806::2004): icmp_seq=3 ttl=57 time=12.2 ms
64 bytes from nrt20s01-in-x04.1e100.net (2404:6800:4004:806::2004): icmp_seq=4 ttl=57 time=5.38 ms

1回目は時間がかかるが、その後はそれなりの時間でPINGが返ってきた。

次にWindowsマシンでも確認。
ブラウザでIPv6対応サイトを正常に閲覧できることを確認できた。

IPv4とIPv6を両方有効にした場合、ipv6-test.comの表示は下図。
(2001::/32というTeredoのIPv6アドレスが表示されている)

IPv6のみを有効にした場合は下図となった。このときはちゃんとKAME Projectの亀も踊っていた。

ちなみにSpeed testで測ってみたら、IPv4が80 Mbps程度に対し、IPv6は1 Mbpsしか出なかった。

とはいえ、実験は大成功!
めでたくIPv4のみのネットワークを、IPv6でインターネット接続できるネットワークにできた。

セキュリティについて

さて、上記の実験で、IPv4ネットワーク内で勝手にIPv6ゲートウェイを作れてしまうことがわかった。
ということは、同じネットワークにIPv6対応端末がいた場合、それらのIPv6通信を全部横取りして盗聴できてしまう。

これは非常にまずい。

私が思いつく対策としては、HTTPSなどエンドツーエンドの暗号化以外には

  • 各端末のIPv6機能を無効化する または 手動設定のみにする
    • iPhoneやAndroidでは難しい
  • IPv4のルータで、外向きのUDP3544(teredoサーバの待受ポート)をブロックする
    • すべてのteredo通信ができなくなるので、正当なteredoの利用もできなくなる
  • 無線LANなら、クライアント間の通信を遮断する

ぐらいしかないのだが、やはり不正RAのセキュリティ問題はすでに懸念されているようで、次のような資料が見つかった。

IPv4における野良DHCPサーバのときと同様、不正RAにもいくつか対策はあるようだが、普及しているものが少ないのが現状な模様。

IPv4ではDHCPリクエストがあって初めて野良DHCPサーバが通信に介入できるのに対し、
IPv6の場合はいつでも誰でもRAを送信でき、影響範囲が大きくなるのが痛い。