nftables
支持动态填充集,这些集记录在nftables wiki中。wiki 页面上的第一个示例如下:
table ip my_filter_table {
set my_ssh_meter {
type ipv4_addr
size 65535
flags dynamic
}
chain my_input_chain {
type filter hook input priority filter; policy accept;
tcp dport 22 ct state new add @my_ssh_meter { ip saddr limit rate 10/second } accept
}
}
nftables
上面的配置解释如下:
在此示例中,我们创建一条规则来匹配新的 TCP ssh(端口 22)连接,该规则使用名为 my_ssh_meter 的动态集将每个源 IP 地址的流量速率限制为每秒 10 个连接。
如何解读这条规则或者如何理解它?我的意思是,如果 Linux 连接跟踪子系统看到到 TCP 目标端口 22( ) 的新连接 ( ip saddr
),则带有数据的源 IP 地址 ( )limit rate 10/second
会添加到命名集中。不过这套好像从来没用过?填充集合时执行的操作是否成功?my_ssh_meter
ct state new
tcp dport 22
my_ssh_meter
accept
会发生什么:
当新的 ssh 连接到达时,其源加上附加的计量表将添加到该集合中(如果尚未存在:它是一个集合,因此每个元素仅出现一次)并进行评估以提供布尔结果 true/false
如果评估为真,则规则可以继续,否则规则停止。
注意:如果没有附加的仪表,添加元素将始终评估为 true:添加到集合不是终结。
这里:
如果它评估为真(即:它没有泛滥),则该规则继续
accept
结束当前输入挂钩(即:chain my_input_chain
)评估。如果评估结果为 false,则规则在最终
accept
语句之前结束accept
因此,无论发生什么,新的连接数据包总是被接受:这个规则集除了填充规则集之外没有任何可见的效果。
wiki 的规则集示例不完整。在相同的条件下,它后面应该跟一个
drop
(或)(某些规则分解当然是可能的):reject
因此,如果指标确实溢出,
accept
则不会评估前一个规则的最后部分,并且传入连接将在下一个规则中被丢弃。只要进行了尝试,就会将其计入指标的令牌桶中。因此,只要尝试保持太快,就可能有零个新连接(请注意,默认令牌桶突发为 5,即使立即泛洪,第一个连接也始终会成功)。这里需要了解的重要一点是,与许多其他语句一样,set语句(使用
@
set的特殊语法)既执行更改操作(将元素添加到集合中),又具有布尔结果:true 或 false这需要进一步评估规则的其余部分:两个角色同时使用。要进行测试,只需替换
10/second
为10/minute
或10/hour
:行为现在将变得更加明显(在第 5 个连接之后:默认情况下 的limit
令牌桶允许突发 5 个数据包。)