我正在尝试使用 nftables 设置防火墙,但根据我找到的文档,我无法理解并实现简单的速率限制。
- 操作系统:Ubuntu 20.04 LTS
- nftables 版本:0.9.3(Topsy)
- 内核版本:5.8.0-53-generic
我已经使用以下命令序列构建了测试防火墙:
nft 'add table inet testnetwork'
nft 'add chain inet testnetwork INPUT { type filter hook input priority 0; policy drop; }'
nft 'add set inet testnetwork SSH { type ipv4_addr; flags dynamic, timeout; size 65536; }'
nft 'add rule inet testnetwork INPUT ct state related,established counter accept'
nft 'add rule inet testnetwork INPUT ip saddr @SSH ct state new tcp dport 22 counter drop'
nft 'add rule inet testnetwork INPUT ct state new tcp dport 22 limit rate over 10/minute add @SSH {ip saddr timeout 60s} counter'
nft 'add rule inet testnetwork INPUT ct state new tcp dport 22 tcp sport 1024-65535 counter accept'
当我列出初始规则集时,我得到:
table inet testnetwork {
set SSH {
type ipv4_addr
size 65536
flags dynamic,timeout
}
chain INPUT {
type filter hook input priority filter; policy drop;
ct state established,related counter packets 0 bytes 0 accept
ip saddr @SSH ct state new tcp dport 22 counter packets 0 bytes 0 drop
ct state new tcp dport 22 limit rate over 10/minute add @SSH { ip saddr timeout 1m } counter packets 0 bytes 0
ct state new tcp dport 22 tcp sport 1024-65535 counter packets 0 bytes 0 accept
}
}
通过这样的配置,我预计 IP 会在 1 分钟内第 11 次(新)连接尝试时添加到 SSH 集中,并从第 12 次尝试开始被阻止(1 分钟)。
但是,当我打开第二个终端窗口并依次启动并关闭少于 10 个到 127.0.0.1 的 ssh 连接时,我会将 IP 添加到 SSH 集然后阻止它。
以下是第七次尝试时的规则集状态:
table inet testnetwork {
set SSH {
type ipv4_addr
size 65536
flags dynamic,timeout
elements = { 127.0.0.1 timeout 1m expires 54s564ms }
}
chain INPUT {
type filter hook input priority filter; policy drop;
ct state established,related counter packets 156 bytes 28692 accept
ip saddr @SSH ct state new tcp dport 22 counter packets 3 bytes 180 drop
ct state new tcp dport 22 limit rate over 10/minute add @SSH { ip saddr timeout 1m } counter packets 1 bytes 60
ct state new tcp dport 22 tcp sport 1024-65535 counter packets 6 bytes 360 accept
}
}
在这一点上,要么是我没有正确理解限制率机制,要么是我在其他地方犯了错误。
有人能帮助我指出我的期望是否错误或者错误可能来自哪里吗?
谨致问候,感谢您的时间
答案1
在我的 VPS 上
sshPort=2222
nft add table ip sshGuard
nft add chain ip sshGuard input { type filter hook input priority 0 \; }
nft add set ip sshGuard denylist { type ipv4_addr \; flags dynamic, timeout \; timeout 5m \; }
nft add rule ip sshGuard input tcp dport $sshPort ct state new ip saddr @denylist reject
nft add rule ip sshGuard input tcp dport $sshPort ct state new limit rate over 2/minute burst 3 packets add @denylist { ip saddr } reject
nft list table ip sshGuard
我测试了几次(每次都使用nft flush set ip sshGuard denylist
),第 4 次连接将被拒绝。如果我将 更改为limit rate over 2/minute burst 3 packets
,limit rate over 2/minute
则在 7-9 次连接后会出现拒绝。因此,我不知道 的确切机制limit rate over 2/minute
,但burst 3 packets
似乎使事情更加确定。
默认burst
值为#define NFT_LIMIT_PKT_BURST_DEFAULT 5
答案2
我想为我的迟来的反馈道歉,我还有一些其他紧急事务,最后完成了需要这个问题的任务。
首先,非常感谢@AB的回答和帮助。我以前不知道“令牌桶算法”,但这有助于我理解整个过程,尤其是“速率”,因为正如你提到的那样,内核不会等待1分钟来做某事。
也感谢@Chen Deng-Ta 的测试。