VPNピアが他のインターフェースにpingできるのはローカルだから
ローカルルーティングテーブルは、ホストが持つあらゆるアドレス宛のパケットを、どのインターフェース上にあっても送り届ける。転送設定はその経路に関与しない。
WireGuardクライアントが接続し、まったく別のインターフェース上のアドレスにpingすると、応答が返る。キャプチャには要求がトンネル上にしか現れない。壊れているものは何もなく、慎重に無効化した転送設定はこれと無関係だ。これは、図では似て見え、カーネル内ではまったく異なる二つの経路の比較である。
一方の経路は他人のためにパケットを転送し、もう一方はホスト自身に届ける。
ホスト宛のパケットはホスト内にとどまる
リモートクライアントは、ホストが持つアドレスにIPパケットを送る。ルーティングはそのパケットについて一つの問いを立てる。この宛先はローカルか。ホストが持つすべてのアドレスはローカルルーティングテーブルに現れ、そのテーブルはメインテーブルより先に参照されるので、パケットは別のインターフェースから出るのではなくホスト自身のスタックへ進む。応答はローカルで生成され、問い合わせがそこから来たためトンネルを通って戻る。
これが仕組みのすべてだ。転送は起こらず、インターフェース状態の変化も関与せず、問題のアドレスはどこか他の場所から到達可能である必要もない。
ip_forward が適用されない理由
転送は、到着したインターフェースとは別のインターフェースから出ていくパケットを扱う。ホスト自身へのpingはその経路を決して通らない。パケットはローカルで消費され、応答もローカルで生成される。したがって net.ipv4.ip_forward=0 を設定してもここでは何も変わらず、転送チェーンのルールがそのトラフィックを見ることもない。正しい制御は入力経路にあり、受信インターフェースや送信元で絞り込む。
だからこそ、転送を無効にしたうえでホストが隔離されているとみなすのは、誤った安心感を生む。
判断したローカルテーブルを読む
ip rule show は通常、優先度ゼロのルールですべての検索をまずローカルテーブルへ送ることを報告し、ip route show table local はホスト自身のアドレスをローカルスコープで一覧表示する。そのテーブルには、管理上ダウンしているが設定は残っているインターフェースのアドレスも含まれる。静的に割り当てられたIPv4アドレスは通常リンク断を生き延びるため、落ちたブリッジへのpingが依然として成功し、運用者を驚かせることがある。
IPv6はまさにこの点で異なる。リンクが落ちると、そのアドレスは通常取り下げられる。ただし keep_addr_on_down が設定されている場合は別だ。一つのルールが両方をカバーすると仮定せず、両者を比較してほしい。
ピアが実際に到達できるもの
セグメント上のルーター自身のアドレスからの応答は、そのセグメントの背後のマシンについて何も語らない。ピアはこの経路で別のインターフェースの背後のホストには到達できず、ルーター自身が持つアドレスにしか到達しない。ルーターのアドレスにpingするのではなく、別のLANホスト上のサービスを試すことが、転送がそもそも許可されているかを確かめる方法だ。
ピアをトンネルアドレスに束縛されたサービスに限定するのは入力ポリシーの問題である。望むサービスをトンネルインターフェースで許可し、それを使える送信元を制限する。パケットは実際にそこへ届くからだ。
廃止するつもりのアドレスも確認してほしい。インターフェースからアドレスを外すほうが、古いアドレスの上にファイアウォールルールを積み重ねるより確実だ。