nftables - 限制速率行为(错误或误用?)

nftables - 限制速率行为(错误或误用?)

我正在尝试使用 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 packetslimit 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 的测试。

相关内容