nftables可通过ct mark标记子网+limit实现按/24子网独立限速,虽无原生hashlimit模块,但借助连接跟踪、地址匹配与速率限制组合可等效达成;多子网差异化策略可用set定义区间并分层限速;并发控制需结合ct count与mark。

直接用 nftables 实现“按子网哈希限速”,核心是 limit 和 ct(连接跟踪)配合使用,但要注意:nftables 本身没有内置的 hashlimit 模块——它不支持 iptables 那种 -m hashlimit --hashlimit-mode srcip --hashlimit-srcmask 24 的原生哈希分组计数方式。不过,通过合理组合 ct、ip saddr、counter 和 limit,仍可达成等效目标:对每个 /24 子网独立限速。
用 ct mark + limit 模拟子网哈希限速
由于 nftables 缺少直接按掩码聚合源地址的限速原语,推荐做法是:先按子网范围标记连接,再对已标记连接做速率控制。适用于 TCP/UDP 服务入口(如 HTTP、DNS):
- 创建一个自定义链,匹配源 IP 所属子网并打标记
- 在主链中跳转到该链处理
- 对已标记连接应用
limit rate,并结合burst控制突发流量
示例:限制每个 /24 子网每秒最多发起 10 个新连接(针对 TCP SYN):
nft add table inet filter<br>nft add chain inet filter input { type filter hook input priority 0; policy drop; }<br>nft add chain inet filter subnet_limit { type filter hook input priority -1; }<br><br># 将来自 192.168.0.0/16 的连接打上 mark 1<br>nft add rule inet filter subnet_limit ip saddr 192.168.0.0/16 ct mark set 1<br><br># 对 mark=1 的连接,限制新建连接速率为 10/second,允许最多 5 个突发<br>nft add rule inet filter input ct mark 1 tcp flags & (fin | syn) == syn limit rate 10/second burst 5 counter drop<br><br># 允许其他常规流量(如已建立连接、ICMP 等)<br>nft add rule inet filter input ct state established,related accept<br>nft add rule inet filter input icmp type echo-request limit rate 5/second accept<br>nft add rule inet filter input ip protocol tcp tcp dport 22 ct state new accept
用集合(set)+ limit 实现多子网差异化策略
若需为多个特定子网设置不同限速阈值(如办公网段宽松、公网段严格),可用 set 存储子网列表,并搭配 limit 规则逐条匹配:
- 定义命名集合,例如
trusted_nets存放 10.10.0.0/16、172.16.0.0/12 - 为信任子网设高限速(如 50/second),为默认公网设低限速(如 3/second)
- 规则顺序很重要:更具体的子网规则必须放在通用规则之前
片段示意:
nft add set inet filter trusted_nets { type ipv4_addr; flags interval; }<br>nft add element inet filter trusted_nets { 10.10.0.0/16, 172.16.0.0/12 }<br><br># 信任子网:宽松限速<br>nft add rule inet filter input ip saddr @trusted_nets tcp dport 80 limit rate 50/second burst 20 accept<br><br># 所有其他来源:严格限速<br>nft add rule inet filter input tcp dport 80 limit rate 3/second burst 2 counter drop
结合 conntrack 实现并发连接数控制
仅控请求频率不够,还需防 SYN Flood 或连接耗尽。nftables 支持 ct count 和 ct state new 组合实现每子网并发连接数限制:
- 用
ct count统计当前处于new状态的连接数 - 配合
ip saddr和子网掩码(需用ip saddr & 255.255.255.0形式模拟 /24 分组,但注意 nftables 不支持动态掩码运算) - 更实用的方式:用
ct mark标记后,再用ct count查该 mark 下的新连接数
例如:任一 /24 子网内,同时新建连接不得超过 30 个:
# 假设已在 subnet_limit 链中为各子网设置了不同 mark 值<br>nft add rule inet filter input ct mark 1 ct count over 30 counter drop
持久化与调试要点
配置完务必保存并验证:
- 导出规则集:
nft list ruleset -n -a > /etc/nftables.conf - 启用开机启动:
systemctl enable nftables && systemctl start nftables - 查看实时计数器:
nft list chain inet filter input -n,观察counter packets是否增长 - 测试时建议先用
log替代drop,确认匹配逻辑无误后再启用丢弃
注意:nftables 的 limit 是 per-rule 计数,不是 per-source-group;真正实现“哈希限速”语义需靠外部标记机制(如 ct mark)辅助,这是与 iptables-hashlimit 的关键差异。不复杂但容易忽略。











