NanoPi R2S+openWRT 21.02.0RCでBIGLOBEのMAP-E接続

2021/09/14追記

OpenWRT 21.02.0リリース版にてだいぶ手順が変わってしまったので、あたらしく「NanoPi R2S+OpenWRT 21.02.0でBIGLOBEのMAP-E接続」として修正しています。

この記事は古い内容となります。


GL.iNET GL-MV1000を使っていたわけですが2020年8月以降IPv6が無効化、そのまま放置され、2021年4月になって再度有効化されたものの、GL.iNETが提供する機能以外の部分はほぼ切り捨てられてしまいました。

GL.iNET firmwareの駄目なところ
・GL.iNET UIで提供されている機能はGL.iNET側で有効化しないとluci側で行った設定が有効にならない(DynamicDNSやIPv6など)
・追加したパッケージはfirmwareバージョンアップ時に削除される(GUI上はパッケージを追加する、とか表示されるけど追加されたことはない)
・GL.iNet ver 3.201だとluci パッケージがインストールされていないため詳細設定が出来ない
・パッケージを追加するにはネットワーク接続が必須だがGL.iNET UIだと詳細設定ができないのでネットワーク接続ができない場合がある

そんな状況が約1年続いたわけなので、さすがに諦めました。

代替としてRockchip RK3328のNanoPi R2S と Rockchip RK3399のNanoPi R4S を候補にあげた。

Amazon日本の倉庫に在庫があるというのと、openWRTのページに「FriendlyARM NanoPi R2S」とデバイスに関する個別ページが作成されており、snapshotの提供がされていたので、NanoPi R2Sを買って設定を行った。

画像
画像

ちなみに置き換え対象となったGL-MV1000とのサイズ比較はこんな感じ

画像
画像

さて、openWRTの設定を行ったタイミングではopenWRT 21.02.0 rc1の提供が開始されていたのでそちらを使用した。(2021/07/12追記 openWRT 21.02.0 rc3は壊れているようでLANポートが稼働しないので使わないこと。やるのであればrc2)

friendlyarm_nanopi-r2s-squashfs-sysupgrade.img.gz を展開したものをmicroSDに書き込んでNanoPi R2Sを起動した。

設定手順1:パッケージの追加

mapパッケージと日本語UIパッケージ(luci-i18n-base-ja)をインストール

CLIでインストールする場合は以下を実行

# opkg update
# opkg install luci-i18n-base-ja
# opkg install map

インストール後は再起動を行うこと。

再起動しないとluciのネットワーク設定で「プロトコル:MAP / LW4over6」が選択肢に現れません。

設定手順2:WAN6インタフェースの作成

WAN6インタフェースがなければ「プロトコル: DHCPv6クライアント」で作成する

最初はそのまま設定して、有効化し、WAN6インタフェースに割り当てられるIPv6アドレスを確認すること。

↑の画像は使い回しなので、この段階では無いはずの「MAP」インタフェースが入ってます

上記のように「IPv6」アドレスが確認できたら、そのアドレスをコピーして、[詳細設定]の「委任されたカスタムIPv6プレフィックス」に貼り付け「/56」とかつけます。

設定手順3:WAN6インタフェースにDHCPv6関連設定

openWRT 21.02の段階でもWAN6インタフェースではDHCPv6関連設定がGUIできない状態であるため、/etc/config/dhcpファイルを直接書き換えます。

必要な設定は「option dhcpv6 ‘relay」「option ra ‘relay’」「option ndp ‘relay’」「option master ‘1’」です。

変更したあとは、以下の様な感じになるかと思います。

config dhcp 'wan6'
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'
        option interface 'wan6'
        option start '100'
        option limit '150'
        option leasetime '12h'

ファイル変更後は下記を実行して変更を反映します。

# uci commit dhcp
# /etc/init.d/odhcpd restart
# /etc/init.d/network restart

設定手順4:LANインタフェースにDHCPv6関連設定

LANインタフェースの[DHCPサーバー]-[IPv6設定]で以下の設定を行います。

RA-Service:リレーモード
DHCPv6-サービス: リレーモード
NDP-Proxy: リレーモード

(マスターにチェックは入れません)

設定手順5: MAP-E接続設定

インタフェースの新規作成で「プロトコル:AP / LW4over6」を作成して、必要な値を入れていきます。

[一般設定]では下記の様にしました。

プロトコル:MAP/LW4over6
タイプ:MAP-E
以後は環境に合わせた値

[詳細設定]では下記の2つを設定します。

「トンネルリンク: WAN6」
「従来のMAPを使用」にチェックを入れる

設定完了

ひとまずこれで設定完了です。

うまく接続が始まらない場合は、再起動してみてください。

設定:ニチバン対策

2chの「v6プラス関連 Part21」に下記のような書き込みがある。

