iptables/nftables: ルーターの接続追跡から転送されたすべてのトラフィックを除外するにはどうすればよいですか?

iptables/nftables: ルーターの接続追跡から転送されたすべてのトラフィックを除外するにはどうすればよいですか?

Linux ボックスには複数のネットワーク インターフェイスがあります。IP 転送は IPv4 と IPv6 で有効になっています。

ルータ自体で実行されているサービスをステートフル ファイアウォール経由で保護したいと考えています。そのためには、接続追跡を有効にする必要があります。同時に、あるインターフェイスから別のインターフェイスに転送されるすべてのトラフィックを接続追跡から除外したいと考えています。

ステートフル ファイアウォールの場合、通常はフィルター テーブルの INPUT チェーンと OUTPUT チェーンを使用します。転送されたトラフィックは FORWARD チェーンに送られます。しかし、私の知る限り、FORWARD チェーンでトラフィックを追跡されていないものとしてマークする方法はありません。このようなロジックは、raw テーブルの PREROUTING チェーンに送られる必要があります。しかし、PREROUTING チェーンでは、トラフィックが転送されるかどうかはまだ決定されていないと思います。

接続追跡には、追跡対象の接続のリストが最大サイズに達したときにパケットがドロップされるなど、多くの欠点があります。

転送されたトラフィック (転送されたトラフィックのみ) を接続追跡から除外する最も簡単な方法は何ですか?

答え1

一般的なルールセットについては、nftables事前にルート検索を行うにはfibルーティングスタックがそれを実行するのを待つ代わりに、式を実行します。これにより、(将来の)出力ルーティングの決定がまだ行われていないにもかかわらず、追加のルックアップを犠牲にして、インターフェイスがまだ存在しないにもかかわらず、追跡が行われるのを防ぎます。その後、結果がパケットがルーティングされることを示している場合は、notrack声明。

FIB表現

fib {saddr | daddr | mark | iif | oif} [. ...] {oif | oifname | type}

式は、(転送情報ベース)を使用して、特定のアドレスが使用する出力インターフェイスインデックスなどの情報を取得します。入力は、ルックアップ関数。

ノートラック声明

notrack ステートメントを使用すると、特定のパケットの接続追跡を無効にすることができます。

notrack

このステートメントを有効にするには、パケットが接続トラックルックアップが行われます。したがって、チェーン内に配置する必要があります事前ルーティングまたは出力フックとフック優先度が -300 以下。

そこで、「簡単な」ルートチェックを事前ルーティング宛先アドレスのみをセレクタとして使用し、出力インターフェースの存在を確認します(ルーティング不可能なパケットやホスト宛のパケットは解決されません)。見よ(ループバック)インターフェースを使用して追跡します。これはローカルトラフィックを表しますが、(出力ホストから自分自身へのパスは事前ルーティングパスと出力インターフェースを持っています見よ送信パケットはすでに接続トラックエントリは、一貫性を保つことをお勧めします。

nft add table ip stateless
nft add chain ip stateless prerouting '{ type filter hook prerouting priority -310; policy accept; }'
nft add rule ip stateless prerouting iif != lo fib daddr oif exists notrack

ipファミリをコンボ ファミリに置き換えると、inet同じ一般的な動作が IPv4 + IPv6 に拡張されるはずです。

より具体的には、fib daddr oif eth1例えば、将来の出力インターフェースを で指定することができます。これは、 とほぼ同等ですoif eth1が、事前ルーティング

もちろん、トポロジが事前にわかっている場合は、管理者がルートを事前に知っているため、アドレス テストに基づく 1 つまたは複数のルールを使用して FIB 検索を回避することができます。これが一般的な方法を維持するよりも興味深いかどうかを知るには、結果をベンチマークする必要があるかもしれません。

たとえば、OP が提供した情報を使用して、前のルールを次のように置き換えます。

nft add rule ip stateless prerouting 'ip daddr != { 192.168.1.1, 192.168.2.1, 127.0.0.0/8 } notrack'

ほぼ同等の効果が得られるはずです。127.0.0.0/8は、上記と同じ理由で存在し、見よインターフェース。

ブロードキャストの処理(192.168.1.255を受信したなど)eth0) とマルチキャスト (インターフェースで受信されたリンクローカル 224.0.0.1 など) は、両方の方法で同じように動作しない可能性があり、また期待どおりに動作しない可能性があり、特に 2 番目の方法では、特定のニーズに合わせて追加のルールが必要になる可能性があります。ブロードキャストとマルチキャストの追跡はほとんど役に立ちません。応答ソースが元のブロードキャストまたはマルチキャスト アドレスの宛先ではない (できない) ため、conntrack エントリが双方向トラフィックを「認識」することはないためです。通常、ステートフル ルールではあまり問題になりません。


ノート

  • これは通常、ステートフル NAT と互換性がありません。

    私の理解では、リモートホストへのDNATは、応答トラフィックがデNATされずに失敗し、転送されたSNATはトリガーされないということです。接続トラックエントリが作成されました。入力パスでめったに使用されないSNATは問題ないはずです。また、DNAT+SNAT(ローカルアドレスソースを使用)の組み合わせも機能する可能性があります。これにより、元の方向と応答方向の両方にローカル宛先が関係するため、接続トラックそうすれば、エントリは常に正しく作成または検索されるはずです。

  • 標準ルールセット

    実際のルールiptablesまたはnftables(独自のテーブルで)ホスト自体のステートフルルールを含め、通常どおり実行できます。ルーティングされたトラフィックは接続トラックエントリ、ルールがそのようなトラフィックに関係する場合は、ステートレスのみに固執し、一致ctすることはないため、いかなる表現も使用しないでください。

  • 動作の確認

    適切なファイアウォール ルールがなくても、次の方法で全体的な動作を確認できます。

    • ダミーctルールを使用して、接続トラック機能は現在のネットワーク名前空間に登録されます。

      nft add table ip mytable
      nft add chain ip mytable mychain '{ type filter hook prerouting priority -150; policy accept; }'
      nft add rule ip mytable mychain ct state new
      
    • 使用conntrackイベントを追跡するためのツール:

      conntrack -E
      
    • リモートからのトラフィックを生成する

      新しい接続トラックルータが受信するトラフィック用のエントリは作成されますが、ルーティングされるトラフィック用のエントリは作成されません。

関連情報