メインコンテンツまでスキップ

GL.iNet Flint 2 (OpenWrt 21) で MAP-E (Biglobe編)

· 約23分
BonyChops
@BonyChops

これまでのあらすじ

やめて!「ルータで細かい設定ができたら面白そう」とかいう浅はかな理由で OpenWRT に手を出したら無限に時間が溶けちゃう!

お願い、死なないで IPv4!

あんたが今ここで倒れたら、¥ 17,919- (税込) で買った Flint 21 はどうなっちゃうの?

時間はまだ残ってる。ここを耐えれば、ハッピーインターネットライフが待っているんだから!

次回「Bony 死す」デュエルスタンバイ! 2

はじめに

備考

こちらは長野高専 Advent Calendar 2025 - 20 日目の記事になります

この記事では、OpenWrt をベースとしたルータを取り扱う GL.iNet の Flint 2 で、MAP-E を確立させる方法と、それまでにあった経緯をまとめていこうと思います。

こういう記事であるあるの、「その根拠はなんなんだよ!!」 みたいな部分は限りなく潰していきたいと思っているので、footnote すらないものは是非コメントをください。

OpenWrt とは

OpenWrtは、ゲートウェイなどの組み込みシステム用ファームウェアとして開発されている Linux ディストリビューション3で他ファームウェアと比較してカスタマイズ性が非常に高いことが特徴として挙げられます。

基本的に既製品のルータには独自のファームウェアが導入されていることが多いので、OpenWrt を使いたい際にはどうにかこうにかねじ込む必要があるのですが、GL.iNet 製のルータは OpenWrt をベースに開発されているので、前述による文鎮リスクなどがないところが良いですね。

日本のインターネットと IPv6 4

警告

基本的には徹底解説 v6 プラスの引用ですが、誤った解釈をしている可能性があります。
詳しくは引用元である徹底解説 v6 プラス – 技術書出版と販売のラムダノートをご確認ください。
PDF 版は無料なので誰でも見れます!

備考

ここで記載する NAT は全て NAPT を含むものをしてください

インターネットの接続方式は国や地域ごとに大きく異なります。 多くの国では、家庭用ルータを用意して LAN ケーブルを挿すだけで、DHCP によりすぐに IPv4/IPv6 の通信が始まります。
ほぼすべての家庭回線が “そのまま IPv4 を使える前提” で設計されているため、接続方式の違いを意識する必要はほとんどありません。

日本は他国と異なり、大抵の場合インターネットに出る手前でフレッツ網という閉域ネットワークを経由します。この網からインターネットに出る方法として、PPPoE と IPoE の二種類から選べる様になっています。技術的な詳しい違いは徹底解説 v6 プラス – 技術書出版と販売のラムダノートの 3.2 節を見て欲しいのですが、PPPoE は ISP が設置する網終端装置(BNG)を必ず経由し、これがアクセス集中で輻輳しやすいと言われているのに対し、IPoE は PPPoE のようなセッション終端装置を通らず、VNE の大規模なルータへ直接届けられます。この構造により、PPPoE より混雑の影響を受けにくく、通信が安定しやすいとされています。そのため、拙宅では IPoE を利用することにしました。

ただし、IPoE の場合仕様上そのままでは IPv4 に接続できません。IPoE を用いて v4 を扱う場合、日本では、MAP-EDS-Liteのいずれかの IPv4 over IPv6 技術を使用するのが主流です。ルータがこの事情を知らない限り、LAN ケーブルを挿しただけでは v4 ネットワークに接続できないのです。 日本で主流のルータのラインナップに限りがあると感じるのはこれが原因で、ルーター側がこの日本の特殊な事情を把握している必要があります

ただし、逆を返せば、ルータがこの事情を知っていれば接続ができます。まさに、OpenWrt の様なカスタマイズ性の高いルータを用意して、上記の様な事情を叩き込んであげれば、たとえ上記の様なルールセットが教えられていないモデルでも使うことができます。今回 GL.iNet の Flint 2 を買った理由として

  • ハイパフォーマンス
  • コスパ良い
  • OpenWrt ベース
    • そもそも細かい設定ができるルータが欲しかった

が理由にあがります。まさにこの事情にピッタリですね。

Biglobe について

