トンネルインターフェースを期待して探しても、ファイアウォールには照合できるものがありません。ポリシーベースのゲートウェイではこれは正常で、暗号化されたやり取りは物理インターフェースに届き、その後転送される復号済みの内側パケットも同じインターフェースに届くものとして観測されます。何も作成していないのでtun0はありません。

内側の要求は依然として独自の送信元、宛先、サービスを持つ別個のパケットであり、カーネルはそれがどのセキュリティアソシエーションから出てきたかを知っています。ファイアウォール規則が照合できるのは、まさにこの知識です。

二つのパケット、一つのインターフェース

受信方向を想像してください。ESPまたはUDPでカプセル化されたパケットが届くと、カーネルは一致するポリシーを見つけて復号し、平文のパケットを転送経路に渡します。インターフェース名だけを見る規則では、そのパケットを同じケーブルに届く他のトラフィックと区別できません。

それを区別するのは、パケットに付随する受信セキュリティパスのコンテキストです。nftablesはこれを meta ipsec exists として公開し、パケットがIPsecのセキュリティパスを通って届いたときに真になります。これをクライアントプール、宛先、サービスと組み合わせれば、規則は安全と言えるほど具体的になります。

コンテキストを省くのがよくある誤りで、それは見た目の問題ではなくセキュリティの問題です。クライアントプールからのものをすべて受け入れる規則は、送信元アドレスだけでは何の証拠にもならないため、ローカルネットワークからの偽装パケットも同じように受け入れます。セキュリティパスのコンテキストは、送信元を意味のあるものにする最も安価な方法です。監査の後に付け足すのではなく、最初からそれを含めて規則を書いてください。

転送規則を書く

10.90.0.0/24 にクライアントを持つ認証済みのIPv4リモートアクセスサービスと、203.0.113.40 に承認済みの宛先が一つあるとします。そのフロー向けの規則の断片は次のとおりです。

meta ipsec exists ip saddr 10.90.0.0/24 \
  ip daddr 203.0.113.40 tcp dport 443 \
  oifname "eth0" counter accept

アドレスとインターフェースは置き換えるための例です。レビュー済みの同等品を、そうしなければフローを拒否する規則より前に転送ポリシーへ置き、インストールのために既存のルールセットをフラッシュしないでください(ゲートウェイはクリーンルーム実験ではありません)。

oifname という条件は残す価値があり、送信の判断を記録し、意図しない方向で規則が一致するのを防ぎます。これはインターネットへの経路が複数あるゲートウェイでは重要です。アップリンクが一本だけの検証機ではこの条件は冗長に見え、だからこそ二本目のアップリンクを得る前に削除されます。

外側のやり取りの権限は別です。ゲートウェイの入力経路には、実際に使うIKEとESPまたはUDPカプセル化のポートが必要であり、それらの権限は内側の復号済みパケットについて何も許可しません。この二つを混ぜると、動いているトンネルがすべてを転送するファイアウォールと同居することになります。

受信コンテキストは送信コンテキストではない

同じ表現群が、rt ipsec で逆方向も扱い、これはパケットが使う送信セキュリティアソシエーションを記述します。答える問いが違い、このパケットがどこから来たかではなく、次の区間で保護されるかどうかです。

この区別は、一つのトンネルを終端しつつ別のトンネルへ転送するゲートウェイで重要です。パケットは復号されて届いても暗号化されて出ていく必要があり、受信コンテキストのためだけに書かれた許可は送信側の要件について何も語りません。ポリシーがその保護を要求するなら、ルーティングが処理するはずだと仮定せず、ルールセットで表現すべきです。

二つの問いは別々の規則に保ち、読者がどちらが適用されているか分かるようにしてください。両方を確認する一つの賢い規則はレビューが難しく、片方が一致しなくなったときのデバッグはさらに難しくなります。カウンタ付きの二つの規則はどちらの要件が失敗しているかも示しますが、統合された一つの規則では決して分かりません。

NATはファイアウォールの判断ではない

プライベートなクライアントプールからインターネットへ向かうトラフィックは通常、応答が戻り道を見つけられるよう送信元変換を必要とします。しかし別の送信IPsecポリシーに選ばれたトラフィックは必要な除外を保たねばならず、次の保護の判断を考えずにすべてのプライベート送信元をマスカレードすると、それが崩れます。

NATチェーン内の許可も一般的な許可ではありません。NATとフィルタリングは役割が異なり、NATチェーンは確立済みフローの後続パケットをすべて検査するわけではないため、セキュリティをNATに頼ると、テストでは動くように見えて負荷時に失敗する規則が生まれます。

逆もまた真で人を驚かせますが、あるフィルタ基底チェーンのどこかにある許可は、別の適用されるチェーンでの後続の破棄に対して何の重みも持ちません。結果を決めるのは順序とチェーンの範囲であり、ファイル内に許可があるかどうかではありません。

内側のサービスを正確に検証する

認可した特定の宛先とポートを実際のクライアントから試し、応答が戻ることを確認してください。次に認可していないものを試し、広すぎる規則も正しい規則と同じように最初のテストを通過するため、通らないことを確認してください。クライアントを決して出ない要求もファイアウォールの結果ではないので、カウンタを読んでパケットがそもそも評価されたかを見てください。二回のテストと一回のカウンタ確認は、ルールセットを読む半日よりも多くを教えてくれます。

nftablesのリファレンスには meta ipsec、rt ipsec、方向ごとの式が記載されており、インストール済みのバージョンに対して構文を確認する場所はそこです。範囲も明確にすべきで、これはIPv4の例であり、IPv6については何も述べておらず、任意の公開ポート転送をVPNサービスの一部にするものでもありません。

関連記事