我创建了一个网络过滤表。我把它写在脚本里了。我无法让这个脚本始终加载。如果我刷新/删除该表,那么如果该表不存在,它就不起作用。如果我不刷新/删除,那么它会合并新旧规则。
如果表存在,如何刷新/删除?
#!/usr/sbin/nft -f
flush table my_table
table ip my_table {
chain output {
type filter hook output priority 0; policy accept;
ip daddr 8.8.8.8 counter
ip daddr 1.1.1.1 counter
skuid "other" jump restrict_chain
skuid "d" jump d_chain
}
chain accept_chain {
nftrace set 1 counter accept
}
chain reject_chain {
nftrace set 1 counter reject
}
chain restrict_chain {
#type filter priority 0; policy drop;
counter
ip daddr 1.1.1.1 counter
oifname "lo" jump accept_chain
oifname != "lo" jump reject_chain
}
chain d_chain {
counter
}
}
答案1
首先声明一个空表。如果表已经存在,它不会抛出错误,也不会更改其内容:什么也不会发生。如果它不存在,则刚刚创建空表。既然它在所有情况下都存在,那么就可以将其删除。这一切都可以在相同规则集。
因此,声明没有链或规则的表,然后删除它(手册页告诉刷新它将刷新链和规则,但这不会删除链本身,它们只会被清空,这将保留旧的重命名链或集,或者如果它们的属性发生更改,则与它们发生冲突。这nftables wiki 有更多关于删除和刷新的信息行为。)。现在你可以真正创建它了,仍然在相同且独特规则集文件。现在可以多次幂等地加载相同的规则集,即使第一次也不会抛出错误。
#!/usr/sbin/nft -f
table ip my_table
delete table ip my_table
table ip my_table {
chain output {
type filter hook output priority 0; policy accept;
ip daddr 8.8.8.8 counter
# [...]
}
}
更新:足够新的内核和nftablesdestroy
还接受表示“如果存在则删除”的关键字,它可以替换前两个命令 ([ add
] + delete
) 以获得相同的幂等效果。
您可以选择使用include
语句将所有此类准备行放在一个单独的文件中,以防有很多准备行并且您不希望它们污染规则集。
您可以在链级别执行相同的操作,即无需更改同一个表中的其他链,也不假设或要求该表及其链之前就在这里。这是一个reject_chain
激活的例子NFTRACE,这不会删除其他表或my_table
链。这个例子没有什么实际用处,只是举个例子。
#!/usr/sbin/nft -f
table ip my_table {
chain reject_chain {
}
}
delete chain ip my_table reject_chain
table ip my_table {
chain reject_chain {
nftrace set 1 counter reject
}
}
兼容性说明:< 3.18 的内核需要刷新 + 删除才能正常工作,如下所示解释了在维基百科中。这(以及链的等效项)甚至可以在任何内核版本上工作:
table ip my_table
flush table ip my_table
delete table ip my_table