「WireGuard がつながらない」とき、原因は鍵の不一致とは限らない。2026年10月、私は端末の QR コードを再発行した直後に、端末で WireGuard をオンにするとインターネットに出られなくなる事象に遭遇した。トンネル自体は張れているのに、通信だけが通らない。結論から書くと、原因は経路 MTU の不一致であり、ingress gateway 側の MTU を 1420 から 1280 へ下げ、端末が受け取る設定ファイルの MTU を 1280 に揃えることで解消した。本稿はその切り分け手順、実測で確定した値、そして再発させないための監視設計をまとめる。
WireGuard とは — UDP 上で動く軽量な VPN
WireGuard は、暗号化されたトンネルを UDP 上で作る VPN プロトコルである。IPsec や OpenVPN に比べて実装が小さく、設定項目も「秘密鍵・公開鍵・相手の公開鍵・AllowedIPs」程度に絞られている。Linux カーネルに取り込まれているため、ユーザー空間の追加デーモンを必要としない構成も多い。モバイル端末向けの公式アプリも提供されており、QR コードを読み込むだけでプロファイルを登録できる(WireGuard 公式サイト / 2026-10-25 参照)。プロトコルの成り立ちや設計思想は WireGuard とは — UDP 上で動く軽量な VPN の仕組みと、つまずきやすい3点 にまとめた。
この「設定が少ない」という長所が、切り分けの場面では短所に転じる。設定項目が少ないぶん、症状から原因を推定する手がかりも少ない。TCP のように「接続が成立したか」を明示的に知らせる手続きがなく、UDP は送りっぱなしである。届かなかったことも分からない。だからこそ、どの層をどの順で測るかを先に決めておく必要がある。
WireGuard がつながらないときに最初に見るべき3点
WireGuard は UDP 上で動作する VPN であり、TCP のように「接続を確立する」手続きを持たない。この性質が、切り分けを難しくする。TCP であれば接続そのものが失敗するので、どこで止まったかが比較的はっきりする。UDP では送りっぱなしであり、届かなかったことも分からない。そのため「つながらない」という一語に、性質の異なる複数の故障が混ざる。
私は切り分けの層を次の3つに固定している。
第一層は鍵とピア設定である。公開鍵の取り違え、事前共有鍵の不一致、AllowedIPs の範囲誤り、サーバ側へのピア登録漏れ。これらはハンドシェイクが成立しないため、wg show の latest handshake が更新されないことで判別できる。
第二層はエンドポイント到達性である。UDP の待ち受けポートに届いているか、NAT やファイアウォールで落ちていないか。ハンドシェイクが成立しない場合はここも疑う。WireGuard は UDP であるため、TCP のポート開放テストだけでは判定できない。
第三層は経路 MTU である。ここが最も見落とされる。ハンドシェイクは成立し、小さいパケットは通る。しかし大きいパケットだけが静かに消える。ping は通るのに Web サイトが開かない、SSH は繋がるのにファイル転送で止まる、といった非対称な症状になる。
この3層を区別せず「つながらない」と一括りにすると、鍵を疑って設定を作り直す作業を延々と繰り返すことになる。私が遭遇したのは第三層だった。そして第三層は、鍵をいくら作り直しても直らない。
事象 — QR 再発行後に WireGuard をオンにするとインターネットに出られない
2026年10月24日、利用者の端末(Pixel11)で WireGuard をオンにすると、インターネットに接続できなくなった。直前に行っていた作業は、Netmaker 上の ext client に対する QR コードの再発行である。
ここで Netmaker について補足する。Netmaker は、WireGuard を土台にしたオーバーレイネットワークの管理ソフトウェアである。WireGuard 単体では、端末ごとに鍵を生成し、サーバ側の設定ファイルへ1台ずつピアを登録する作業が必要になる。Netmaker はその管理を肩代わりし、サーバ(ingress gateway)と端末(ext client)の鍵・アドレス・経路を一元管理して、端末向けの設定ファイルや QR コードを生成する。多数の端末を同じ仮想ネットワークに収容する用途で使われる(Netmaker 公式サイト / 2026-10-25 参照)。Tailscale との違いやオンプレミス運用での位置づけは Netmaker とは — Tailscale のオンプレミス代替として何ができ、何が足りないか に整理した。
時系列だけを見ると「QR を読み込んだら繋がらなくなった」ので、鍵か設定の問題に見える。実際、私も最初はそう疑った。
しかし実測すると、別の姿が見えてきた。まず端末の到達性を起点ホスト(broker)から確認したところ、次の結果になった。
| 測定項目 | 起点 | 実測結果 |
|---|---|---|
| ICMP(小さいパケット) | broker | 応答なし(ICMP_SMALL=0) |
| TCP 8006(Proxmox GUI) | broker | 到達(HTTP 200) |
| UDP 送信 | broker | 送信成功(UDP_SEND_OK) |
ICMP が返らず、TCP は通る。この組み合わせは、単純な経路断でもポート閉塞でも説明がつかない。さらに、当該時刻の端末は WireGuard を意図的にオフにしていた。つまりこの測定は「トンネルが張られていない状態」を測っていた。プローブの判定は VERDICT=WG_OFF_OR_PATH_DOWN(WireGuard オフ、または経路断)であり、この時点では通信断の再発を意味しない。
ここで重要なのは、判定を「再発した/していない」の二値で扱わないことだ。プローブが返した分類は、そのままでは原因を特定しない。分類ごとに次の一手が変わる、という形で使う。
原因の切り分け — ICMP と TCP で違う結果が出たら経路の MTU を疑う
MTU の問題は、症状が非対称になる。これを理解するには、パケットが経路上でどう扱われるかを押さえる必要がある。
IPv4 のパケットには、分割を許可するかどうかを示す DF(Don’t Fragment)ビットがある。DF が立っているパケットが、経路の途中で MTU を超える大きさだった場合、ルータはそのパケットを破棄し、送信元へ ICMP Fragmentation Needed(Type 3 / Code 4)を返す。送信元はそれを受けて、以後のパケットサイズを小さくする。これが経路 MTU 探索(PMTUD)である。
問題は、この ICMP が返ってこない経路が現実に存在することだ。ファイアウォールが ICMP を落とす設定になっている、NAT が ICMP を正しく転送しない、といった環境では、破棄されたことが送信元に伝わらない。送信元は同じ大きさのパケットを再送し続け、通信は「張れているのに進まない」状態になる。これが PMTU ブラックホールである。
切り分けの実務では、次の順で見る。
- 小さいパケットが通るかを確認する。
ping -s 64程度で応答があれば、経路そのものは生きている。 - 大きいパケットを通してみる。
ping -s 1472 -M do(DF 付き)で落ちるなら、その経路の MTU は 1500 未満である。 - 境界を二分探索する。
-s 1400が通り-s 1450が落ちるなら、経路 MTU は 1428〜1478 の間にある。 - TCP は通るがアプリケーションが固まる場合、MSS クランプが効いているかを確認する。
私の環境では、10GbE 側の経路(MTU 9000)と 1GbE 側の経路(MTU 1500)が混在しており、経路上のどこかで 1500 を超えるパケットが通らない区間があった。WireGuard のトンネル内 MTU が 1420 のまま、その外側の経路がより小さい MTU しか通さない状態になると、ちょうどこのブラックホールに落ちる。
MTU 1420 と 1280 — WireGuard のトンネルで使える MTU の決まり方
WireGuard は UDP でカプセル化する。したがって、トンネル内で使える MTU は、物理経路の MTU から WireGuard のヘッダ分を差し引いた値になる。IPv4 のオーバーヘッドは 60 バイト、IPv6 では 80 バイトとされる。経路 MTU が 1500 の IPv4 なら 1440、IPv6 なら 1420 が上限の目安になる。
1420 という値は、IPv6 を前提にした控えめな既定値として広く使われている。実際、Netmaker の ext client 生成コードでも既定値は 1420 である。しかし、この 1420 が常に安全とは限らない。経路上に PPPoE(MTU 1492)やモバイル回線のように MTU の小さい区間が挟まると、1420 でも超過する場合がある。
1280 は IPv6 の最小 MTU として規定された値である(RFC 8200 / 2026-10-25 参照)。IPv6 では経路途中での分割を原則行わないため、最小 MTU を 1280 と定め、すべてのノードがそれを通せることを要求している。逆に言えば、1280 以下にしておけば、IPv6 の要件を満たす経路では必ず通る。これが「困ったら 1280」と言われる理由である。
ただし 1280 に下げると、スループットは確実に落ちる。1 パケットあたりのペイロードが減るため、同じデータ量を運ぶのに必要なパケット数が増えるからだ。1420 で通るなら 1420 のほうが速い。だから「常に 1280」ではなく、「通らないなら 1280 まで下げる」という順序で考えるのが正しい。
Netmaker の ext client は host の MTU を継承する(実測)
ここで効いてくるのが、Netmaker における MTU の継承規則である。私はこれを推測せず、上流のソースコードを実測で確認した。
upstream_v1.7.0/controllers/ext_client.go:371-373
defaultMTU := 1420
if host.MTU != 0 { defaultMTU = host.MTU }
... MTU = %d
この4行が示すのは明快である。ext client の設定ファイルに書き込まれる MTU は、所属する ingress gateway ホストの MTU フィールドを継承する。host.MTU が 0 のときだけ既定の 1420 が使われる。つまり、個々のクライアント設定を書き換えるのではなく、ホスト側の 1 項目を変えれば、配下の ext client すべてに反映される。
実際に変更前後を実測した結果が次の表である。
| # | 測定内容 | 変更前 | 変更後 |
|---|---|---|---|
| 1 | ingress gw host の mtu |
1420 | 1280 |
| 2 | host listenport |
443 | 443(不変) |
| 3 | host wg_public_listen_port |
443 | 443(不変) |
| 4 | host endpointip |
133.242.153.63 | 同一(不変) |
| 5 | ext client 件数(対象ネットワーク全体) | — | 1件(影響範囲は限定的) |
| 6 | ext client レコードの mtu |
null | null(=host 継承) |
| 7 | 生成 conf の MTU |
1420 | 1280 |
| 8 | gateway node の ingressmtu |
— | 1280 |
| 9 | gateway node の connected |
— | true(生存) |
注目すべきは #2〜#4 である。host レコードを PUT で更新すると、サーバ側が計算するフィールド(listenport など)が一時的にリセットされる挙動が過去に観測されていた。今回は isstaticport=true のため再計算され、443 のまま維持された。過渡的な不通も観測されていない。ただしこれは環境依存であり、更新後は必ず読み戻して確認するべき項目である。
復旧手順 — ingress gateway の MTU を 1280 へ変える
実際の手順は単純である。ただし、可逆性を担保してから実行する。
まず変更前の状態を丸ごと退避する。host レコードと hosts 一覧の JSON を取得し、タイムスタンプ付きで保存する。これは「戻せない変更をしない」ための最低条件である。
次に host の mtu だけを 1280 に更新する。API への PUT は 1 回で済む。更新後、次の4点を読み戻して確認する。mtu が 1280 になったこと、listenport と wg_public_listen_port が 443 のままであること、endpointip が変わっていないこと、ext client の生成 conf の MTU が 1280 になっていること。
撤回は 1 コマンドで済む。退避した JSON を使って mtu を 1420 に戻す PUT を 1 回実行するだけだ。可逆であることが明確であれば、この種の変更は承認を得たうえで速やかに実行してよい。逆に、可逆性が担保できない変更は、たとえ 1 項目でも実行すべきではない。
ここで注意すべきは、サーバ側の設定変更が端末側に自動反映されない場合があるという点である。
端末側に残る古い conf という落とし穴
サーバ側で生成される conf が 1280 になっても、すでに端末へ配布済みの QR コードや設定ファイルは 1420 のまま残る。端末が古い設定を使い続ける限り、端末側のトンネル MTU は 1420 である。サーバ側だけ直して「直った」と判断すると、この差分を見落とす。
したがって復旧手順には、必ず「端末側の設定を再取得するか」の判断を含める。判断基準は次のとおりである。
- 端末がすでに 1280 相当で安定しているなら、再配布は急がない。実際、私の環境では下流側の実 MTU が 1200 で設定が 1280 という安全側の状態にあり、直ちに再配布しないと困る状況ではなかった。
- 端末側で再現するなら、QR を再発行して再インポートする。このとき、古いプロファイルを削除してから読み込む。同名プロファイルが残っていると、どちらが有効か分からなくなる。
- 再配布した日時と MTU を記録に残す。後から「いつ何を配ったか」を追えなくなるのを防ぐためである。
設定ファイルの配布は、変更そのものより事故が起きやすい工程である。サーバ側の変更記録と、端末側の配布記録を分けて残すのがよい。
WireGuard の MTU 問題を再発させないための監視
同じ事象を二度起こさないためには、症状ではなく判定を自動化する。私は到達性プローブを作り、結果を4つの判定に分類する形にした。
| 判定 | 条件 | 意味と次の一手 |
|---|---|---|
WG_OFF_OR_PATH_DOWN |
ICMP 応答なし | 意図的なオフか経路断。端末の状態を先に確認する |
PMTU_BLACKHOLE |
小さい ICMP は通るが大きい ICMP が落ちる | MTU 起因。トンネル MTU を下げる |
APP_DOWN_8006 |
ICMP は通るがアプリケーションポートが閉じている | サービス側の異常。MTU ではない |
OK |
すべて通る | 正常 |
この分類の価値は、判定ごとに「次に何をするか」が一意に決まる点にある。単に「疎通あり/なし」を返すプローブでは、次に何をすればよいかが分からない。監視は状態を可視化するだけでなく、行動を指定できる形にするのが望ましい。
併せて、MTU の設定値そのものを監視対象にする。サーバ側の生成 conf の MTU と、端末が実際に使っている MTU が一致しているかを定期的に確認できれば、「片方だけ直した」状態を検出できる。設定のドリフト検知は、監視ルールのドリフト検知と同じ発想である(監視ルールのドリフト検知 — Prometheus の配備漏れを機械的に検知する)。
ネットワーク機器の設定は、変更した瞬間は正しくても、時間とともに周辺の前提が変わる。MTU は特にその影響を受けやすい。経路が変われば最適値も変わるからだ。
まとめ — WireGuard の MTU がずれると「鍵は正しいのに通信が止まる」
本稿の内容を、実務で使える形に整理する。
- WireGuard がつながらないときは、鍵・エンドポイント到達性・経路 MTU の3層に分けて切り分ける。
- ハンドシェイクが成立しているのに通信が止まるなら、MTU を疑う。ICMP が通るか、大きいパケットが通るかを分けて測る。
- WireGuard のトンネル MTU は、経路 MTU からヘッダ分(IPv4 で 60 バイト、IPv6 で 80 バイト)を引いた値が上限の目安になる。
- 1420 で通らない場合の受け皿として 1280 がある。1280 は IPv6 の最小 MTU であり、これを下回る経路は実質的に存在しない。
- Netmaker では ext client の MTU は ingress gateway ホストの MTU を継承する。ホスト側 1 項目の変更で配下に反映される(上流コードの実測で確認)。
- サーバ側を直しても、端末に配布済みの conf は古いまま残る。再配布の要否を必ず判断する。
- 変更は 1 項目でも退避してから行い、読み戻しで確認する。撤回手段を 1 コマンドで用意できることが、速く動くための条件になる。
「QR を読み込んだら繋がらなくなった」という報告は、鍵の問題に見える。しかし実際には、鍵は正しく、経路の MTU が合っていなかった。症状から原因を推測するのではなく、層に分けて実測する。遠回りに見えて、これが最も速い。
参照した一次情報:
- WireGuard 公式サイト(プロトコルと実装)https://www.wireguard.com/ (2026-10-25 参照)
- Netmaker 公式サイト https://www.netmaker.io/ (2026-10-25 参照)
- RFC 8200「Internet Protocol, Version 6 (IPv6) Specification」(IPv6 最小 MTU 1280)https://www.rfc-editor.org/rfc/rfc8200 (2026-10-25 参照)
- 関連記事: Meta Quest 3 と Windows 11 のリンクが不安定だったので、Virtual Desktop と有線LAN化で組み直した
- 関連記事: Proxmox の vzdump が監視を誤爆させていた — ZFS スナップショットと sanoid でバックアップを分ける
