OpenWrtでv6プラス (MAP-E) での IPv6 / IPv4 接続と、IPv4 PPPoEでのサーバー公開を両立する

(追記)この方法は完全ではないです

後日、以下の方法では特定のサイトが見ることができなくなったり、表示が遅くなったりする問題が起こることが分かった。この問題はまだ解決できていない。本記事の内容を試す前に、追記記事を読むことを強く勧める。(そして、発生する現象の解決を試みるのも良いかもしれない。)

(未解決)OpenWrtでv6プラス (MAP-E) 接続すると、一部のサイトに接続できなくなった。


概要

IPv6 の普及が進みつつあり、IPv6 での接続オプションを提供するプロパイダも増えている。日本国内においては、光接続において一般的に使われてきた IPv4 PPPoE 接続においてはフレッツ網終端装置での混雑によって速度が低下することが指摘されているが、IPv6 接続ではこの混雑を回避することができ、通信速度が向上するという利点もある 1

今回、自宅のインターネット接続を IPv6 化を試み、OpenWrtを導入したルータで IPv6 接続できたので、本記事ではその方法を記録する。IPv6 で接続した際に、 IPv4 の通信をどのように通す(IPv4 over IPv6)かは大きな問題で、様々な方式があり、プロバイダによって提供する方式が異なる。今回は、MAP-E、あるいは日本において v6 プラスと呼ばれる方式で接続した。

MAP-E では、利用可能なポートが大きく制限されるため、いわゆるポート開放が必要なことを行うのは難しく、基本的にサーバーの公開はできない 2。そこで、IPv4 PPPoE の接続も維持し、サーバーはこの経路で通信させることで、サーバーの公開も行えるようにした。

図 1 に本記事で構築するネットワークの概念図を示す。ルータは IPv6 アドレスと、MAP-Eで割り振られる IPv4 アドレスを持ち、これに加え従来から存在する IPv4 PPPoE 接続の IPv4 アドレスを持つ。LAN内のクライアントは、IPv6 接続で外部に接続できるし、IPv4 接続も、IPv6 トンネル上を通過する。これによりフレッツ網終端装置での混雑を回避する。一方、サーバーは従来の IPv4 PPPoE 接続を通して外部と通信する。

ISP
ISP
網終端装置
網終端装置
VNE
VNE
IPv4
インターネット
<div>IPv4</div><div>インターネット</div>
IPv6
インターネット
<div>IPv6</div><div>インターネット</div>
NGN網
NGN網
IPv6
[Not supported by viewer]
IPv4
[Not supported by viewer]
wan: IPv4 PPPoE
203.0.113.1
[Not supported by viewer]
map-wan6_map: IPv4 (MAP-E)
198.51.100.1
[Not supported by viewer]
wan6: IPv6
2001:0db:dead:beef::cafe/64
[Not supported by viewer]
クライアント
192.168.A.0/24
2001:0db:dead:beef::/64
[Not supported by viewer]
サーバー
192.168.X.Y
[Not supported by viewer]
OpenWrt
OpenWrt
図 1. ネットワーク概念図。各アドレスは架空のものだ。

環境

以下の環境で行った。

  • ISP: So-net (v6プラス オプションを契約済み)
  • ルータ: Buffalo WSR-1166DHP2 (OpenWrt 18.06.5)
  • すでに IPv4 PPPoE での接続は確立している
  • すでに PPPoE でサーバーを公開するためのNATは設定している。

MAP-E で接続するためには、(当然ながら)v6 プラスの接続オプションを申し込んでおかなければならない。So-net では無料でこのオプションを追加することができる。現時点ではこのページから申し込みできる: So-net 光 プラスの次世代通信 v6プラス | So-net (ソネット)。僕は以前に v6 プラスではない IPoE サービス( IPv4 には接続できない)を申し込んでいたため、一度解約して申し込む必要があった3。申し込みから 2 日目ほどで利用開始の連絡がきた。

