2026年6月4日
2026年6月4日
WireGuardの切断対策手順|つながらなくなる原因の切り分けと再発防止
WireGuardが「しばらくすると切れる」「つながっているのに通信が止まる」場合、原因の多くはNATやファイアウォールの無通信タイムアウト、接続先IPアドレスの変化、MTUの不一致のいずれかです。まず wg show でハンドシェイクが続いているかを確認し、症状に合わせて PersistentKeepalive、エンドポイントの再解決、MTUの調整を行います。この記事では、切断の見分け方、原因の多い順の確認と直し方、再発を防ぐ監視の方法を説明します。
WireGuardの「切断」を正しく理解する
WireGuardには、OpenVPNのような「接続中」「切断」という状態がありません。通信が必要になったときに鍵交換(ハンドシェイク)を行い、通信が続いている間はおよそ2分ごとに鍵を更新します。通信が無ければ、何も送りません。
そのため「切断」として見えている現象は、実際には次のどれかです。
- ハンドシェイクが成立しなくなった(相手に届かない、応答が返らない)
- ハンドシェイクは成立しているが、データの一部が届かない(MTUや経路の問題)
- そもそもインターフェースが起動していない(再起動後に上がっていない)
どれに当たるかで対策が変わるので、最初に状態を確認します。
まず状態を確認する
# インターフェースとピアの状態
sudo wg show
# ピアごとの最後のハンドシェイク時刻(UNIX時間)
sudo wg show wg0 latest-handshakes
wg show の出力で見るべき項目は次のとおりです。
- latest handshake: 最後に鍵交換が成立した時刻です。通信しているのに数分以上前のままなら、ハンドシェイクが失敗しています。一度も表示されない場合は、最初から相手に届いていません
- transfer: 送受信の量です。送信だけが増えて受信が増えない場合、パケットが相手に届いていないか、相手の返信が戻ってきていません
- endpoint: 相手の実際のIPアドレスとポートです。想定と違うアドレスになっていないかを見ます
あわせて、パケットがサーバーまで届いているかをパケットキャプチャで確認します。
# サーバー側で、WireGuardのポートにUDPが届いているか(ポート番号は設定に合わせる)
sudo tcpdump -ni any udp port 51820
クライアントから通信したときに何も表示されなければ、途中(ファイアウォール、ルーター、クラウドのセキュリティグループ)で止まっています。
原因と対策(多い順)
1. NATやファイアウォールの無通信タイムアウト
もっとも多い原因です。家庭用ルーターやモバイル回線のNATは、一定時間通信が無いUDPの対応表を消します。すると、サーバー側から送ろうとしても届かなくなり、「しばらく放置すると切れる」「サーバーからクライアントへの通信だけできない」という症状になります。
対策は、NATの内側にいる側のピア設定に PersistentKeepalive を入れることです。指定した秒数ごとに小さなパケットを送り、NATの対応表を保ちます。
[Peer]
PublicKey = your-server-public-key
Endpoint = vpn.example.com:51820
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25
25秒は、多くのNATのタイムアウトより短い値として広く使われています。両側がNATの内側にない構成(両方に固定のグローバルアドレスがある)では、通常は不要です。
2. 接続先のIPアドレスが変わった
Endpoint にホスト名を書いても、WireGuardが名前解決するのは設定を読み込んだときだけです。ダイナミックDNSで運用しているサーバーのIPアドレスが変わると、クライアントは古いアドレスに送り続けます。
対処法は次のいずれかです。
- インターフェースを再起動して名前を引き直す(
sudo systemctl restart wg-quick@wg0) - wireguard-toolsの配布物に含まれる
reresolve-dns.shのようなスクリプトを定期実行する(パッケージによって同梱場所が異なります) wg setで新しいエンドポイントを直接設定する
sudo wg set wg0 peer your-server-public-key endpoint vpn.example.com:51820
なお、固定アドレスを持つ側は、相手のアドレスが変わっても受け取ったパケットから新しいアドレスを学習します(ローミング)。問題になるのは、アドレスが変わった側に向けて送る場合です。
3. MTUが合っていない
「pingは通るのに、Webページの表示やファイル転送、SSHの画面表示の途中で止まる」なら、MTUを疑います。WireGuardは元のパケットにヘッダーを付けて送るため、経路のMTUより大きなパケットが落とされると、大きなデータだけが届かなくなります。
wg-quickは経路から自動でMTUを決めますが、PPPoE回線やトンネルの多重化、IPv6経由の接続では大きすぎることがあります。トンネル内でサイズを変えながら確認します。
# 断片化を禁止してサイズを指定(1372 + ヘッダー28 = 1400バイト)
ping -M do -s 1372 -c 3 10.8.0.1
通らないサイズが見つかったら、インターフェースの設定でMTUを下げます。
[Interface]
MTU = 1380
値は環境によって違うため、確認しながら決めます。サーバーがクライアントの通信をインターネットへ中継している場合は、TCPのMSSを経路に合わせて調整するファイアウォール設定(MSSクランプ)もあわせて検討します。
4. ファイアウォールやセキュリティグループ
サーバー側でWireGuardのUDPポートが許可されているかを確認します。ufwとクラウドのセキュリティグループ(またはVPS事業者のパケットフィルター)の両方で許可が必要です。ListenPort を指定していないと、起動のたびにポートが変わることがあるため、サーバー側では明示的に指定します。
sudo ufw allow 51820/udp
sudo ss -ulnp | grep 51820
5. 再起動後にインターフェースが上がっていない
サーバーやクライアントを再起動したあとにつながらない場合は、自動起動の設定を確認します。
sudo systemctl enable --now wg-quick@wg0
systemctl status wg-quick@wg0
6. AllowedIPsの重複や経路の衝突
複数のピアに同じ AllowedIPs を書くと、後から設定したピアにだけ通信が向かい、もう一方が「切れた」ように見えます。また、トンネルのアドレス帯が、接続先の拠点やカフェのWi-Fiのアドレス帯と重なっていると、経路が衝突します。ip route でトンネル向けの経路を確認し、重ならないアドレス帯を選びます。
7. 時刻が大きく戻った
WireGuardは、古いハンドシェイクの使い回しを防ぐために時刻情報を使います。時計の無い小型機器などで、再起動後に時刻が過去に戻ったままハンドシェイクを試みると、相手に拒否されることがあります。NTPで時刻が合ってから起動する順番にするか、相手側のインターフェースを再起動すると解消します。
再発を防ぐ監視
最後のハンドシェイクからの経過時間を定期的に確認すると、利用者から連絡が来る前に異常に気付けます。
#!/bin/sh
# 最後のハンドシェイクから300秒以上経ったピアを表示する
now=$(date +%s)
wg show wg0 latest-handshakes | while read -r key ts; do
if [ "$ts" -eq 0 ] || [ $((now - ts)) -gt 300 ]; then
echo "stale peer: $key"
fi
done
PersistentKeepalive を入れていないピアは、通信が無いとハンドシェイクも行われないため、この確認では「古い」と表示されます。監視の対象は、キープアライブを設定したピアに絞ります。設定ファイルの変更前には、現在の /etc/wireguard/ をバックアップし、リモートのサーバーを操作する場合はVPNを経由しない管理経路(コンソールなど)を確保してから作業します。各OSのパッケージやクライアントアプリの画面は更新で変わることがあるため、細部は公式の説明を確認してください(2026年10月現在)。
まとめ
- WireGuardに接続状態は無いので、
wg showのハンドシェイク時刻と送受信量で状態を判断する - 放置すると切れるならNATのタイムアウト。NAT側のピアに
PersistentKeepalive = 25 - IPアドレスが変わるサーバーは、エンドポイントの再解決を定期実行する
- 小さな通信だけ通るならMTU。
ping -M doで確認して下げる - ファイアウォール、自動起動、AllowedIPsの重複、時刻も順に確認し、ハンドシェイクの経過時間を監視する