直接用一条带匿名集合的drop规则可单行封住上百非必需端口,核心是“只留必要、静默拦截、顺序正确”:先用ss命令确认真实监听端口,将必需端口填入{ },搭配ct state new drop实现新连接静默丢弃,且该规则必须置于所有ACCEPT规则之前。

直接用一条带匿名集合的 drop 规则,配合白名单思维和连接状态判断,就能在单行内干净封住上百个非必需端口——关键是“只留必要、静默拦截、顺序正确”。
先确认哪些端口真正在用
别靠记忆或文档列白名单。执行命令查实监听端口:
-
ss -tln看所有 TCP 监听端口(重点关注:22、:80、:443、:3306等) -
ss -uln看所有 UDP 监听端口(如:53、:123、:161) - 排除仅绑定
127.0.0.1的端口(如9000、9090),它们不需对外放行 - Docker 或 Kubernetes 节点上,检查
2376、10250、8443是否必须暴露
写一条精准的静默丢弃规则
把所有业务必需端口放进大括号,其余新连接一律不响应:
- TCP 封闭:
nft add rule inet filter input tcp dport != {22, 80, 443, 3000, 5044} ct state new drop - UDP 封闭:
nft add rule inet filter input udp dport != {53, 123} ct state new drop - != {…} 表示“目标端口不在该集合中”,不是“等于其中任意一个”
- ct state new 保证只拦新连接,已建立的 SSH、HTTP 流量完全不受影响
- drop 是关键:不回 SYN-ACK,也不发 RST,扫描器收不到任何响应,只能超时
规则顺序决定成败
这条 drop 规则必须放在所有 accept 规则之前,否则会被绕过。完整 input 链推荐顺序:
- 允许回环:
nft add rule inet filter input iifname "lo" accept - 放行已有连接:
nft add rule inet filter input ct state established,related accept - 显式放通 SSH(防锁死):
nft add rule inet filter input tcp dport 22 ct state new accept - 紧接着就是你的匿名集合 drop 规则
- 最后可加默认策略:
nft chain inet filter input '{ type filter hook input priority 0; policy drop; }'
为什么能优雅支撑上百端口
nftables 内核对匿名集合做的是哈希查找或位图匹配,不是逐条比对:
- 写
tcp dport != {22,80,443,...,9999}(含 120 个端口),内核一次查表就完成 - 若拆成 120 条独立
tcp dport 22 drop规则,内核要线性扫描最多 120 次 - 尤其在高并发入口链(input hook),性能差异非常明显
- 匿名集合不占命名空间,不需提前定义 set,改端口只需改一行命令
不复杂但容易忽略。

