WSR-1166DHP2 は本来 MAP-E には対応していないが、ファームウェアを OpenWrt に書き換えることで MAP-E 接続が可能になる。OpenWrt のインストールの詳細は割愛するが、全体的な流れは WSR-1166DHP2にLEDE 17.01.4をインストールしたメモ – OpenWrt memoを参考に、イメージはOpenWrt Project: Buffalo WSR-1166DHPopenwrt-18.06.5-ramips-mt7621-wsr-1166-squashfs-sysupgrade.bin を使ってインストールできた。僕の環境では sysupgrade 前に mtd erase firmware しなければ上手く書き換えられなかった。

このルータは既に製造終了しているが、筐体を開けずに OpenWrt化できるし、有線 LAN は LAN 側 WAN 側 ともに 1Gbps 対応しているし、無線も 802.11ac 対応しているし良いものだと思う。後継の WSR-1166DHP3WSR-1166DHP4 もあるが、CPUが違うため、OpenWrt化は難しいかもしれない 4

設定

設定は 56 を参考にしながら、以下のように行った。

IPv6の設定

まず、単純な IPv6 IPoE での接続から設定する。6 では luci-proto-ipv6ip6tables のインストールが必要と書いているが、すでに入っていたのでそのまま設定を行ったような記憶がある。また、wan6インターフェースもすでに存在したので、新規に追加せず、細かい設定のみで済ませたように思う。Cover the following interfaceは、本環境では eth1 ではなく eth0.2 に読み替えた。(WSR-1166DHP2 は、NIC は LAN 側 WAN 側共通で、VLAN で分離されている)

インターフェースの読み替え以外は基本的に 6 にある通りに行えば良いはずなので、そのまま引用する。

以下の手順で DHCPv6 クライアントの設定をする。

1. OpenWrt の Web UI にログインする。  
2. [Network] – [Interfaces]  
3. [Add new interfane…] をクリックする。  
  - Name of the new interface: wan6
  - Protocol of the new interface: DHCPv6 client
  - Create a bridge over multiple interfaces: チェックしない
  - Cover the following interfaces: Ethernet Adapter: “eth1”
  - [Interface Overview] から「WAN6」の [edit] をクリックする。
  - [Firewall Settings] で「wan:」を選び [Save] をクリックする。

RA や DHCPv6 を LAN 側にリレーするように設定する。再度 OpenWrt に ssh でログインし、設定ファイル

/etc/config/dhcp
を以下のように編集する。

  :
config dhcp 'lan'  
  :
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
  :
config dhcp 'wan6'  
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'
  :

変更を反映させる。

root@OpenWrt:~# uci commit /etc/config/dhcp

フレッツ光 + OpenWrt で IPv6 を使う : あかぎメモ

ここまで設定して、[Network] - [Interface]の画面で WAN6 の [Connect] ボタンを押すと IPv6 で接続される。MAP-E の設定に入る前に、IPv6 で正しく通信できていることを確認すると良いだろう。例えば、test-ipv6.com で確認すると、IPv4 と IPv6 共に IP アドレスが表示するのが確認できるはずだ。(ただし、この段階では、「IPv4またはIPv6のいずれかのトンネルメカニズムを使用しているようです。」という警告が出ている。)

MAP-Eの設定

IPv6 IPoEで接続できることを確認したのち、MAP-Eによる IPv4 接続を設定する。まずは、必要なモジュールをインストールする。

OpenWrtにSSHで接続して

# opkg update
# opkg install map

としても良いが、Web UIから [System - Software] を開き、[Update lists] した後、map パッケージを検索し、インストールすると楽だ。

インストール後、[Network - Interfaces] から [Add Interface] し、Protocol of the new interface: MAP / LW4over6 としたインターフェースを追加する。インターフェース名は任意だが wan6_map とした。追加後、以下のようにインターフェースの設定を編集する。

事前準備

設定に必要な情報を http://ipv4.web.fc2.com/map-e.html で計算しておく。「IPv6 プレフィックスかアドレスを入力」の欄に、ルータに割り当てられたIPを入力する。[Network - Interfaces] で、wan6インターフェースの欄に表示されているIPをそのままコピペすれば良い。

General Setup

  • Type: Map-E
  • BR / DMR / AFTR: 2404:9200:225:100::64 (固定値)
  • IPv4 prefix: 上記サイトで計算したipaddrの値
  • IPv4 prefix length: 同 ip4prefixlen
  • IPv6 prefix: 同 ip6prefix
  • IPv6 prefix length: 同 ip6prefixlen
  • EA-bits length: 同 ealen
  • PSID-bits length: 同 psidlen
  • PSID offset: 同 offset

