Linux-Networking

如何在 nftables 中刷新設置元素超時?

  • March 30, 2022

如何在集合元素過期之前用 nft 刷新它的超時/過期值?

將現有元素添加到集合中不會重置 timeout/expires 值:

nft add element ip mytable myset { 10.10.10.1 timeout 60s }
# wait 10s
nft add element ip mytable myset { 10.10.10.1 timeout 60s expires 60s }
nft list set ip mytable myset

使用 iptables/ipset 我可以通過添加現有元素來刷新超時:

ipset add myset 10.10.10.1 timeout 60
# wait 10s
ipset add myset 10.10.10.1 -exist timeout 60
ipset list myset

雖然記錄了原子規則替換

原子規則替換

您可以使用該-f選項自動更新您的規則集:

% nft -f file

它沒有明確記錄元素替換,但這實際上只是規則替換的一種情況。可以在引入的單個原子事務中刪除和添加元素-f:這將用新條目及其更新的過期時間替換舊條目,而不會暫時失去元素。

因此,不要執行以下操作,這不是原子的,因為在兩次呼叫之間nft,元素將暫時不存在,並且取決於此集合的規則將暫時不匹配:

~~```

nft delete element ip mytable myset ‘{ 10.10.10.1 }’

nft add element ip mytable myset ‘{ 10.10.10.1 timeout 60s expires 60s }’

這應該使用`-f`輸入文件(`-`代表*標準輸入算作*有效輸入文件)來完成:

nft -f - <<‘EOF’

delete element ip mytable myset { 10.10.10.1 } add element ip mytable myset { 10.10.10.1 timeout 60s } EOF


元素永遠不會停止存在,因為它是原子變化。


與此*nft*構造一樣,如果想要冪等地執行此操作,而不必知道元素是否已經存在,並且不涉及其他元素,則應該添加、刪除和重新添加它,因為添加現有元素時' t 一個錯誤,刪除一個缺失的元素將是一個錯誤:

nft -f - <<‘EOF’

add element ip mytable myset { 10.10.10.1 } delete element ip mytable myset { 10.10.10.1 } add element ip mytable myset { 10.10.10.1 timeout 60s } EOF


它仍然是一個單一的原子事務。




---


補充筆記


* [從數據包路徑](https://manpages.debian.org/nftables/nft.8#SET_STATEMENT)


從數據包路徑執行此操作時,兩者之間存在區別,`add @myset`僅在創建新元素時設置超時,但不會更新現有元素的超時,允許它稍後在其整個持續時間內超時,並且`update @myset`確實設置在所有情況下超時。
* 原子規則更新不僅限於元素,還可以在任何級別使用


例如,如果需要關注單個元素,則可以在集合級別執行相同的操作:

nft -f - <<‘EOF’

add set ip mytable myset { type ipv4_addr; flags timeout; } delete set ip mytable myset add set ip mytable myset { type ipv4_addr flags timeout elements = { 127.0.0.1 timeout 1m } } EOF


實際上,上面的範例可能會失敗,因為可能存在引用該集合的規則,因此即使在事務期間也不允許將其刪除(可以用`add table ip mytable`, `delete table ip mytable`,類似地重寫整個表`add table ip mytable { ...`)。如果已知該集合之前存在,則在添加回單個元素之前刷新它就足夠了:

nft -f - <<‘EOF’

flush set ip mytable myset add element ip mytable myset { 127.0.0.1 timeout 1m } EOF



當然,可以使用實際文件代替`- &lt;&lt;'EOF'`... `EOF`。

引用自:https://serverfault.com/questions/1097074