757名無しさんに接続中… (ブーイモ MM0e-wDGU)2020/09/27(日) 12:54:30.84ID:cYRzN3kgM>>758
openwrtでMAP-Eされてる方で、
https://gist.github.com/anonymous/0fdec75fa20a7f1ce4806391d6b0429b
このgitのコメントにあるように、
json_add_boolean connlimit_ports 1を
json_add_string connlimit_ports “1”
に変えるor最新のfirewallパッケージを入れるで安定して通信出来てる人いますか?

これをする事でopenwrtで当たり前となってるmap.sh編集してMARKターゲット作ってstatisticで分散してって事をせずとも、
connlimitでポートセット使い切ったら次のポートセット移ってってfirewallがちゃんと出来上がるようになるけど、
ルール通りロールアウトしてる気配が全く無い。
ロールアウトせずパケ詰まりしてしまう。

795 757 (ブーイモ MMe7-PIvK)2020/09/30(水) 20:53:39.27ID:1mR0IohpM>>802
最終的にこのようなcunstom rulesになりました。
https://pastebin.pl/view/raw/06212cd8
多分ですが、map.shで自動生成されるiptablesだと、
–connlimit-maskの指定がなく32になるので、
それだとdestinationが0.0.0.0/0なのでマッチせずロールアウトされないんだと思います。
0にしてあげたらロールアウトしました。(間違ってたらご指摘下さい。)
TCPもnf_conntrack調整したらconnlimitでも大丈夫な感じでしたが、
statisticでかなり安定してるのでTCPのみstatisticにしました。
map.shはlegacy=1をコメントアウトするか、snapshotsから最新のmapをインストールした場合は、
option legacymap ‘1’をnetworkのmapインターフェイスに追記するだけで動くと思います。
markターゲット追加する改変は不要です。
custom rulesに書いただけだと、リブート時、custom rulesの後にmap.shがiptablesを書いてしまうので、
local startupに
sleep 30
sh /etc/firewall.ser
を書けばmap.shで自動生成されたNATテーブルを削除して改めて書いてくれます。

これで、ニチバンベンチ回してもTCPは詰まらないですし、
MAP-EでUDP hole puch使うアプリケーションが使えるので、PS系ゲーム機でNATタイプ2になりましたし、
SoftEtherでUDP高速化機能が使るようになりました。

アドバイス下さった>>758様や、スクリプト考案の先駆者様等、
有難うございます。

GL-MV1000時代にも試した「OpenWrt map-e (JPNE v6plus) において、割当ポート240個をちゃんと使わせるための設定。」はここでもうまく動作していなかった模様。

代替としてhttps://pastebin.pl/view/raw/06212cd8にある設定に置き換えるとある。

しかし「OpenWrt map-e (JPNE v6plus) において、割当ポート240個をちゃんと使わせるための設定。」のコメント欄を見ると、誤植があるようだった。

また、誤植修正後も接続状況が不安定なので出力されるiptablesの確認したところ、範囲外のポートを指定していることが判明

(2021/05/21追記: この差異はV6プラス/BIGLOBEとOCN バーチャルコネクトとの仕様の違いとのこと)

修正版として https://gist.github.com/osakanataro/a9ba5ded340070b8e6abc28969d7ae4f を作成した。

修正点
「units=63」→「units=15」
「portl=expr $rule \* 1024 + $PSID \* 16」→「portl=expr $rule \* 4096 + $PSID \* 16

IP4,PSID, LANDEV,WAN6DEV,TUNDEVは自分の環境に合わせて変更すること
IP4, PSIDがわからない場合は http://ipv4.web.fc2.com/map-e.html で確認すること

#units=63
units=15

IP4='xxx.xxx.xxx.xxx'
PSID=110
LANDEV='br-lan'
WAN6DEV='eth0'
TUNDEV='map-MAP'

iptables -t nat -F PREROUTING
iptables -t nat -F OUTPUT
iptables -t nat -F POSTROUTING

rule=1
while [ $rule -le $units  ] ; do
  mark=`expr $rule + 16`
  pn=`expr $rule - 1`
  portl=`expr $rule \* 4096 + $PSID \* 16`
  portr=`expr $portl + 15`

  echo iptables -t nat -A PREROUTING -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A PREROUTING -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark
  echo iptables -t nat -A OUTPUT -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A OUTPUT -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark

  echo iptables -t nat -A POSTROUTING -p icmp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p icmp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr
  echo iptables -t nat -A POSTROUTING -p tcp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p tcp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  echo iptables -t nat -A POSTROUTING -p udp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p udp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr

  rule=`expr $rule + 1`
done

上記を

openwrtの[ネットワーク]-[ファイヤーウォール]-[Custom Rules] (/etc/firewall.user) に記載する。

また、[システム]-[スタートアップ]-[ローカルスタートアップ] (/etc/rc.local)の exit 0よりも前に下記2行を追加する

sleep 30
sh /etc/firewall.user

また、iptablesのstatisticモジュールはiptables-mod-ipoptに入っているが、標準では導入されていないため、下記のようにインストールする。

