私は何をしますか?

私は何をしますか?

iptablesからnftablesに移行しましたが、迷惑な問題に固執しました。以前のシステムには、毎日いくつかのルールを削除/追加するスクリプトがありました。場所に応じてiptablesルールを簡単に追加/削除できます。これは一定です。

今私たちは迷惑なハンドルを持っています。スクリプトからルールを追加すると、動的ハンドル番号によって割り当てられます。まず、対応するハンドル番号を検索してルールを削除できます。問題は、同じルールを削除して再度追加する場合です。それ以降はハンドル番号が増加するため、同じではありません。そのため、従来のシステムなどの簡単な方法は使用できません。

誰でもこの問題を解決するためのソリューションを提供できますか?チェーンには少なくとも40のルールがあり、同じルールを削除し、毎日いくつかのルールを再度追加したいと思います。 iptablesを使用すると簡単すぎますが、今は簡単な解決策を見つけることができません。

ありがとうございます。

答え1

OPはこの種のルールを使用します、これは答えの基礎として例として使用されるレイアウトです。

add rule ip nat postrouting oifname $inet_if ip saddr 172.xx.xx.xx counter snat to $inet_if_ip
add rule ip nat postrouting oifname $inet_if ip saddr 172.xx.xx.xx counter snat to $inet_if_ip

...など...

セットを使う

nftables特徴セット、似ているIPセットiptablesと対になっていますが、より多様です。

だから買収分解が可能です。ナットルールを1つのルールにまとめてから、ルールに触れることなく、関連するコレクションでのみ機能します。コレクション要素の操作 (削除を含む) は、ルールとは異なり、コンテンツの順序が関係なく、ハッシュリストを使用してカーネルメモリから効率的に検索および並べ替えることができるため、ハンドルは必要ありません。

独立して計算する場合ナットストリーム(たとえば、維持される役割がcounter重要です。これには最新のツールが必要です(最小> = 0.9.1、しかしnftables> = 0.9.4が推奨されている、を参照)。私の答えこの回答の最後にある「エラー」も参照してください。nftablesまだ開発中なので、一部の機能はバージョンによって異なります。nftablesまたはカーネル。

この回答にはnftables 0.9.6 0.9.8が使用されました。これはいくつかの構文や機能(JSONなど)に影響を与える可能性があります。

したがって、このルールセットの代わりに:

define inet_if = eth0
define inet_if_ip = 192.0.2.2

table ip nat        # for idempotency
delete table ip nat # for idempotency

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        oifname $inet_if ip saddr 172.17.1.2 counter snat to $inet_if_ip
        oifname $inet_if ip saddr 172.17.1.3 counter snat to $inet_if_ip
    }
}

後で埋めることができるセットを使用することが可能です(または直接塗りつぶすこともできます)。

define inet_if = eth0
define inet_if_ip = 192.0.2.2

table ip nat
delete table ip nat

table ip nat {
    set curfewlist {
        type ipv4_addr
        counter        # optional
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        oifname $inet_if ip saddr @curfewlist snat to $inet_if_ip
    }
}

その後、コレクションは06:00にcrontabに埋め込むことができます(前の例による)。

nft 'add element ip nat curfewlist { 172.17.1.2, 172.17.1.3 }'

23:00に1つずつ削除できます。

nft 'delete element ip nat curfewlist { 172.17.1.2 }'
nft 'delete element ip nat curfewlist { 172.17.1.3 }'

あるいは、一度に複数の要素を使用することもできます。

nft 'delete element ip nat curfewlist { 172.17.1.2, 172.17.1.3 }'

または単にフラッシュしてください。

nft flush set ip nat curfewlist

注:aの範囲(名前空間とも呼ばれる)置く独自のテーブル内:コレクションは他のテーブルから参照することはできませんが、以下に関連しています。iptablesテーブルは1つのフックタイプに限定されません。 1つは一緒にすることができますおそらくそうすべきでしょう同じテーブルに複数の種類のチェーンがある場合は、同じコレクションを再利用できます。フィルタールールとナット模倣ではないルールiptables'テーブルごとに1つのフックタイプに制限されます。

meta hour競争を利用する

カーネル>= 5.5の場合、これ以上何も変更する必要はありません。meta hourこれはパケットパスを介して確認できます。個人ナットルールは次のように置き換えることができます。

meta hour 06:00-23:00 oifname $inet_if ip saddr @curfewlist snat to $inet_if_ip

そしてコレクションは決して埋められません。年に 2 回だけ夏時間が変更される間、カーネルは常に UTC 時間を使用するため、ルールセットを再ロードする必要があります。完全なルールセットは次のとおりです。

define inet_if = eth0
define inet_if_ip = 192.0.2.2

table ip nat
delete table ip nat

table ip nat {
    set curfewlist {
        type ipv4_addr
        counter
        elements = { 172.17.1.2, 172.17.1.3 }
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        meta hour 06:00-23:00 oifname $inet_if ip saddr @curfewlist snat to $inet_if_ip
    }
}

注:カーネルメモリに保存されている時間単位の間隔はUTCタイムゾーンに従い、常に24時間モジュールで単一の連続間隔です。現地のタイムゾーンによって時間表現を異なる方法で読むことができます。たとえば、次のようになり!= "23:00"-"06:00"ます。"06:00"-"23:00"


上記は結果を単純化すると考えていますが、以下では別の方法でハンドルを解決または使用しようとする方法について説明します。

ジョイスティックは必要ありません。