Advanced Setup

  • Tunnel Link: wan6
  • (その他はデフォルト)

Firewall Settings

  • Create / Assign firewall-zone: wan

Legacy MAP 0 mode を有効にする

SSH で接続し、/lib/netifd/proto/map.sh を編集し、# export LEGACY=1 のコメントを外し export LEGACY=1 とする。

正直これは何をやっているのか分からない。ただ、これをやらないと実際繋がらなかった。

接続とトラブルシュート

ここまで設定したら、インターフェースの [Connect] をクリックする。インターフェースが接続されていないのようなエラーが出た場合、ルーターを再起動することで直ると思う。運が良ければ、これでMAP-E経由での接続が確立されるかもしれない。

ここで、僕の環境では "MAP rule is invalid" というエラーが出て接続できなかった 。この場合、以下の設定を追加で行えばよい7

インターフェースの一覧から、前の節で追加した IPv6 接続用インターフェース (wan6)の [Advanced Settings] を開き、Custom delegated IPv6-prefix に、ルータに割り当てられた IP アドレス(CIDR表記)を入力する。IPv6 の接続を確立した状態でインターフェース一覧を開くと IP アドレスが表示されているので、そのままコピペすれば良い。設定が終わったら、念のため [Reconnect] をクリックして再接続し、その後 wan6_map インターフェースも再接続すれば、無事にMAP-E での接続が確立される。

図2. 赤線で囲ったように、表示されたIPv6 アドレスをそのまま Custom delegated IPv6-prefix に設定する。設定値はIPv6-PDとして表示される。
図2. 赤線で囲ったように、表示されたIPv6 アドレスをそのまま Custom delegated IPv6-prefix に設定する。設定値はIPv6-PDとして表示される。

メトリックの設定

ここまでで、以下の3つの接続が確立されている。

  • IPv6
  • IPv4 PPPoE
  • IPv4 MAP-E

この段階では、経路の優先度を設定していないため、IPv4 では PPPoE 経由で通信する可能性がある。これを防ぎ、確実に MAP-E 経由で通信するようにメトリックを設定する。

[Network] - [Interface] から、WANインターフェースを開き、[Advanced Settings] 内の Use gateway metric に1以上の数字を設定する。一方で、WAN6_MAP インターフェースを開き、同じく Use gateway metric に 0 を設定する。メトリックは小さいほど優先されるため、以上の設定により、 IPv4 での通信が確実に MAP-E 接続を経由するようになる。

この状態で、例えば確認くんでリモートホスト名を確認すると、***.v4.enabler.ne.jp などと、Virtual Network Enabler (VNE) 事業者のもののようなホスト名になるはずだ。また、test-ipv6.com で確認すると、MAP-E を構成する前には表示されていた「IPv4またはIPv6のいずれかのトンネルメカニズムを使用しているようです。」という警告は消え、「管理されたトンネルメカニズム(6RD 8)を使用してIPv4経由でIPv6を転送しているようです。」と表示されるはずだ。

サーバー用のルーティング設定

MAP-E では、実質的にプロバイダ側でNATに近いことをしているようなもので、同じIPアドレスが複数の端末に割り振られ、実際の通信先はポート番号で識別される。このため、任意のポートで通信することは許されず、従って、TCP 80 や TCP 443 を使ってサーバーを公開することはできない 2

MAP-E と同時に従来の IPv4 PPPoE の接続も張っているため、サーバーに接続するためのアドレスとして PPPoE 接続側のものを公開しておけば良いように思われるが、実際にTCP80/443 で HTTP(S) サーバーを立てたところ、外部から接続できなかった。詳しく検証していないので推測になるが、要求は IPv4 PPPoE を通してサーバーに到達するも、応答は MAP-E を経由し、送信元ポートが公開可能ポート外となってしまったパケットがプロバイダや VNE 側で弾かれたのではないかと考えている。

そこで、サーバーからの通信はすべて(外部からの接続ではなく、純粋にサーバーが始めた通信だとしても)、PPPoE を通すことにする。すなわち、送信元をサーバーとする通信については、PPPoE 側のインターフェースをデフォルトゲートウェイとすることにする。

