要求はマシンを離れ、VPN ピアは応答し、その応答がソケットに届かない。トンネルは上がっており、ピアのログにはパケットの送信が記録され、アプリケーション側には沈黙を説明するものが何もない。Linux では、よくある容疑者の一つが逆経路フィルタリングである。送信元検証が、カーネルがその送信元に期待するルートと一致しない場合、受信した IPv4 パケットは拒否されうる。順に追っていけば、それが原因なのか偶然なのかが分かる。また、欠けたルートを直すためにセキュリティ制御を切ることも防げる。

送信元検証が決めていること

カーネルは、パケットの送信元アドレスが、それが到着したインターフェースにとって妥当かどうかを、その送信元への戻りルートをルーティングテーブルに問い合わせて調べる。逆ルートが別の場所を指していれば、ファイアウォール規則やアプリケーションのソケットが見る前にパケットは破棄されうる。この検査は特定の偽装パターンを難しくするためにあり、非対称な設計やポリシールーティングの設計がこれに当たる一方で、同じネットワーク上の普通のクライアントは問題なく動くのはそのためである。普通のクライアントは対称なルーティングを持ち、検査が前提にしているのはまさにそれである。

重要なのは「妥当」という語である。パケットは完全に正当でありながら検査に落ちることがある。検査しているのは正当性ではないからだ。

有効なモードを読む、一つのフィールドではなく

モードは三つある。無効、厳格、緩和である。厳格は緩和とは異なるルートの期待を課し、グローバル設定はインターフェースごとの設定と相互作用するため、一つのファイルを読むと実際に有効な内容を誤って説明しうる。両方を読み、しかも応答を受け取るインターフェースで読むべきで、デフォルトルートのインターフェースではない。

sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.<iface>.rp_filter
ip route get <source-of-the-reply>

三行目のルート検索こそ、人が飛ばす部分である。それはカーネルが送信元について何を信じているかを示し、まさに検査の入力になる。

検査を変える前に食い違いを見つける

応答がなぜそのインターフェースに来るのか、その逆ルートが異なるべきなのかを突き止める。要求を一方の経路で送り、応答を他方で返すポリシー規則は正当な設計だ。その設計を厳格な検証は拒否し、ポリシールーティングで使うマークも、逆引きが返すものを変えるため、ここで効いてくる。

逆ルートが単に欠けているなら、検査を切るのではなく、それを追加すれば原因が直る。欠けたルート、ファイアウォールによる拒否、誤ったトラフィックセレクタはどれも同じ目に見える症状を生み、そのうち送信元検証に関わるのは一つだけである。

最初の反応として送信元検査を全体で切ってはいけない。それは具体的な診断を、後で覚えておかねばならない広い挙動変更と引き換えにする。

弁護できる選択的な調整

狭い調整が本当に必要な場合は、それを必要とするインターフェースに限定し、理由を書き留め、再起動後も残るようそのインターフェースを所有する設定に置く。そのうえで、失敗したまさにその流れを、同じ送信元から同じ宛先へ再試験する。都合のよい何かへの ping ではない。

それでも拒否されるべきケースを含める。そのケースが今通るなら、調整は直そうとした一つの経路以上に弱めたことになる。

IPv4 と IPv6 を分けて考える

見慣れた sysctl は、すべてのアドレスファミリーに対する方針ではない。IPv6 には独自の挙動と独自の設定があり、特定の宛先が失敗するまで誰も気づかないまま、一方のファミリーで厳格、他方で緩いという状態になりうる。ワークロードが両方を使うなら両方を確認する。

モード、インターフェース、ルート検索の出力、変更の理由を一か所に記録する。次に来る人は設定だけを見つけて説明を見つけず、それを削除するか、本来属さない場所へコピーする。

関連記事