MAP-E での BR アドレス(接続先)を決める上で、この回線はどの VNE であるかを意識することは極めて重要です。
拙宅で使用している Biglobe について調べてみると「Biglobe は VNE 事業者である5」とされています。 徹底解説 v6 プラス – 技術書出版と販売のラムダノートでは、VNE 事業者は 3 社であるとされ、そこには Biglobe は載っていないことから矛盾している気がするのですが、「Biglobe は VNE 事業者であり BR アドレスが存在する」という前提で設定するとうまくいくため、本記事では一旦そういうことにしてあります。

設定

では設定に入っていきます。これを確立させるために、実に4 週間ぐらいかかりました 😅
奮闘記は下記にまとめてあります。何かしらでうまくいかない場合は、以下ももしかしたら参考になるかもしれません。

GL.iNet Flint 2 (OpenWrt 21) で Biglobe の IPv6 オプションに対応させる

項目仕様
ルータGL.iNet Flint 2
ファームウェアv4.8.3
回線Biglobe 1Gプラン
備考

下記は Biglobe 光回線で検証しています

GL.iNet の管理パネル

徹底解説 V6 プラス4には

光電話の契約がない場合、フレッツ網から RA が提供される/64 のセグメントにおいて、ルータは IPv6 パススルーを行います。
p86

とありますので、その様に設定します。

  • ネットワーク -> IPv6
    • モード: Passthrough
    • DNS 取得方法: 自動
GL.iNet v4.8.2, v4.8.3 あたりを使用している場合、または下記を全てやってうまくいかない場合
  • ネットワーク → ネットワークアクセラレーションを無効

詳しいことは#Network Acceleration を有効にすると NAT を介さないパケットが漏れ出る に書いてあります。

WAN6 の修正

以降は LuCI での設定になります。
システム -> 詳細設定 -> LuCI へ移動する (インストールが済んでいない場合はする)

  • Network -> Interfaces を開き、WAN6 を Edit, device を正しい物理インタフェース(eth1 など)にする

この時点でうまく行っている場合は IPv6 接続ができる様になっているはずです(google.comなどにアクセスして確認してください)。

注記

System -> Administration -> SSH-keys で公開鍵を設定しておくと便利です

MAP-E に必要なパッケージのインストール

sshで実行
opkg update --no-check-certificate
opkg install map ca-certificates --no-check-certificate
/etc/init.d/network restart
備考

特に、最後の /etc/init.d/network restart を実行しないと LuCI (Web インタフェース)上の Protocol に MAP / LW4over6 が出現しません。

うまくいかない場合は map インストール後にルータを再起動してください。

という指示が散見されるのはこれが理由です。

IPv4, IPv6 を控える

IPv6 が接続されている場合、WAN6 インタフェースにこの様な IPv6 アドレスが表示されていると思います

https://ipv4.web.fc2.com/map-e.html

↑ 上記サイトで諸々の値(IPv4 など)を控えておいてください。

IPv6 PD 設定6

備考

ここからの設定は構成ファイルでも可能です。GUI での操作が嫌いな人は #ここまでの構成ファイル まで読み飛ばしてください

このインタフェースが必要な理由

Flint 2 は 64 bit アーキテクチャで動作しています。MAP-E で使用されるアドレス計算用のモジュール mapcalc には、64bit アーキテクチャ環境でのみ発生するバグがある7ことがわかっているため、

WAN6 の Custom delegated IPv6-prefix を設定する

等の設定ではうまくいきません。OpenWrt 21 の場合、WAN6PD に偽のインタフェースを設けることでこの問題を回避できます。

警告

OpenWrt 21 以外では現状うまくいきません。

Add new interface...から

  • Name: WAN6PD
  • Protocol: Static Address
  • デバイス: eth1

で作成。

この時、WAN6 に表示されている IPv6 が
wwww:xxxx:yyyy:zzzz:aaaa:bbbb:cccc:dddd/64
であれば、

  • ネットワーク部(最上位 64 bit):wwww:xxxx:yyyy:zzzz
  • インターフェース ID(下位 64 bit):aaaa:bbbb:cccc:dddd

