ルーターはトンネル経由でインターネットに出ているのに、その後ろのノート PC は依然として ISP のアドレスを報告している。許可ルールを追加しても効かないが、この失敗は示唆に富む:フィルタリングが答えるのはパケットが通過してよいかであり、どこへ行くかではない。インターフェースの選択は、クライアント一覧を何も知らないルーティング検索によってすでに決まっている。検索を直せば、ファイアウォールはもう容疑者ではない。

フィルタールールはインターフェースを選べない

Linux ルーターのパケットフローは、まずルーティング判定を実行し、その後で forward フックを通る。ルールが外向きのトンネルデバイスに一致するころには、カーネルはすでにトンネルが出口だと決めている。メインテーブルが依然として WAN のデフォルトルートを優先していれば、パケットは ISP へ向かい、書いたばかりの許可ルールはそれを見ることすらない。この順序という一つの事実が、新しいファイアウォールルールを一枚追加しても何も変わらない理由を説明する。

以下の例では br-lan 上の 192.168.8.0/24 の LAN、トンネルデバイス tun0、そしてトンネルを使うべき 192.168.8.23 のセットトップボックスを使う。

ルールを編集する前に検索結果を読む

カーネルにそのクライアントの代理としてルートを解決させる。返答には外向きデバイスと選ばれる送信元アドレスが含まれ、診断を確定するにはそれで十分だ。返答が WAN デバイスを指すなら、パケットはあなたのルールに届く機会がなかった。

ip -4 route get 198.51.100.7 from 192.168.8.23

通常の経路に残すべきクライアントでも同じ問い合わせを繰り返す。両方の返答が同じデバイスを指すなら、送信元ごとのポリシーはまだ働いておらず、修正すべきはフィルタリングではなくルーティングだ。

対象にしたいクライアントにテーブルを結びつける

ポリシールーティングはメインテーブルの前にルール検索を差し込む。デフォルトルートがトンネルであるテーブルを作り、そのテーブルをセレクター(入力インターフェース、送信元アドレス、ファイアウォールマーク)に結びつける。優先度が順序を決め、メインテーブルはリストのずっと下、32766 にあるので、番号の小さいルールが先に参照される。インターフェースのセレクターはブリッジ上の全クライアントを覆い、アドレスのセレクターは一台のマシンを覆う。

ip -4 route add default dev tun0 table 200
ip -4 rule add iif br-lan lookup 200 priority 200

ファームウェアの画面は通常、ポリシールーティングや VPN ポリシーのページと同じオブジェクトを表示する。そこのデバイス一覧は手書きのルールより維持しやすく、ルールの書式が変わるアップグレードでもたいてい残る。

セレクターは意図して選ぶ。インターフェースのルールは短く将来に強いが、そのブリッジに届くルーター自身の管理トラフィックも拾ってしまう。送信元のルールは正確で、デバイス一覧が変わるたびに編集が要る。選択を書き残すのは、ある機器だけ挙動が違う理由を次に尋ねる人がそれを必要とするからだ。

ローカルの宛先をトンネルの外に保つ

新しいテーブルは自分で入れたルートしか知らない。LAN のプレフィックスが無いため、プリンターや NAS の通信はトンネルのデフォルトルートをたどって消える。throw ルートはこのテーブルでの検索を終わらせ、判断をメインテーブルに戻す。

ip -4 route add throw 192.168.8.0/24 table 200

そのルートを省くとローカルの共有が壊れ、セレクターが想定より広いとルーター自身の管理セッションも消えかねない。送信元の問題については、LAN アドレスをまだ持つトンネルのパケットは遠端が戻り経路を知っている必要があり、トンネル上で masquerading すればその条件も、遠端が見るクライアントの識別情報も消える。

実行時に追加したルールとルートは、再起動やファームウェア更新で消える。ルーターの起動処理に追加して一度再起動し、クライアントで公開アドレス、WAN に残すべきもう一台のクライアント、新しい接続中のトンネルカウンターを再試験する。

関連記事