
NURO MAP-E環境におけるNordVPN NordLynxのMTU/PMTUD障害
1. 背景
NURO 光のMAP-E環境へ回線を移行した後、macOS版NordVPNで NordLynx を使用すると、VPNアプリ上では「接続済み」と表示される一方、WebブラウジングやHTTPS通信が正常に行えない現象が発生した。
当初は以下を疑った。
MAP-EにおけるUDPポート制限
NordVPNサーバーへのUDP/51820到達不能
NordVPNのルーティング異常
DNS障害
NordVPN Kill SwitchやNetwork Extensionの競合
NordLynxそのものの接続失敗
NURO側でのWireGuard/NordLynxプロトコル制限
しかし、その後のパケットキャプチャ、VPNプロトコル比較、MTU変更試験によって、単純なUDP遮断やVPNサーバー到達不能では説明できないことが判明した。
さらに再検証した結果、NordLynxが生成するutunインターフェースのMTUを1420から1392以下へ下げると通信が成立し、1393以上では同一のHTTPS試験が失敗するという明瞭な閾値が得られた。
本レポートでは、それまでの調査過程で生じた推測や暫定結論をいったん破棄し、再検証後の観測結果を基準として問題を再構成する。
NURO公式はMAP-Eについて、IPv4パケットをIPv6パケット内に内包してIPv6専用アクセス網を通過させる方式であると説明している。また、一部のVPNサービスや特定プロトコルがMAP-E環境で利用できない場合があることも明記している。[1]
2. 用語・単語説明
MAP-E
Mapping of Address and Port with Encapsulation の略。
IPv4通信をIPv6網上で提供するIPv4 over IPv6方式の一つで、IPv4パケットをIPv6パケットにカプセル化して運ぶ。
RFC 7597では、MAP-EでIPv4パケットをIPv6にカプセル化すると通常40 byte程度パケットサイズが増加すること、MTU処理にはPMTUD、フラグメンテーション、TCP MSSなどが関係することが説明されている。[2]
NordLynx
NordVPNが提供するVPNプロトコル実装。WireGuardを基盤としている。[3]
本調査環境ではNordLynx接続時にmacOS上へ utun インターフェースが生成され、IPv4アドレス 10.5.0.2 が割り当てられた。
WireGuard
UDPを利用するVPNトンネルプロトコル。NordLynxの基盤となっている。
本調査で物理NIC側をキャプチャしたところ、NordLynxのトンネル外側ではNordVPNサーバーとのUDP通信が双方向に成立していた。
MTU
Maximum Transmission Unit。
インターフェースや経路が1パケットとして扱えるIPパケットサイズの上限。
IPv4でMTU 1392の場合、オプションなしの通常TCPでは概算で次の関係になる。
1392 - IPv4 header 20 - TCP header 20 = TCP MSS 1352実際に本調査では、MTU 1392設定時のTCP SYNから MSS 1352 が確認された。
MSS
Maximum Segment Size。
TCPが1セグメントに格納するTCPペイロードサイズの上限。MTUとは異なり、IPヘッダやTCPヘッダを含まない。
PMTU / PMTUD
Path MTU は、送信元から宛先までの経路全体でフラグメントせずに通過できる最大IPパケットサイズ。
Path MTU Discovery は、その値を検出して送信パケットサイズを調整する仕組み。
必要なICMPエラー等が正常に送信元まで戻らない場合、送信側が大きすぎるパケットを繰り返し送り続ける「PMTUブラックホール」が発生し得る。
MTUブラックホール / PMTUブラックホール
小さいパケットは正常に通る一方、一定サイズ以上のパケットが途中で失われ、かつ送信側が適切なMTU縮小を認識できない状態。
典型的には以下のような症状になる。
TCP 3-way handshakeは成功する
pingや軽量通信の一部は成功する
TLSハンドシェイク途中で停止する
Webサイトによって「開く」「開かない」が分かれる
大きなTCPセグメントだけ再送され続ける
MTUを手動で下げると突然正常化する
utun
macOSがNetwork ExtensionやVPN等で使用する仮想トンネルインターフェース。
utun6 の数字部分は固定ではなく、再起動や接続状況によって変わる可能性があるため、恒久対策でインターフェース番号をハードコードするべきではない。
3. アブストラクト
NURO 光 MAP-E環境において、macOS版NordVPNのNordLynxを使用すると、VPN接続自体は成立するもののIPv4 HTTPS通信が停止する問題を確認した。
物理NIC上ではNordVPNサーバーとのUDP通信が双方向に成立しており、単純なUDP/51820遮断ではなかった。NordLynx内部のTCPパケットをキャプチャすると、TCP接続確立後、MTU 1420相当の大きなIPパケットだけが相手へ到達せず、後続の小さいセグメントは到達してSACKされる挙動が確認された。
NordLynx接続時のutun MTUは 1420 で生成される。これを手動変更して境界探索した結果、同一条件のCloudflare HTTPS HEAD試験では以下となった。
MTU 1394 : 失敗
MTU 1393 : 失敗
MTU 1392 : 成功
MTU 1391 : 成功
MTU 1390 : 成功さらにMTU 1392ではCloudflareから10,000,000 byteの連続HTTPSダウンロードが成功し、約28.18 MB/s、HTTP 200を記録した。
TCP SYNをキャプチャすると、MTU 1392時にMac側が MSS 1352 を広告しており、
1392 - 20 - 20 = 1352と完全に一致した。
以上から、本環境では NordLynxの既定MTU 1420と、NURO MAP-Eを含む実経路で安全に通過可能なパケットサイズとの不整合により、一定サイズ以上の通信でパケットブラックホールが発生していると判断する。
ただし、1392という値をNURO MAP-E一般の固定PMTUと断定することはできない。1392は本環境・本経路・本検証時点で得られた NordLynx内側インターフェースの実証済み上限値 である。
実運用ではわずかな余裕を持たせ、MTU 1390 を暫定推奨値とする。
4. 前提
4.1 回線
NURO 光
MAP-E方式
LAN側IPv4ネットワーク: 192.168.1.0/24
ONU/ルーターがMAP-E処理を実施
物理LANインターフェースのMTU: 1500
4.2 クライアント
macOS
NordVPN macOSアプリ
調査時のNordVPNアプリは10.6.0系
utun6 という番号自体は恒久的識別子ではない
4.3 NordLynx接続時
実測例:
default route : utun6
IPv4 address : 10.5.0.2
MTU : 1420NordVPNを切断すると当該utunは消滅し、再接続すると新たにトンネルが生成され、MTUは再び1420へ戻った。
したがって、
sudo ifconfig utun6 mtu 1390による変更は接続単位の一時変更であり、NordVPN再接続後には維持されない。
4.4 比較条件
同一Macで次の挙動を確認している。
NURO MAP-E + NordLynx 異常
NURO MAP-E + OpenVPN UDP 正常
NURO MAP-E + OpenVPN TCP 正常
NURO MAP-E + NordWhisper 正常
iPhoneテザリング + NordLynx 正常
従来型デュアルスタック回線 + NordLynx 正常
この比較から、問題はMac全体、NordVPNアカウント、NordVPNサーバー一般、WireGuard一般の恒常障害ではなく、NURO MAP-EとNordLynxの組み合わせに強く依存する。
5. 仮説
仮説A: UDP/51820がMAP-Eで遮断されている
棄却。
物理NIC上のパケットキャプチャでNordVPNサーバーとのUDP通信を双方向に確認した。
したがって、少なくとも本件を「UDP/51820が単純に遮断されている」と説明することはできない。
仮説B: NordLynxトンネルそのものが確立していない
棄却。
utunインターフェース生成
10.5.0.2 の割当
デフォルトルート設定
小さいICMP/TCPパケットの通信
NordVPNサーバーとの双方向UDP
が確認されている。
仮説C: DNS障害
主要因として棄却。
IPアドレス指定や、名前解決後のTCP/TLS段階でも停止が確認された。
仮説D: NordVPN内部Firewall/Conntrackのみが原因
主原因としては支持されない。
NordLynxログには、
telio_firewall::firewall:808 Conntrack failed for outbound IPv4 packetという警告が多数存在した。
ただし、このログ単独では通信障害との因果関係を証明できない。一方、MTUを1392以下に変更するだけで通信が再現性高く正常化するため、少なくとも主要な直接要因としてはMTU/パケットサイズ問題の方が強く支持される。
仮説E: MTU / PMTU不整合によるパケットブラックホール
強く支持される。
根拠:
小さい通信は成立する。
TCP 3-way handshakeは成立する。
大きな1420 byte IPパケットだけが欠落するキャプチャが得られた。
後続の小さいTCPセグメントは相手側に到着しSACKされる。
MTUを下げるだけでTLS/HTTPSが回復する。
MTU 1393と1392の間に再現性のある境界が得られた。
MTU 1392で10 MB連続転送が成功する。
MTU 1392時にMSS 1352が正しく広告される。
本レポートでは、この仮説を現時点で最も説明力の高い原因モデルとする。
6. 詳細
6.1 MAP-Eによる追加カプセル化
RFC 7597では、MAP-EはIPv4パケットをIPv6でカプセル化し、MAPドメインを通過させる。
RFC 7597 §8.3では最大パケットサイズの扱いが重要であるとされ、PMTUD、フラグメンテーション、TCP MSSが明示的に挙げられている。またIPv4をIPv6でカプセル化することで通常40 byte程度サイズが増えると説明されている。
概念的には以下となる。
アプリケーション
↓
TCP / IPv4
↓
NordLynx / WireGuard
↓
UDP / IPv4
↓
NURO MAP-E
↓
IPv6カプセル化
↓
NURO IPv6網したがって、一般的な単一トンネル環境よりヘッダの積み重なりが増える。
ただし、本検証だけからNURO内部経路の正確なPMTUや全ヘッダ構成を確定することはできないため、「何byteのヘッダが原因で1392になる」と断定しない。
6.2 NordLynx既定MTU
NordLynxへ接続するたび、対象utunはMTU 1420で生成された。
NordLynx disconnected
↓
対象utun消滅
NordLynx connected
↓
対象utun生成
MTU 1420この挙動は再接続で再現した。
6.3 NordLynx Extension内部
NordLynx Extensionログには以下が存在する。
[NNE] startTunnel
[NNE] starting tunnel
[NNE] [setTunnelNetworkSettings][0]: applying settings
[NNE] [setTunnelNetworkSettings][0]: completed successfullyまた、バイナリ調査では次のMTU関連文字列が確認された。
_mtu
setMtu:
getMtuさらに nm ではSwiftシンボル:
_$s9SharedNNE20NetworkConfigurationC9InterfaceC3mtuSivpfiを確認した。
これは SharedNNE.NetworkConfiguration.Interface.mtu に相当するMTUフィールドが実装されていると解釈できる。
一方、以下のPreference plistは空だった。
com.nordvpn.NordVPN.NordLynx.plist
{}com.nordvpn.NordVPN.NetworkTunnelExtension.plist
{}したがって、少なくとも調査時点では、ユーザーがplistの公開設定値を書き換えるだけでNordLynx MTUを変更できる形跡は確認できなかった。
6.4 1420時のTCP挙動
NordLynx内部のutunをtcpdumpすると、TCP 3-way handshake自体は成立した。
しかしその後、
IP length 1420
TCP seq 1:1369に相当する大きなセグメントが送信された後、相手側からそのデータに対するACKが返らなかった。
その後の小さいセグメント:
seq 1369:1544は到達し、相手側は概ね次の状態を返した。
ACK 1
SACK {1369:1544}これは、
後から送った小さい範囲は受信済み
先頭の大きい範囲 1:1369 が欠落している
ことを示す。
大きなセグメントは再送され続け、最終的により小さい単位へ再送された際にACKが進行した。
この挙動は「接続先が応答していない」のではなく、パケットサイズに依存して特定セグメントが失われていることを強く示す。
6.5 Webサイトごとの差
MTU 1420でもXが開く場合がある一方、YouTubeは正常に利用できないことがあった。
これは本件が「完全なVPN切断」ではなく、通信内容・TCPセグメントサイズ・TLS交換・再送条件等によって表面症状が変化することと整合する。
したがって、特定サイトが開くことだけでは、そのMTUが安定していることの証明にはならない。
7. 検証
7.1 NordLynx外側UDPの確認
物理NICでUDP/51820をキャプチャ。
観測:
Mac → NordVPNサーバーのUDP通信あり
NordVPNサーバー → MacのUDP応答あり
大小複数サイズのパケットあり
デフォルトMTU 1420時には外側IPv4長約1480 byteのNordLynx UDPパケットも観測
結論:
UDP/51820の単純遮断ではない。
7.2 VPN方式比較
NURO MAP-E上で以下を比較。
NordLynx : 異常
OpenVPN UDP : 正常
OpenVPN TCP : 正常
NordWhisper : 正常NordWhisper接続時にはutun MTU 1420でも通常のHTTPS通信が成立し、utun上で1420 byteの内側TCP/IPパケットがACKされていた。
このため、「内側MTU 1420という数値だけが常に問題」という説明は成立しない。
プロトコルごとの外側カプセル化方式とMAP-E経路との組み合わせが重要である。
7.3 他回線比較
同一Mac・NordLynxで、
iPhoneテザリング
従来型デュアルスタック回線
では正常に通信できた。
したがって、NordLynx自体が当該Macで恒常的に故障している可能性は低い。
7.4 MTU手動変更による再現性確認
NordLynx接続直後はMTU 1420で通信障害を確認。
sudo ifconfig utun6 mtu 1380
とするとブラウジングとHTTPS通信が回復した。
NordVPN切断→再接続後はMTU 1420へ戻り障害が再発し、再びMTUを下げると復旧した。
7.5 MTU粗探索
for mtu in 1420 1410 1400 1395 1390
do
sudo ifconfig utun6 mtu $mtu
echo "MTU=$mtu"
curl -4 -I --connect-timeout 1 --max-time 3 -s -o /dev/null -w "%{http_code}
" "https://www.cloudflare.com/"
done結果:
MTU=1420
000
MTU=1410
000
MTU=1400
000
MTU=1395
000
MTU=1390
200000 はcurlが制限時間内にHTTPレスポンスコードを得られなかったことを示す。000 自体がパケット破棄の直接証拠ではないが、他のパケットキャプチャ結果と合わせて評価する。
7.6 MTU精密探索
for mtu in 1394 1393 1392 1391 1390
do
sudo ifconfig utun6 mtu $mtu
echo "MTU=$mtu"
curl -4 -I --connect-timeout 1 --max-time 3 -s -o /dev/null -w "%{http_code}
" "https://www.cloudflare.com/"
done結果
MTU=1394
000
MTU=1393
000
MTU=1392
200
MTU=1391
200
MTU=1390
200この試験条件では 1392と1393の間に明瞭な成否境界 が存在した。
7.7 MTU 1392での連続データ転送
curl -4 --connect-timeout 2 --max-time 10 -o /dev/null -w "%{speed_download} %{http_code}
" "https://speed.cloudflare.com/__down?bytes=10000000"結果:
100 9765k
Average Speed: 約26.8 MiB/s
speed_download: 28179174 byte/s
HTTP: 200約10 MBを正常に転送でき、speed_download では約28.18 MB/sを記録した。
7.8 MSS確認
MTU 1392時に:
sudo tcpdump -i utun6 -nn 'tcp[tcpflags] & tcp-syn != 0'Mac → Cloudflare:
options [mss 1352,...]Cloudflare → Mac:
options [mss 1380,...]Mac側広告MSSは計算値と一致する。
MTU 1392
- IPv4 header 20
- TCP header 20
= MSS 1352これにより、ifconfig で設定したMTUがTCPレベルにも正しく反映されていることを確認した。
なお、TCP MSSは双方向で独立して広告されるため、Cloudflare側MSS 1380とMac側MSS 1352が異なること自体は異常ではない。
8. 結果
8.1 観測事実
NURO MAP-E + NordLynxで通信障害が発生する。
同一環境でOpenVPN UDP/TCPおよびNordWhisperは正常。
同一MacのNordLynxは他回線では正常。
NordLynx外側UDPは双方向に通信している。
NordLynx接続時のutun MTUは1420。
NordVPN再接続でMTUは1420へ戻る。
MTU変更だけで症状の発生・解消を再現できる。
MTU 1393ではCloudflare HTTPS試験失敗。
MTU 1392では同試験成功。
MTU 1392で約10 MBのHTTPS連続転送成功。
MTU 1392時のMac側TCP MSSは1352。
MTU 1420時、大きなTCPセグメントが欠落し、小さい後続セグメントのみSACKされる挙動を観測した。
8.2 MTU試験結果
【NordLynx内側 MTU評価(Cloudflare HEAD)】
------------------------------------------
MTU値 ステータス 結果
------------------------------------------
1420 000 失敗
1410 000 失敗
1400 000 失敗
1395 000 失敗
1394 000 失敗
1393 000 失敗
1392 200 成功 (適正上限)
1391 200 成功
1390 200 成功
------------------------------------------8.3 1392での追加結果
【MTU 1392 での追加検証結果】
----------------------------------------------------------------------
項目 結果 / 詳細
----------------------------------------------------------------------
HTTPS HEAD 200 OK
約10 MB HTTPS download 成功
speed_download 28,179,174 byte/s (約 28.18 MB/s)
TCP SYN Mac側MSS 1352
理論MSS 1352 (計算式: 1392 - 20 - 20)
HTTP status 200 OK
----------------------------------------------------------------------8.4 推論
最も整合する説明は以下である。
NordLynx
内側MTU 1420
↓
WireGuard/UDPによる外側カプセル化
↓
NURO MAP-EによるIPv6カプセル化
↓
経路上の許容サイズを一部パケットが超える
↓
必要なPMTU調整が十分機能しない
↓
大きいパケットだけ消失
↓
TCP再送 / TLS timeout / Webサイト部分不通MTUを1392以下にすると、
内側TCP/IPパケット縮小
↓
TCP MSSも1352へ縮小
↓
NordLynx外側パケットも縮小
↓
MAP-Eを含む経路で安全に通過
↓
HTTPS正常化と説明できる。
8.5 未確定事項
以下は現時点では確定していない。
NURO MAP-E内部の実際のIPv6 Path MTU
1392という閾値を決定している正確なヘッダ/経路要因
NURO ONU/CEがどの段階でフラグメントまたはICMPv6 Packet Too Bigを処理しているか
NordLynx/macOS Network Extension側でPMTUD情報がどのように扱われているか
NURO設備固有なのか、特定ONU/ファームウェア固有なのか
1392が別NordVPNサーバー、別時刻、別経路でも常に同一か
したがって、「NURO MAP-EのMTUは1392である」と一般化してはならない。
正確には、
本検証環境において、NordLynx内側utun MTU 1392が成功し1393が失敗する再現性のある境界を観測した。
と表現する。
9. 結論
本件は、NordVPNアプリが「接続済み」にならない問題でも、NordVPNサーバーへのUDP到達不能でも、DNSだけの問題でもない。
NURO MAP-E環境とNordLynxの多重カプセル化条件下で、NordLynx既定MTU 1420が本経路に対して大きすぎ、PMTU調整が十分に機能しないことで一定サイズ以上のパケットがブラックホール化する問題と判断する。
決定的な根拠は以下である。
MTU 1420時に大きなTCPセグメントだけが欠落する。
MTU変更だけで障害の再現・解消が可能。
HTTPS試験の境界が1393失敗 / 1392成功として観測された。
MTU 1392時にMSS 1352へ正しく縮小され、10 MB連続転送も成功した。
現時点で最も実用的な回避策は、NordLynx接続後に対象utun MTUを下げることである。
最大確認値:
MTU 1392安定性を優先した暫定運用推奨値:
MTU 1390ただし、さらに安全余裕を求める場合は1380等を採用する選択肢もあり、1380でも正常通信は実証済みである。
10. 今後の課題
10.1 MTU自動適用
NordLynx再接続のたびにutunが再生成され、MTUが1420へ戻る。
恒久対策としてはroot権限のLaunchDaemon等で、
NordVPN NordLynx がConnectedであることを確認
現在のデフォルトルートのインターフェースを取得
対象がNordLynxのutunであることを確認
MTUが1390でなければ ifconfig <utun> mtu 1390
とする方式が現実的である。
utun6 を固定値として使用してはならない。
10.2 NordVPN内部MTU設定の探索
NordLynx Extensionには NetworkConfiguration.Interface.mtu に相当する実装が存在する。
今後、
MTU値がどこから渡されるか
1420がローカル定数か動的計算値か
Network Extension設定の非公開パラメータとして変更可能か
NordVPN Remote Config等が関与するか
を調査する余地がある。
10.3 物理側で1392 / 1393を比較
同一通信について、
NordLynx MTU 1392
NordLynx MTU 1393
それぞれで物理NICの外側UDPパケットサイズを取得し、差分を確認する。
10.4 ICMP / ICMPv6の観測
物理側で、
ICMP Fragmentation Needed
ICMPv6 Packet Too Bigが戻っているかを確認する。
必要なエラーが生成されていない、あるいはMac/NordLynxまで伝達されていない場合、PMTUブラックホールの成立過程をさらに直接証明できる。
10.5 サーバー・時間帯・経路差の反復試験
別NordVPNサーバー、別時間帯、再起動後に同一試験を行い、
1393 NG
1392 OKという境界が恒常的かを確認する。
11. まとめ
今回の調査では、NURO MAP-E環境でNordVPN NordLynxを利用した際の通信障害について、単なる相性問題という段階から、パケットサイズ依存のMTU/PMTU問題まで原因を絞り込んだ。
最も重要な観測は次の通りである。
NordLynx既定MTU = 1420
↓
NURO MAP-E環境
↓
一部小通信は成立
大きなTCPセグメントは欠落
↓
HTTPS/TLS/YouTube等が不安定・停止MTUを段階的に縮小すると、
1393 = 失敗
1392 = 成功という境界が得られた。
MTU 1392では、
MSS = 1352
10 MB HTTPS transfer = 成功
HTTP = 200まで確認できた。
したがって、本環境における現時点の実用対策は、
sudo ifconfig <NordLynxのutun> mtu 1390とすることである。
ただし、これは「NURO MAP-E一般のMTUが1390または1392」という意味ではない。
現時点で証明できているのは、
このMac・このNURO MAP-E環境・このNordLynx実装において、NordLynx内側MTU 1420ではパケットサイズ依存の通信障害が発生し、1392以下へ縮小すると解消する。
という点である。
原因モデルとしては、NordLynx/WireGuardとMAP-Eによる多重カプセル化の結果、実経路に対して既定MTUが過大となり、PMTUDまたはフラグメンテーション処理が期待通り成立せずパケットブラックホールが発生している、という説明が最も観測事実と整合する。
次の段階は、NordLynx接続時にMTU 1390を安全かつ自動的に適用する恒久回避策の実装と、物理側1392/1393比較およびICMPv6 Packet Too Big観測による原因モデルの最終確認である。
NURO 光, IPv6アドレス対応およびMAP-E方式について, https://www.nuro.jp/ipv6.html↩︎
IETF / RFC Editor, RFC 7597, Mapping of Address and Port with Encapsulation (MAP-E), https://www.rfc-editor.org/rfc/rfc7597.html↩︎↩︎
NordVPN Support, What is NordLynx, https://support.nordvpn.com/hc/en-us/articles/19564565879441↩︎↩︎