上記のアプローチがユースケースに十分でない場合でも、ユーザーチェーン内のすべての論理ルールを移動し、ルールレベルではなくチェーンレベルで操作を実行できます。これはここに与えられます:

define inet_if = eth0

table ip nat
delete table ip nat

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        oifname $inet_if jump curfew
    }

    chain curfew { }
}

06:00に次のルールセットセクション(たとえば)がロードされますnft -f curfew.nft

define inet_if_ip = 192.0.2.2

flush chain ip nat curfew #for idempotency

table ip nat {
    chain curfew {
        ip saddr 172.17.1.2 counter snat to $inet_if_ip
        ip saddr 172.17.1.3 counter snat to $inet_if_ip
    }
}

23:00に次のコマンドを実行します。

nft flush chain ip nat curfew

コントローラを引き続き使用できる他の方法はありますか?

これを行うには、単にスクリプトを使用するのではなく、何らかの方法でスクリプトを使用する必要があります。NFFT

後でルールを識別するにはダンプが必要です。みんなルールをリンクします(たとえば、カーネルからユーザーモードに移動します)。これは何ですか?nftables「開発者は最初から避けようとしました。

特定のユースケースで後で削除できるルールを追加する場合は、後でハンドルを照会する必要がないようにルールを追加するときにハンドルを保存します。

--echoこのオプションを使用すると、--handleハンドルを含む追加したコンテンツが自動的に表示されます(別々にnft --handle monitor実行することもできます)。古いcurfew.nftファイルを使用すると、次のものが提供されます(呼び出しごとにハンドルが変更されます)。

# nft --echo --handle -f curfew.nft 
add chain ip nat curfew # handle 2
add rule ip nat curfew ip saddr 172.17.1.2 counter packets 0 bytes 0 snat to 192.0.2.2 # handle 4
add rule ip nat curfew ip saddr 172.17.1.3 counter packets 0 bytes 0 snat to 192.0.2.2 # handle 5

したがって、合理的なフィルタを使用してやり直してください(この特定のルールセットセクションに何が追加されたかを知ることは簡単です)。

# nft --echo --handle -f curfew.nft | sed -n 's/^add rule.*# handle \(.*\)$/\1/p' | tee curfew-handles.txt
6
7

追加のルールを手動でリンクし、そのハンドルを保存できます。

# nft --echo --handle add rule ip nat curfew ip saddr 172.17.1.4 snat to 192.0.2.2 | sed -n 's/^add rule.*# handle \(.*\)$/\1/p' | tee -a curfew-handles.txt
8

次に、リストからハンドルのすべてのルールを削除します。

# for i in $(cat curfew-handles.txt); do printf 'delete rule ip nat curfew handle %d\n' $i; done | nft -f - && : > curfew-handles.txt

修正する:nftables >= 0.9.8 より良いJSONサポート

nftablesサポートするJSON出力しかし、バージョン0.9.8が必要:nft --echo --handle --json add rule ...バージョン0.9.6では何もエコーしませんが、0.9.8ではうまく動作します(ここではカーネル5.10.xでテストしました)。

次の方法で追加したルールハンドルを検索する例jq。追加の出力コメント行自体はJSON出力ではないため、フィルタリングする必要があります。

# nft --echo --json add rule ip nat curfew ip saddr 172.17.1.4 snat to 192.0.2.2 | 
    grep -v '^#' | 
    jq '.nftables[].add.rule.handle'
40

nft monitorあるいは、ルールに従ってチェーン情報を提供しながら両方を使用すると、より便利です。

nft --json monitor | 
    grep --line-buffered -v '^#' |
    jq -j '
        .add.rule |
            if . != null then
                (.handle, " ", .family, " ", .table, " ", .chain, "\n")
            else
                empty
            end'

上記の前のルールコマンドを実行した結果:

40 ip nat curfew

警告する:

  • いくつかのnftablesバージョンのバグ

    現在(v0.9.8)--echo --handleいくつかの完全なルールセットを使用すると、nft警告(以前のルールセットが空の場合)または競合が発生する可能性があります(たとえば、counterセットに最近導入されたキーワードが原因で、これらのコマンドが発生したか、実行中のコマンドがクラッシュするしたようですnft --handle monitor)。今は、ルールだけを追加するコマンドに引き続き使用するのが最善です。

答え2

これは働きます:

handle=$(nft list ruleset -a | grep "$your_rule" | grep "#" | awk '{print $NF}')
test -n "$handle" && nft delete rule filter output handle "$handle"
nft insert rule filter output position XX ...

答え3

私は何をしますか?

カスタムフォームなので毎回交換してください。単一の呼び出しで完了できる場合、テーブルの更新はアトミックですnft

したがって、私のプログラムのルールを変更し、テーブルを再生成し、nft

答え4

要素タイムアウトは必要なソリューションを提供できます。コレクションにアドレスまたはポートを含めることができ、有効期限が切れるとコレクションから自動的に削除されます。

タイムアウトは、時間、分、秒、または2時間、10分、5秒などの組み合わせで指定できます。

nftables wikiの例を引用すると、次のようになります。

% nft add table inet myfilter
% nft add set inet myfilter myset {type ipv4_addr\; flags timeout\; }
% nft add element inet myfilter myset {10.0.0.1 timeout 10s }

結果:

% nft list ruleset
table inet myfilter {
    set myset {
        type ipv4_addr
        flags timeout
        elements = { 10.0.0.1 timeout 10s expires 8s}
    }
}

源泉:https://wiki.nftables.org/wiki-nftables/index.php/Element_timeouts

関連情報