という構造になっています。
このネットワーク部を用いて下記の様に設定してください。

  • IPv6 address: wwww:xxxx:yyyy:zzzz::1001
  • IPv6 gateway: wwww:xxxx:yyyy:zzzz::1
  • IPv6 routed prefix: wwww:xxxx:yyyy:zzzz::/56

MAP-E 接続設定6

警告

GL.iNet 製のルータでは、IPv4 のステータスを WAN インタフェースから取得するため、WAN6_mape のような新規インタフェースを作成するとそれを認識できません
そのため、ここでは WAN インタフェースを直接編集するやり方を紹介します。

WAN インタフェースの Edit から、

  • Protocol: MAP/LW4over6
  • Really switch protocol?: Switch protocol
  • Type: MAP-E

あとは #IPv4, IPv6 を控える で控えた各設定をそのまま設定します。

  • General Settings
    • BR: peeraddr
    • IPv4 prefix: ipaddr
    • IPv4 prefix len: ip4prefixlen
    • EA bit len: ealen
    • PSID len: psidlen
    • PSID offset: offset
  • Advanced Settings
    • Use MTU on tunnel interface: 適切なMTUを設定 (Biglobeの場合は1460)
    • Use legacy map8: ✅
BR アドレス(peeraddr)について

前述の通り、BR アドレス値は VNE 事業者のアドレスになります。各ブログで、

という両者の意見を見かけるのですが、https://ipv4.web.fc2.com/map-e.html の実装(JS)を確認する限り、なんらかの指標でこの値を算出してくれているっぽいのでそのまま使って良い気がします。
拙宅の Biglobe の場合は算出されたものをそのまま使って大丈夫でした。

ここまでの構成ファイル

これまでの設定は全て下記のファイルの編集・追記でも設定できます。

備考

関係ない部分は省略しています

/etc/config/network
config interface 'wan'
option classlessroute '0'
option ipv6 '1'
option proto 'map'
option maptype 'map-e'
# ---ここから要変更---
option peeraddr 'xxx'
option ipaddr 'xxx'
option ip4prefixlen 'xx'
option ip6prefix 'xxx'
option ip6prefixlen 'xx'
option ealen 'xx'
option psidlen 'x'
option offset 'x'
option mtu 'xxxx'
option legacymap '1'
# ---ここまで要変更---

config interface 'wan6'
option proto 'dhcpv6'
option disabled '0'
option reqaddress 'try'
option reqprefix 'auto'
option device 'eth1'

config interface 'wan6pd'
option proto 'static'
# ---ここから要変更---
list ip6addr 'xxx'
option ip6gw 'xxx'
option ip6prefix 'xxx'
# ---ここまで要変更---
option defaultroute '0'
option device 'eth1'
/etc/config/firewall
config zone
option name 'wan'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
option input 'DROP'
list network 'wan'
list network 'wan6'
list network 'wwan'
list network 'secondwan'
list network 'wan6pd'

上記で設定した場合は下記を実行する

/etc/init.d/network restart
/etc/init.d/firewall restart

ニチバン対策

下記スクリプトでニチバン対策ができます。
他サイトを諸々参考[]にして作りましたが、最終的には自分(ChatGPT)が作っております。

以下に作る際で沼ったポイントを一応書いておきます。

すでに使われている mask

GL.iNet 製ルータ(OpenWrt / fw3 ベース)では、iptables の mangle / nat / filter テーブル上位で、fwmark / connmark の一部ビットがシステム用途として恒常的に使用されています。

以下は iptables-save から、今回の議論に関係する部分のみを抜粋したものです。

root@GL-MT6000:~# iptables-save

# mangle
-A PREROUTING -m connmark ! --mark 0x0/0xf000 \
-j CONNMARK --restore-mark --nfmask 0xf000 --ctmask 0xf000

-A TUNNEL100_ROUTE_POLICY \
-m mark --mark 0x0/0xf000 \
-j MARK --set-xmark 0x8000/0xf000

# filter
-A zone_lan_input -p udp --dport 53 \
-m mark ! --mark 0x8000/0xf000 \
-j DROP

この構成から分かる通り、

  • 0x8000/0xf000(fwmark bit12-15)

    • ポリシールーティング(VPN / トンネル判定)
    • DNS leak 防止判定
    • connmark ⇔ fwmark の save / restore

といった システム中核ロジックがこのビット範囲に依存しています。