root@nanopi:~# opkg install iptables-mod-ipopt
Installing iptables-mod-ipopt (1.8.7-1) to root...
Downloading https://downloads.openwrt.org/releases/21.02.0-rc1/targets/rockchip/armv8/packages/iptables-mod-ipopt_1.8.7-1_aarch64_generic.ipk
Installing kmod-ipt-ipopt (5.4.111-1) to root...
Downloading https://downloads.openwrt.org/releases/21.02.0-rc1/targets/rockchip/armv8/packages/kmod-ipt-ipopt_5.4.111-1_aarch64_generic.ipk
Configuring kmod-ipt-ipopt.
Configuring iptables-mod-ipopt.
root@nanopi:~#

これで、とりあえずニチバンもスムースに開けるようになった。


失敗例コレクション

「プロトコル:MAP / LW4over6」が選択肢にない

画像

mapパッケージインストール後、openWRTを再起動するまで、このプロトコル一覧は更新されませんでした。

再起動すると表示されるようになりました。

「MAP rule is invalidError: MAP rule is invalid」になる

「MAP rule is invalidError: MAP rule is invalid」はWAN6インタフェースの詳細設定で「委任されたカスタムIPv6プレフィックス」(ip6prefix)を設定していない場合に出力されました。

invalidと表示された時のWAN6インタフェースの「IPv6-PD」に表示されている値を突っ込んだら、invalidが解消されました。

設定ファイル的には/etc/config/networkのWAN6に関する記述に「list ip6prefix」を追加する感じです。

LAN内にDHCPv6アドレスが配布されない

nanoPi上は特に問題無くIPv6アドレスが割り当てられており動作もしているが、LAN内のクライアントにDHCPv6アドレスが配布されていないという状態になった。

これは、LANインタフェースの[DHCPサーバ]-[IPv6設定]にある「マスター」にチェックを一度でも入れてしまうと発生する事象だった。

一度チェックを入れて保存すると、/etc/config/dhcp に以下の様な設定が行われる。

<略>
config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option ra_maxinterval '600'
        option ra_mininterval '200'
        option ra_lifetime '1800'
        option ra_mtu '0'
        option ra_hoplimit '0'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'
        option master '1'
<略>

この後、マスターのチェックを外すと、以下の様になる

<略>
config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option ra_maxinterval '600'
        option ra_mininterval '200'
        option ra_lifetime '1800'
        option ra_mtu '0'
        option ra_hoplimit '0'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'
<略>

ここで問題となったのは以下の値でした。

        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option ra_maxinterval '600'
        option ra_mininterval '200'
        option ra_lifetime '1800'
        option ra_mtu '0'
        option ra_hoplimit '0'

これらの値が存在しているとDHCPv6アドレスのLAN内への配布がうまくいきませんでした。

/etc/config/networkを編集したあと、下記で反映することで動作するようになりました。

# uci commit dhcp
# /etc/init.d/odhcpd restart
# /etc/init.d/network restart

参考: IPv6 working on router but not on clients

MAP-E接続が開始されない

GL-MV1000からnanoPi R2Sに置き換えてすぐは、IPv6接続はできているが、MAP-E接続が開始されない、という状態になった。

ONUの電源を切り、5分ぐらいしてから電源を入れnanoPiも起動するとMAP-E接続が可能となった。

おそらく、接続先でのセッション認識が消えないと別のデバイスでの接続が行うことができないようだ。(エラーにもならないので詳細は不明)


参考資料

/etc/config/network

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd23:66f8:d98f::/48'

config interface 'lan'
        option type 'bridge'
        option ifname 'eth1'
        option proto 'static'
        option netmask '255.255.255.0'
        option ipaddr '192.168.1.1'
        option ip6assign '60'

config device 'lan_eth1_dev'
        option name 'eth1'
        option macaddr '1a:e4:a4:xx:xx:xx'

config interface 'wan'
        option ifname 'eth0'
        option proto 'dhcp'
        option auto '0'

config device 'wan_eth0_dev'
        option name 'eth0'
        option macaddr '1a:e4:a4:xx:xx:xx'

config interface 'wan6'
        option ifname 'eth0'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option reqprefix 'auto'
        list ip6prefix 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/56'

config interface 'MAP'
        option proto 'map'
        option maptype 'map-e'
        option peeraddr 'xxxx:xxxx:xxxx:xxxx::64'
        option ipaddr 'xxx.xxx.xxx.xxx'
        option ip4prefixlen '15'
        option ip6prefix '240b:10::'
        option ip6prefixlen '31'
        option ealen '25'
        option psidlen '8'
        option offset '4'
        option tunlink 'wan6'
        option legacymap '1'

/etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option boguspriv '1'
        option filterwin2k '0'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option nonegcache '0'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option nonwildcard '1'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

config dhcp 'wan6'
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'
        option interface 'wan6'
        option start '100'
        option limit '150'
        option leasetime '12h'