OpenWrtベースのGL.iNet GL-BE3600でMAP-E(v6プラス)を正しく構成する (2026年3月版)
OpenWrt 23.05ベースのGL.iNet BE3600でドコモ光 + v6プラスで正しく構成する方法を2026年3月時点でまとめました。現在はIPv4/IPv6ともに安定して運用できています。 ついでに、Tailscale連携のカスタマイズ方法にも触れます。
MAP-E (v6プラス)について
筆者の環境におけるv6プラスは以下を差します。
- NTT東日本が提供するコラボ光 (フレッツ光クロスによる10G)
- ドコモ光 + GMOとくとくBB
- IPv6の足回りはJPIXのものを使う(240b::/26)
- とくとくBBでv6プラスを申し込み
- これはJPIXが提供しているMAP-E設備を使う追加契約。申し込まないとプロビジョニングされない。契約方法によってはデフォルトでプロビジョニングされていない場合があるので注意が必要。
v6プラスにおけるMAP-Eについて
設定値を生成するサイトとして https://ipv4.web.fc2.com/map-e.html が有名ですが、このサイトの動作原理をMAP-Eの仕様に沿って解説します。
まず重要な点として、v6プラスのMAP-Eはドラフト版に基づいている点です。 OpenWrtでは Legacy として設定する必要があります。
上のサイトが動くのは、JPIXが提供するMAP-EのDefault Mapping RuleとBorder Routerのアドレスを持ち合わせているからです。 通常はおそらくベンダーにしか公開されていない情報ですが、 MAP-EのBasic Mapping Ruleを理解していれば、市販ルーターの動作から推測することは十分に可能です。
例えば、
- 構成されているIPv6アドレスとIPv4アドレスを確認する
- BRのアドレスとMAP-EのCEアドレスはトンネルトラフィックを見れば特定できる
- CEアドレスを見れば、IPv4アドレスを元に、PSIDが特定できる
- PSIDの長さが推定できる
- PSIDの長さは全ポートに対して実際に通信を試みればoffset含めて特定できるはず(ポートセットに含まれていなければ流れてこないので、流れてきたポートから特定できる)
- PSIDの長さがわかれば、DHCPv6-PDで得られたprefixから、IPv4アドレスのsuffixとPSIDを元にEA bitsを推定できる
- Rule IPv6 prefixが推定できる
- CEを動作させるだけなら、BRのアドレスとCEのアドレスから得られるIPv4アドレス、PSID、PSID長でトンネルとNAPTは構成できるはず
v6プラスにおけるBasic Mapping Rule
https://datatracker.ietf.org/doc/html/draft-ietf-softwire-map-00#section-5.2
設定値生成サイトの情報を整理すると以下になります。
- Rule IPv6 Prefix:
240b:10::/31(n = 31 bits) - End-user IPv6 prefix len: /56 (DHCPv6-PD)
- つまり、 56 - 31 = 25 bitsの中に必要な情報を埋め込む = EA bits = o = 25 bits
- IPv4アドレス32bitsより小さいので、EA bitsには完全なIPv4アドレスは含まれないことがわかる。したがって、BMRで事前にRule IPv4 prefixが与えられなければいけない。
- つまり、 56 - 31 = 25 bitsの中に必要な情報を埋め込む = EA bits = o = 25 bits
- EA bits (Embedded Address Bits)
- Rule IPv4 Prefix:
106.72.0.0/15(106.72.0.0 - 106.73.255.255)- IPv4アドレス 32bitsのうち、15bitsはBMPで与えられるので、EA bitsでは残りの17bitsとポートセットIDを表現する必要がある。
- r bits = 15 bits
- p bits = 17 bits
- q bits = 25 - 17 = 8 bits (Sharing Ration R = 256)
- ポートセットは2**8 = 256組。1つのIPv4アドレスを256加入者で共有している。
- IPv4 prefix全体では (2 ** 17) * (2**8)= 33,554,432 加入者(おおよそ3300万加入者)を収容できる
- UDP/TCPの最大ポート数は16bitsなので (2**16)/256組 = 1加入者あたり256ポートだが、<4096ポートは使用しないので実際は (65,536 - 4096) / 256 = 1加入者あたり240ポート使える
- 通信は送信元と送信先の組み合わせ(アドレスとポート番号+プロトコルの5タプル)なので、同じ宛先に対して大量にポート番号を使う場合には問題になりうるが、実用上はそこまで困ることはない(NAPTの実装に依るけど…Full Coneだと心許ないかもしれん。OpenWrt(Linux)だとSymmetric的動作になる。)
- Rule IPv4 Prefix:
- Border Router:
2404:9200:225:100::64
なお、設計上はマップルール配信サーバーが存在しているため、パラメーターが更新された場合は市販ルーター等の動作から再度推測する必要があります。
MAP-EにおけるMAP IPv6アドレスの構成について
BRのアドレスがわかったところで、実際にトンネルを構成する時の外側のアドレスはどのように構成されるのでしょうか。
まず、MAP subnet-idとして最初のサブネット(すべて0)を予約しなければならないとしています。
The MAP IPv6 address is created by concatenating the End-user IPv6 prefix with the MAP subnet-id and the interface-id as specified in Section 6. The MAP subnet ID is defined to be the first subnet (all bits set to zero). A MAP node MUST reserve the first IPv6 prefix in a End-user IPv6 prefix for the purpose of MAP.
/64のサブネットをこの方法に従って構成します。残りはPrefixが64bitsの場合におけるIPv4-Embedded IPv6 Address Formatで表現します。
https://datatracker.ietf.org/doc/html/draft-ietf-softwire-map-00#section-6
+--+---+---+---+---+---+---+---+---+
|PL| 8 16 24 32 40 48 56 |
+--+---+---+---+---+---+---+---+---+
|64| u | IPv4 address | PSID | 0 |
+--+---+---+---+---+---+---+---+---+
PSIDがsuffixに相当します。つまり、BRはIPv4アドレス (106.72.x.x) + PSIDで構成されるIPv6アドレスにトンネルトラフィックを投げる動作になります。
全体的にMAP-Eの仕様は既存のアセットをうまく組合せている点でよくできていると思います。
OpenWrtでのMAP-E (v6プラス)実装について
さて、OpenWrtでの実装はどうでしょうか。
2026年3月地点では以下がまとまっています。
- https://qiita.com/site_u/items/c6a50aa6dea965b5a774
- https://github.com/site-u2023/map-e/tree/main
- https://zenn.dev/wistnki/articles/784d33e3c8a17c
OpenWrtでのインターフェース名について
設定はUCI論理デバイスに対して行ないます。OpenWrtはその設定に従ってネットワークを構成します。
- 物理デバイス名
- br-lan (LAN側)
- eth1
- eth0 (WAN側)
- br-lan (LAN側)
- UCI論理デバイス名
- wan
- MAP-E
- wan6
- DHCPv6 over eth0
- wan
- ファイアーウォールゾーン名
- wan
- lan
WAN側 (IPv6) インターフェースの構成
wan6 論理デバイス名に対して、DHCPv6-PDを構成します。
- Protocol: DHCPv6 client
- Device:
eth0
WAN側 (MAP-E) インターフェースの構成
wan 論理デバイス名に対して、MAP-E (Legacy)を構成します。
- Protocol: MAP / LWover6
- Type: MAP-E
- Tunnel Link:
wan6 - MAP-EはLegacy実装を使う (Use legacy MAP)
- MTUは1460に設定する (1280だとTailscaleなどのVPNが動かない)
- 各パラメーターは設定値Webサイトを参照
Tailscale連携のカスタマイズ
例えば、Tailscale SSHを有効にしたい場合は /usr/bin/gl_tailscale をカスタマイズする必要があります。
このスクリプトではTailscale起動時に --reset が指定されているため、 tailscale set の結果が永続化されません。直接ファイルを書き換える必要があります。
timeout 10 /usr/sbin/tailscale up --reset --accept-routes $param --timeout 3s --accept-dns=false --ssh > /dev/null