Web UIどころか、uciですらうまく設定できなかったので、泣く泣く /etc/hotplug.d/iface/30-nas-routing に以下のスクリプトを追加した。

#!/bin/sh

if [ "$ACTION" = 'ifup' ] && [ "$DEVICE" = 'pppoe-wan' ]; then  
    modified=0
    if ! ip rule list | grep 'from 192.168.X.Y lookup pppoe'; then
        ip rule add from 192.168.X.Y table pppoe;
        modified=1;
    fi
    if ! ip route list table pppoe | grep "default dev ${DEVICE}"; then
        ip route add default dev ${DEVICE} table pppoe;
        modified=1;
    fi

    if [ $modified -eq 1 ]; then
        ip route flush cache;
    fi
fi

192.168.X.Y はサーバーの IP アドレスだ。$DEVICEの値は IPv4 PPPoE 側のインターフェース名に適宜置き換えてほしい。

/etc/hotplug.d/ 以下のスクリプトは、ネットワークの接続状態が変化したときに、変化した状態を表す適切な変数が設定された状態で実行される 9。上記のスクリプトは、IPv4 PPPoE 経由のインターフェースが接続されたときに、192.168.X.Y を送信元とした通信のデフォルトゲートウェイを pppoe-wan インターフェースのものとするルーティングを追加するものだ。if 文は、すでに設定がある場合に重複した設定を追加されることを防ぐものだ。

ここまでの設定を行うことで、MAP-E を介したインターネットへの接続と、サーバーを従来の IPv4 PPPoE を通して公開することができるようになった。

おわりに

本記事では、OpenWrt で IPv6 IPoE 接続と、その上で MAP-E (または v6 プラス)を使った IPv4 通信のトンネリングを行う方法を説明し、またサーバーを外部公開するために、特定の送信元からの通信を IPv4 PPPoE にルーティングする方法を説明した。

さて肝心の速度だが、これまで、IPv4 PPPoE では下りが早いときで 30Mbps、遅いと 10Mbps ぐらいの速度しか出なかった(上りはもう少し速かったように思う)が、インターネット接続の IPv6 化を行ったことで、IPv6 接続、MAP-E での IPv4 接続ともに、また上下ともに 90Mbps 前後出るようになった。自宅までの回線の引き込みが LAN 配線方式のため 100Mbps が上限なので、ほぼ飽和しており悪くない数字だと思う。

OpenWrt での MAP-E 接続についてはあまり情報がなく、 5 の記事と 7 のツイートには助けられた。特に当該ツイートを見つけられなかったらどこが悪いのか分からず諦めていたと思う。感謝したい。

ほぼ手探りで書いた記事のため、認識や記述に間違い、あるいは改善できる点があるかもしれない。何か見つけた場合は、@mecab まで教えていただければ嬉しい。特に最後のルーティングの設定は、Web UI 上で、あるいはせめて uci 上で設定できる方法があれば良いなと思っている。

  1. https://www.janog.gr.jp/meeting/janog42/application/files/1015/3238/7198/janog42-IPoE-overview_toyama.pdf

  2. 「v6プラス」に移行すべきか? メリットとデメリット So-netの場合 | Solomonレビュー[redémarrage]

  3. IPoEのオプションを解除しない状態だと「お客様はこのオプションを申し込めません」のようなエラーになった。

  4. WSR-1166DHP2にOpenWrtを入れる方法: okoyaの私的メモ なお、WSR-1166DHP3 や WSR-1166DHP4 を OpenWrt 化した記事は見つけられなかった。

  5. OpenWRT で MAP-E によるインターネット - 満月紀行元ページはすでに削除されているためInternet Archiveの魚拓)

  6. フレッツ光 + OpenWrt で IPv6 を使う : あかぎメモ

  7. https://twitter.com/ryu2012/status/1143753845966692352

  8. 今回使っているのは 6rd でなく MAP-E なので、test-ipv6.net 上の表記は正確でないが、トンネルできていることには違いない。6rd (Wikipedia) も MAP-E と同じく IPv4 / IPv6 移行技術の一つ。ただし、IPv4 上で IPv6 のパケットを通すものだ。

  9. OpenWrt Project: Hotplug