OpenWrt:v6プラス MAP-E IPv4通信不能 – 5年目の罠 –

Internet

インシデント発生:2026年5月28日(木)帰宅時

 帰宅後、照明操作のため、Alexaに話しかけると「インターネットに接続できません」聞いたこともないような「ささやき声」で彼女は言いました。
「ささやき声」で話しかけた訳ではないのですが、真っ暗な部屋でAlexaの突然の「ささやき声」はとても怖かったです。

 インターネット接続不具合の状況を確認したところ、GoogleやYouTubeなど、IPv6で到達できるサービスは利用できるのですが、なぜかIPv4アクセスができません。
 
 下図は我が家のネットワーク構成図です。クライアント用インターネット経路はOpenWrt VMのv6プラス/MAP-E接続、サーバ用インターネットアクセス経路はSophos FirewallのIPv4 PPPoE接続を使用しています。
グレーアウトしている範囲は、今回の障害とは直接関係しない部分です。

 Sophos Firewall経由のPPPoE接続は正常でした。平日の夜だったため、原因調査は週末に回すことにしました。
暫定対処として、クライアントセグメントのデフォルトルートをOpenWrtからSophos Firewallに変更し、しばらく代替運用することにしました。

OpenWrtのルーティング機能は正常に動作していたため、経路を1つ追加することで対応できました。

不具合調査再開

 週末になり、切り分けのためにNEC Wi-Fiルータ WG1200HP4で動作確認したところ、正常にIPv4アクセスが可能でした。そうなると、これは確実にOpenWrtの問題です。さらに詳しくルータの通信状況を確認したところ、IPv6の割り当て、正確にはIPv6プレフィックスが以前の値から変わっていることに気が付きました。
(よく気が付いたな)

 OpenWrtのv6プラス/MAP-E接続は、2021年頃に設定したものです。当時は、IPv6プレフィックスから共有IPv4アドレスを計算し、その結果をOpenWrtのwanmapeに静的設定するような手順で構築していました。当時は今ほど情報も多くなく、OpenWrtでv6プラス/MAP-Eを動かすには、必要な値を手計算して設定するのが現実的でした。

暫定復旧

復旧作業はOpenwrtにssh接続して行いました。
最初に現在DHCPv6-PDで取得しているIPv6プレフィックスを確認します。

root@OpenWrt:~# ifstatus wan6

#実行結果一部抜粋
:
(省略)記事中のIPv6プレフィックスは実環境の値をそのまま掲載せず、一部を伏字にしています。
:


"ipv6-prefix": [
        {
                "address": "240b:10:b5a4:xxxx::",
                "mask": 56,
                "class": "wan6",
                "assigned": {
                        "lan": {
                                "address": "240b:10:b5a4:xxxx::",
                                "mask": 60
                        }
                }
        }
]

:
(省略)
:

確認結果、ipv6-prefixのaddressは「240b:10:b5a4:xxxx::」、maskは「56」
下記のコマンドでnetwork.wan6.ip6prefixを明示的に設定します。

root@OpenWrt:~# uci set network.wan6.ip6prefix='240b:10:b5a4:xxxx::/56'
root@OpenWrt:~# uci commit network

network.wan6.ip6prefixを更新したあと、念のためwan6も一度再起動します。

root@OpenWrt:~#  ifdown wan6
root@OpenWrt:~#  sleep 5
root@OpenWrt:~#  ifup wan6
root@OpenWrt:~#  sleep 30

wan6インターフェースをダウン、もう1度アップします。
実際にはsleepは使わず、停止後5秒、起動後30秒ほど待機しています。
これは、停止処理が完全に終了するのを待つ意図と、DHCPv6-PDによるIPv6プレフィックス再取得の完了を待つための安全マージンという意図で待機しています。待機時間は目安です。

次にwanmapeを再生成します。

root@OpenWrt:~#  ifdown wanmape
root@OpenWrt:~#  sleep 5

root@OpenWrt:~#  nft delete table inet mape 2>/dev/null

root@OpenWrt:~#  ifup wanmape
root@OpenWrt:~#  sleep 5

firewallを再読み込みします。

root@OpenWrt:~#  /etc/init.d/firewall restart

:
(省略)
:
ubus nat (ubus:wanmape[map] nat 0) specifies ports but no UDP/TCP protocol, ignoring section
ubus nat (ubus:wanmape[map] nat 3) specifies ports but no UDP/TCP protocol, ignoring section
ubus nat (ubus:wanmape[map] nat 6) specifies ports but no UDP/TCP protocol, ignoring section
:
(省略)
:

root@OpenWrt:~#  sleep 5

firewall restart時には、ICMP用NATセクションが無視される警告が大量に出力されていました。map-wanmape向けのTCP/UDP SNATはfw4のnftablesルールとして生成されていましたが、ICMP用SNATは生成されておらず、外部インターネットホストへのping疎通はできませんでした。そこで、下記のコマンドでICMP用SNATを追加して補完しました。

root@OpenWrt:~#  nft insert rule inet fw4 srcnat \
  meta nfproto ipv4 \
  meta l4proto icmp \
  oifname "map-wanmape" \
  counter \
  snat ip to 106.72.xxx.xxx:pppp-qqqq \
  comment manual_mape_icmp_test

# snat ip to <共有IPv4アドレス>:<利用可能ポート範囲> 

 共有IPv4アドレスおよびポート範囲は、実環境の値をそのまま掲載せず、一部を伏字にしています。実際には、wanmapeに割り当てられた共有IPv4アドレスと、利用可能なポート範囲を指定します。
利用可能なポート範囲は、ifstatus wanmapeやnft list rulesetで生成されているTCP/UDP用SNATの範囲を参考にしました。
commentは空白いれると構文エラーとなったため、_(アンダースコア)で代用しました。

下記のコマンドでコンソール上での通信確認を行いました。

root@OpenWrt:~# wget -4  -O- http://exiv.net/ >/dev/null && echo "OK"
Downloading 'http://exiv.net/'
Connecting to 172.67.211.218:80
Redirected to / on exiv.net
Writing to stdout

Download completed (324799 bytes)
OK
root@OpenWrt:~#

root@OpenWrt:~# ping -4 -c 4 exiv.net
PING exiv.net (104.21.67.36): 56 data bytes
64 bytes from 104.21.67.36: seq=0 ttl=55 time=9.251 ms
64 bytes from 104.21.67.36: seq=1 ttl=55 time=8.943 ms
64 bytes from 104.21.67.36: seq=2 ttl=55 time=9.091 ms
64 bytes from 104.21.67.36: seq=3 ttl=55 time=9.023 ms

--- exiv.net ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 8.943/9.077/9.251 ms

なお、今回追加したICMP用SNATは手動で投入したnftablesルールのため、OpenWrtの再起動で消えます。
恒久対応については、後編のMAP-E自動化スクリプト導入時にまとめて対応しようと思います。

まとめ

IPv6プレフィックスは5年間変わらなかったため、どこかで「永続的なもの」と決めつけていました。

今回の不具合は、IPv6プレフィックス変更にOpenWrt側のv6プラス/MAP-E設定が追従できていなかったことが原因でした。新しいIPv6プレフィックスをもとにMAP-E設定をやり直し、ICMP用SNATも補完したところ、OpenWrt側のIPv4通信は復旧しました。

ただし、これで終わりにすると、また同じことが起きる可能性があります。

次回は、国内IPoE向けのOpenWrt用スクリプトを導入し、OpenWrtのv6プラス/MAP-E設定を、もう少し自動化寄りの運用に寄せていこうと思います。

余談:ホームラボの歴史

下記は、VMware ESXi時代に作成したネットワーク構成図です。

 

今のProxmox版と比べると、設計・機能はほぼ同じですね。

  • Sophos Firewall / OpenWrtをVMとして配置
  • DMZを仮想スイッチに展開
  • 物理スイッチへトランク
  • Sophos FirewallでVLAN間ルーティング

 5年くらい前から「1台のミニPCの中に仮想ルータと複数セグメントを詰め込み、小さなデータセンターのように扱う」方式で運用しています。この構成は、検証や学習にはとても便利です。

 ESXiからProxmoxへ移行したのは、2024年10月でした。これぐらいの時期にVMwareから他のハイパーバイザーに移行した人も多かったのではないでしょうか。このタイミングで、ミニPCもCeleron N5100搭載機からGMKtec M5 Plus(Ryzen 7 5825U)へ変更しています。

 Ryzen 7 5825Uの消費電力設定を10Wに制限にしていますが、各VMが以前より快適に動作していることが体感できます。24時間稼働のホームラボとしては、性能と消費電力のバランスがかなり良いアップグレードだったと思います。

(おしまい)

コメント

タイトルとURLをコピーしました