高效端口过滤关键在于结构设计与匹配优化:统一用inet协议族管理双栈,结合named set、连接状态和速率控制,避免堆砌规则。

用 nftables 实现高效的端口范围批量过滤,关键不在“堆规则”,而在结构设计和匹配路径优化。端口范围本身不是性能瓶颈,真正影响效率的是规则组织方式、匹配粒度和内核处理逻辑。合理利用协议族抽象、集合(set)与映射(map)、以及连接状态上下文,才能在万级端口或高频访问场景下保持亚毫秒响应。
用 inet 协议族统一管理 IPv4/IPv6 端口策略
避免为 IPv4 和 IPv6 分别写两套重复规则。直接使用 inet 协议族,一条规则同时覆盖双栈:
- 创建统一表:
nft add table inet filter - 定义输入链(默认 drop):
nft add chain inet filter input { type filter hook input priority 0; policy drop; } - 放行常用服务端口(含范围):
nft add rule inet filter input tcp dport { 22, 80, 443, 8000-8100 } ct state established,related accept - 对新连接做端口白名单限制(防扫描):
nft add rule inet filter input tcp dport { 22, 80, 443, 8000-8100 } ct state new limit rate 5/minute burst 10 packets counter name port_whitelist
注意:nftables 支持 8000-8100 这类连续端口范围语法,内核会自动展开为高效位图或区间匹配,无需手动拆解。
用 named set 管理动态端口组,提升可维护性
当端口数量多(如开放 50+ 个非标准端口)、或需频繁增删时,硬编码在规则里难维护且易出错。改用命名集合(named set),规则只引用一次,内容可独立更新:
- 创建端口集合:
nft add set inet filter web_ports { type inet_service; } - 批量添加端口:
nft add element inet filter web_ports { 80, 443, 3000, 5000, 8000-8080 } - 在规则中引用:
nft add rule inet filter input tcp dport @web_ports ct state established,related accept - 后续增删只需操作集合:
nft add element inet filter web_ports { 8443 }或nft delete element inet filter web_ports { 3000 }
集合类型 inet_service 是专为端口优化的,查找复杂度 O(1),支持范围、单值混合,比用字符串或数值型集合更安全高效。
结合连接状态与速率控制,区分合法流量与扫描行为
仅按端口放行不够——攻击者常轮换源 IP 扫描大量端口。必须叠加连接上下文判断:
- 丢弃无效连接尝试:
nft add rule inet filter input ct state invalid drop - 限制单 IP 对任意端口的新建连接速率:
nft add rule inet filter input ct state new limit rate 10/minute burst 20 packets counter name scan_protection - 对高危端口(如 22、3389)单独加强:
nft add rule inet filter input tcp dport { 22, 3389 } ct state new limit rate 3/minute burst 5 packets counter name ssh_rdp_limit - 允许已建立连接无条件通行:
nft add rule inet filter input ct state established,related accept(这条应放在所有限速规则之前)
这样既保证业务连通性,又让扫描行为在几秒内触发限速并被计数器捕获,便于后续脚本自动拉黑。
避免常见低效写法
以下做法看似直观,实则损害性能或可维护性:
- ❌ 不要为每个端口写一条独立规则(如
tcp dport 8000、tcp dport 8001…),规则越多,匹配遍历越慢; - ❌ 不要用
ip protocol tcp冗余匹配,tcp dport已隐含协议筛选; - ❌ 不要在同一链中混用
ct state new和ct state established的复杂组合,优先靠链顺序分层(established/related 放最前,new 限速放中间,invalid drop 放最后); - ❌ 不要依赖用户态脚本实时生成大量规则,应通过 set/map + counter/log 驱动自动化,保持规则静态、数据动态。
真正高效的批量端口过滤,是把“端口”当作数据维度来管理,而不是规则维度来堆砌。结构清晰、状态明确、动静分离,才能扛住真实生产环境的并发与变化。