そのため、0x8000 を含む 0x0000f000 領域はユーザーが独自用途で使用すると確実に衝突するという前提で設計する必要があります。

本記事ではこの予約領域を避けるため、 bit16 以降(例: 0x00100000 以上)を MAP-E 用 fwmark として使用しています。

nth ルールは等確率ではない

調査時、PREROUTINGにて、 -set-mark をしているにもかかわらず mark が(GL.iNet によって付与された0x8000を除いて)立っていないパケットがちらほら散見されました。

有志による/etc/firewall.userの実装9では

/etc/firewall.user
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 0 -j MARK --set-mark 10
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 1 -j MARK --set-mark 11
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 2 -j MARK --set-mark 12
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 3 -j MARK --set-mark 13
...

のように、nthルールを用いてパケットを書くポート群に分散させていました。 ただ、自分も勘違いしていましたが、どうやらnth ルールは等確率でパケットを分けてくれるわけではない様です。

nth ルールは

  • それぞれ独立したカウンタを持つ
  • そのカウンタは、「そのルールまで到達したパケット数」で増える

という特性を持っています。

つまり、

  • 1 本目のルールは「全部のパケット」を見てカウントする
  • 2 本目のルールは「1 本目でマークされなかったパケットだけ」をカウントする
  • 3 本目のルールは「1〜2 本目でマークされなかったパケットだけ」

という、階段状にどんどん「見ている母数」が減っていく構造になる...らしい。

そうすると、各 nth ルールでの周期がずれ、最終的にどこにもヒットしないパケットが通り抜けて出てきてしまうことがあるみたいです。

GPT と相談し、random を用いてほぼ等確率にパケットを分けてくれる様にしました。

二重実行の回避

現環境(GL.iNet 固有?)では /etc/firewall.user がなぜか 2 回実行されます。このままではルールセットが 2 重で追加されてしまうため、重複実行されることを前提としたルール (重複防止ガードを組むなど)にする必要がありました。

/lib/netifd/proto/map.shで、下記を追記してください。

/lib/netifd/proto/map.sh
 	      json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_close_object
else
local MARK_BASE=0x00100000 # ここから開始
local MARK_MASK=0x0fff0000 # 上位 12bit だけ使用
local mark=${MARK_BASE}
for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
for proto in icmp tcp udp; do
json_add_object ""
json_add_string target SNAT
json_add_string family inet
json_add_string proto "$proto"
json_add_string mark "$(printf '0x%08x' "${mark}")/${MARK_MASK}"
json_add_boolean connlimit_ports 1
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_add_string snat_port "$portset"
json_close_object
done
mark=$((mark + 0x00010000))
done
fi
if [ "$maptype" = "map-t" ]; then

Network -> Firewall -> Custom Rules に以下を設定 (/etc/firewall.user に設定したのちに/etc/init.d/firewall restart を実行するのと同義です)。

備考

複数のインタフェースにmarkをふりたい場合は半角スペース区切り( )でインタフェースを追加してください。 例: wgserverを追加したい場合は以下のようになります。

/etc/firewall.user
-IFACES="br-lan"
+IFACES="br-lan wgserver"
/etc/firewall.user
# MAP-E で mark を振りたい入口インタフェースたち
IFACES="br-lan wgserver"

# --- 並行実行ガード(すでに誰かが実行中なら即終了) ---
LOCKDIR=/var/run/mape_nth.lock
if ! mkdir "${LOCKDIR}" 2>/dev/null; then
exit 0
fi
trap 'rmdir "${LOCKDIR}"' EXIT

# MAP-E 用:ポートセット数
EVERY=15

# fwmark のうち、MAP-E 用に使うビットマスク
MARK_MASK=0x0fff0000

# MAP-E で使う mark のベース値
# 例: 0x00100000, 0x00200000, ... と 0x00010000 刻みで 15 個使う想定
MARK_BASE=0x00100000

# HMARK の mod 値
# hash(tuple) % HM_MOD + MARK_BASE の結果のうち、
# MARK_MASK 部分がちょうど 15 個のバケットに割り当たるように
# EVERY * 0x00010000 としている
HM_MOD=$((EVERY * 0x00010000))

PRE_LOG_PREFIX="MAPE_PRE_WARN "
POST_LOG_PREFIX="MAPE_POST_WARN "

