トンネルは上がっており、ハンドシェイクは 二分ごとに起こり、向こう側ではちょうど 一つのアドレスだけが応答する。ピアのトンネルアドレスへの ping は通るが、その先は何も通らない。誰かがインターフェース設定を読み、ホストプレフィックスを見て、マスクが間違っていると結論する。/24 に広げると ping はしばらく直り、その後で別の何かが壊れる。プレフィックスは原因ではなかったし、欠けていた経路はマスクが制御する経路ではない。

インターフェースプレフィックスが実際に作るもの

Linux では、インターフェースにアドレスを割り当てると、そのプレフィックスの接続経路が作られる。ホストプレフィックスを割り当てれば、接続経路は 一つのアドレスだけをカバーする。/24 を割り当てれば 256 をカバーし、そのすべてがそのリンク経由で到達可能とみなされる。

ip -4 addr show dev wg0
ip -4 route show dev wg0
ip route get 10.80.7.1

ホストプレフィックスはポイントツーポイントのトンネルではまったく普通の選択だ。向こう側にはちょうど 一つのピアしかないからだ。三つ目のコマンドがユーザーの疑問に答える。その宛先にカーネルがどのインターフェースを使うかを示し、どの経路も一致しなければ役立つものは何も表示しない。

これが症状のすべての説明だ。一つのアドレスが応答するのは、そのアドレスの接続経路が存在するから、あるいはピアの許可リストに偶然含まれているからだ。それ以外には経路がなく、WireGuard が関与する前に捨てられる。トンネル自体は一貫して健全であり、だからこそ ハンドシェイクカウンターは安心感のある表示を続ける。

AllowedIPs は 一つの名前を持つ 二つの規則

WireGuard のピアごとの許可リストは同時に 二つの仕事をしており、設定構文のために 一つに見える。受信側では、ピアが提示してよい送信元アドレスを許可する。送信側では、最も具体的な一致を見つけて、パケットをどのピアへ送るかを選ぶ。

どちらの仕事もルーティングではない。カーネルは、WireGuard がパケットを見る前に、そのパケットがトンネルインターフェースに属すると判断しなければならず、その判断はルーティングテーブルから来る。広い許可リストを持つピアエントリは それ自体では経路をインストールしない。

だから設定が完全に見えても非対称に振る舞うことがある。経路があるのでクライアントは向こう側へ送るが、向こう側の許可リストがクライアントの送信元を許可していない、あるいは向こう側に戻り経路がないため、応答は決して届かない。両方向は別々の判断であり、失敗の仕方も別々だ。どちらを試しているかを書き留めることが診断の半分になる。

経路はどこから来るのか

wg-quick を使う場合、経路は各ピアの許可リストから自動で生成される。ただし Table = off を設定して自分で管理を引き受けた場合は別だ。これはツールが文書化している動作であり、明示的な経路指定がない設定でも動く理由でもある。

sudo wg show wg0 allowed-ips
ip route show | grep wg0
sudo wg-quick strip wg0

許可リストと、実際に存在する経路を比べる。サブネット全体を許可しているのにホスト経路しか作られていないなら、ヘルパーが一度も走っていないか、wg と ip でインターフェースを直接管理しているかのどちらかで、その場合は経路を作るものが何もない。

手動で管理する場合、経路は 一行で、形は明示的だ。宛先をインターフェース経由で、リンクがポイントツーポイントなのでゲートウェイはない。これを足すのは悪いプレフィックスの回避策ではなく、ルーティングを自分で持つと決めた設計の欠けていた半分だ。

プレフィックスを広げてもピアエントリは増えない

誘惑される修正は、アドレスを /24 に変えて接続経路がサーバーの LAN をカバーするようにすることだ。動いたように見えるが、動いたように見える理由は接続経路が一致するようになったからで、WireGuard が何かを新しく学んだからではない。

さらに、その範囲全体をそのリンク経由で直接到達可能だと主張したことになる。他のピアに属するアドレスや、実際にはサーバーの背後にある LAN のアドレスも含まれる。それらのアドレスへの通信はトンネルに入るようになり、向こう側から出るかどうかはサーバー自身のルーティングと許可リスト次第だ。

暗号の側はどちらの場合も影響を受けない。WireGuard はピアを選ぶために宛先をカバーする許可リストのエントリを依然として必要とし、向こう側はあなたの送信元をカバーするエントリを依然として必要とする。広いインターフェースプレフィックスはどちらも提供できない。

何かを変える前に両方向を確認する

両端を別々に扱い、それぞれが何を言っているかを書き留める。クライアント側は経路とピアエントリ、サーバー側は鏡像と自身の戻り経路だ。

ip route get 192.168.70.20
sudo wg show wg0 allowed-ips
sudo wg show wg0 latest-handshakes
sudo tcpdump -ni wg0 -c 10

方向についての議論を決着させるのはキャプチャだ。外向きのパケットがトンネルインターフェースに現れ、サーバーが何も記録しないなら、遠端が拒否している。多くは送信元がその許可リストの外にあるためだ。何も現れないなら、経路がないか別の場所を指している。

そのうえで狭い側を直す。サーバー側でクライアントのアドレスに対する許可リストのエントリ、クライアント側で宛先サブネットに対するエントリ、これが通常の形で、インターフェースプレフィックスには触れない。プレフィックスを広げるのは、アドレス計画が本当にそのリンクで共有サブネットを望むときだけにし、デバッグの手順ではなく計画の変更として行う。

関連記事