OpenWrtポリシールーティング:ローカルDNSを捕まえるチェーン
クライアントの問い合わせとルーター自身の問い合わせは別のフックから入ります。prerouting を狙ったポリシーはすべての LAN クエリを運び、ルーターを ISP のアップリンクに残します。
LAN のクライアントはトンネル経由で解決し、ルーター自身の問い合わせは静かにそうしません。 パッケージ更新、時刻同期、動的 DNS はどれも通常のアップリンクから出る一方、転送された問い合わせはすべて VPN を通り、インターフェースには二つの異なる経路があることを示すものは何もありません。 説明はポリシーのバグではなく、どのフックがパケットを見るかという問題です。 二つのフロー、一つのリゾルバーアドレス、そしてルーターを越えるのはそのうち片方だけです。 両者を切り分けることが修正のすべてです。
二つのフロー、一つのリゾルバーアドレス
最初のフローは人が思い描くものです。 クライアントがルーターのリゾルバーに問い合わせ、リゾルバーが上流へ転送し、その転送されたパケットが外向きにルーターを通ります。 そのパケットは転送トラフィックを監視するあらゆるものから見えます。
二番目のフローはどこからも到着しません。 ルーターが生成するので、受信パケットも照合すべき転送ステップも存在しません。
どちらも同じリゾルバーアドレスを狙うことがあり、だからこそ違いを見落としやすいのです。 同じ宛先、異なる起点、異なるチェーン。 起点が見えれば、残りの診断は自然に続きます。
転送パケットとローカル生成パケットは入り方が違う
転送トラフィックは別のインターフェースから到着したときに評価されます。 ポリシールーティングのパッケージはそれを prerouting チェーンとして露出し、そこに置かれたルールはルーターを越えるすべてのパケットを見ます。 だからクライアントの問い合わせはポリシーの記述どおりに振る舞い、だからルーターはそれを無視します。 ルールが間違っているのではなく、ルーターが決して到達しないフックに付いているだけです。 移動すれば、同じマッチが機能し始めます。
ローカル生成トラフィックはルーター上のプロセスによって作られ、代わりに出力パスに入ります。 ルーター自身の判断でルーティングされ、ポリシーがそのチェーンを覆っている場合にだけポリシーに出会います。 照合する受信インターフェースも、観察する転送判断もありません。
これはパケットがどこで生まれるかの性質であり、特定のパッケージの性質ではありません。 一方のチェーン用に書かれたルールは、もう一方について何の意見も持ちません。 どんなにルールを調整してもそれは変わりません。
出力チェーンを選び、次にマッチを絞る
修正は同じ意図を出力チェーンにも付けること、あるいはルーター自身の問い合わせが重要ならルールをそこへ移すことです。 ポリシールーティングのパッケージで構築した OpenWrt では、ルールのチェーン設定で prerouting ではなく output を選ぶということです。 両方の母集団にカバレッジが必要なら両方のルールを残します。
次にルールが何にマッチするかを絞ります。 リゾルバーが実際に使うポート上の宛先リゾルバーアドレスは、ルーターが生成するすべてをトンネルに送るよりはるかに小さな判断です。
両方のチェーンを覆う一つのルールを書こうとするのではなく、二つのルールを明示的に保ちます。 別々のルールは読みやすく、デバッグ中にクライアントのトラフィックを乱さずにルーターの経路を無効にできます。 またカウンターを一つずつ意味のあるものにします。
トンネル自身のトランスポートをルールの外に置く
トンネルの外側の接続もルーターが作ります。 ローカル生成のすべてのトラフィックをトンネルに送るルールは、トンネルを自分自身経由でルーティングし、トンネルはまったく上がりません。
管理アクセスが二つ目の犠牲者です。 ルーターから発信された管理セッションやその応答は、広すぎるローカルルールによってトンネルに引き込まれ、LAN から到達できなくなることがあります。
トンネルのエンドポイントをマッチから除外し、ルールをリゾルバーアドレスに限定します。 これで DNS の要件には十分で、考えるにも十分小さいです。
片方ではなく両方の母集団をテストする
ルーターが自分の問い合わせを行うのを観察し、どのインターフェースが運んだかを記録します。 LAN のホストから同じ問い合わせを繰り返し、そちらが通った経路を記録します。 ポリシールールのカウンターは、推測せずに両方の答えを見せてくれます。
結果は二つの発見として扱います。 トンネル経由で解決するクライアントはルーターについて何も語らず、正しく解決するルーターは別のリスナー上のクライアントについて何も語りません。 変更記録には別々の行として書きます。
ポートも確認します: 宛先ポート 53 にマッチするルールは、853 の DNS over TLS や HTTPS エンドポイント経由で到達するリゾルバーを取りこぼします。 設定された上流が実際に使うトランスポートに合わせれば、リークは正しい理由で閉じます。