# すでに HMARK ルールが入っているかチェック
check_prerouting_one() {
local ifname="$1"
iptables -t mangle -C PREROUTING -i "$ifname" \
-m conntrack --ctstate NEW \
-m mark --mark 0x0/${MARK_MASK} \
-j HMARK \
--hmark-tuple src,srcport,proto \
--hmark-mod "${HM_MOD}" \
--hmark-offset "${MARK_BASE}" \
2>/dev/null
}

# PREROUTING に HMARK ルールを追加
add_prerouting_rules_one() {
local ifname="$1"

# 入口インタフェース ifname から入ってきた「新規」通信で、
# まだ MAP-E 用の mark が振られていないものに対して、
# src,srcport,proto ベースで安定したハッシュを fwmark に設定する。
iptables -t mangle -A PREROUTING -i "$ifname" \
-m conntrack --ctstate NEW \
-m mark --mark 0x0/${MARK_MASK} \
-j HMARK \
--hmark-tuple src,srcport,proto \
--hmark-mod "${HM_MOD}" \
--hmark-offset "${MARK_BASE}"
}

# 既存チェック→未導入なら投入(インタフェースごと)
for ifname in $IFACES; do
check_prerouting_one "$ifname" || add_prerouting_rules_one "$ifname"
done

最後に下記を実行。

/etc/init.d/network restart

これをすることで、下記の様なルールが生成されていることを確認できると思います。

root@...# iptables -t mangle -L PREROUTING -nv --line-numbers
root@...# iptables -t nat -L POSTROUTING -nv --line-numbers

余談

以下は調査中に気づいたことです。

Network Acceleration を有効にすると NAT を介さないパケットが漏れ出る

これはおそらく GL.iNet v4.8.2, v4.8.3 あたりで発生している問題だと思います。

そのIPに対して本来ルーティングされるべきでないパケットが漏れ出ているということはL3の問題であり、iptablesの問題でない事が分かります。調査の結果、 Network Acceleration が有効の場合(Hardware, Software問わず)に再現できる問題のようでした
この問題に関しては今後GL.iNetのフォーラムに投げてみようかなあと考えています。

ちなみに最近 Beta 版であるv4.8.99 (2025-11-28)を試してみましたが、こちらにすると

  • Software Acceleration: ✅ 問題なし
  • Hardware Acceleration: ❌ 再現

という感じでした。

おわりに

これで晴れて Flint 2 で快適なインターネットライフを送れる様になりました 🥳

ただ、前述した通り現状は Network Acceleration を無効にしているため真のパフォーマンスはまだ発揮できていないと思います。

今後の TODO としては

あたりになると思います。

まとめとしては、日本で外向きに通信する L3 ルータとして GL.iNet はお勧めできません!素直に Yamaha の RTX830 を買ってください!!!10

Footnotes

  1. 日本で買う場合は技適の都合で Amazon.co.jp を使うのをお勧めします。セール時だと前述の値段なので狙うことをお勧め。

  2. こちらの前置きが面白かったので真似させていただきました 😅 自力で IPv4 over IPv6 をした(Tunnel 編) | 愚行録 the Next Generation

  3. OpenWrt - Wikipedia

  4. 徹底解説 v6 プラス – 技術書出版と販売のラムダノート 2

  5. 入社 1 年目の挑戦:IPv4 over IPv6 への新たな取り組み - BIGLOBE Style | BIGLOBE の「はたらく人」と「トガッた技術」

  6. NanoPi R2S+OpenWRT 21.02.0 で BIGLOBE の MAP-E 接続 – OSAKANA TARO のメモ帳 2

  7. OpenWRT の 64bit アーキテクチャで、mapcalc が適切に動かない話 [MAP-E] | Medium 2

  8. MAP の場合の設定は、RFC 7598 で標準化されている DHCPv6 Option 95 によりプロバイダから降ってくることが前提ですが、日本の場合 ISP と VNE が違う都合、ルータ側で設定されている必要があります47。legacy map オプションを有効にして自分で設定する必要があるのはこのためです。

  9. OpenWrt map-e (JPNE v6plus) において、割当ポート 240 個をちゃんと使わせるための設定。

  10. 中古で買うと安いのでお勧め