不能用一条multiport规则封上千端口,因硬性限制最多15个;应按风险等级分组(每组≤15端口)、用ipset白名单优化源判断、结合conntrack仅阻断new连接,并同步清理nat表dnat及forward链规则。

不能用一条 multiport 规则封闭上千端口——它硬性限制最多 15 个端口(或端口段),超限直接报错 too many ports specified。想高效封堵大量漏洞端口,关键不是“堆数量”,而是“分组+聚合+前置过滤”。
按风险等级和协议分组,每组≤15个端口
把上千端口按用途、暴露面、漏洞严重度归类,例如:
- 高危调试端口:3000, 3001, 3002, 5000, 5001, 8000, 8001, 8080, 8081, 9000, 9001, 9002, 9200, 9300, 9600
- 数据库默认端口:3306, 5432, 6379, 27017, 27018, 27019, 11211, 2181, 9092, 9093, 8443, 8444, 8545, 8546, 8547
- 开发/测试服务端口:4000, 4200, 4500, 5005, 5555, 6006, 6666, 7000, 7070, 7777, 8888, 8889, 9999, 10000, 10001
每组严格控制在 15 个以内,分别写一条 -m multiport --dports DROP 规则。这样 1000 个端口只需约 67 条规则,远少于逐条写 1000 条。
用 ipset 绑定 IP 段 + 端口组,避免规则爆炸
如果只对公网封禁、内网保留访问,不要给每个端口加 -s ! 192.168.0.0/16 这类条件——它会让规则数翻倍且匹配变慢。正确做法是:
- 先建 ipset 白名单:
ipset create internal_nets hash:net,再批量添加可信网段 - 用一条规则放行白名单所有端口:
iptables -I INPUT 1 -m set --match-set internal_nets src -j ACCEPT - 后续所有
multiport DROP规则都无需加源地址判断,天然只作用于非白名单流量
这样既保持规则简洁,又实现“内网全通、外网严控”的安全边界。
结合 conntrack 状态,只封新建连接
封端口不是封数据包,而是封“新连接”。错误写法:-p tcp --dport 5000 -j DROP 会拦截每一个 TCP 包,包括已建立连接的重传、ACK 等,影响稳定性。
正确写法必须带状态检查:
iptables -A INPUT -p tcp -m multiport --dports 5000,5001,5002 -m conntrack --ctstate NEW -j DROP- 确保前面已有
-m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT规则,保障已有会话不受影响
这样 DROP 只触发在三次握手第一个 SYN 包,既精准阻断攻击入口,又不干扰正常业务流。
配合 nat 表清理转发残留,防止绕过
很多漏洞端口是通过 DNAT 暴露到公网的(比如容器映射、反向代理后端)。仅在 filter 表封 INPUT 不够——攻击者可能直连内部 IP 或利用 FORWARD 链绕过。
- 检查
iptables -t nat -L PREROUTING,删掉所有指向漏洞端口的 DNAT 规则 - 在
FORWARD链同步封端口:iptables -A FORWARD -p tcp -m multiport --dports 5000,5001,... -m conntrack --ctstate NEW -j DROP - 若启用了 MASQUERADE/SNAT,也检查
POSTROUTING是否存在异常出口映射
端口封堵必须覆盖 nat 和 filter 两张表,否则策略形同虚设。











