应使用multiport合并端口规则,如iptables -i input 1 -p tcp -m multiport --dports 22,80,443,8080,9000 -m conntrack --ctstate new -j accept,配合conntrack状态匹配和ipset实现高效、安全、可扩展的访问控制。

用multiport合并端口,减少规则数量
当需要放行或拦截多个不连续端口(比如22、80、443、8080、9000)时,不要写5条独立的-p tcp --dport X -j ACCEPT。直接用-m multiport --dports把它们压成一条规则:
iptables -I INPUT 1 -p tcp -m multiport --dports 22,80,443,8080,9000 -m conntrack --ctstate NEW -j ACCEPT- 支持最多15个端口或端口段(如
21:25,80,443,3000:3005),语法紧凑,内核匹配一次完成 - 注意:multiport只支持tcp/udp协议,不适用于icmp或自定义协议
结合连接状态,避免重复判断
仅靠端口匹配不够安全,必须叠加连接跟踪条件。否则每条规则都会对每个新包做端口比对,浪费性能。
- 正确写法:
-m conntrack --ctstate NEW(只匹配新建连接)+--dports,确保只在首次握手时检查端口 - 已建立连接统一由前置规则处理:
iptables -I INPUT 2 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - 这样后续所有数据包跳过端口检查,直接放行,大幅降低匹配开销
端口转发场景下的multiport应用
DNAT本身在nat表中完成,但filter表的FORWARD链必须同步放开对应端口——这里最易堆积冗余规则。
- 例如将外部80/443/8080映射到内网Web服务器,FORWARD链只需一条:
iptables -I FORWARD 1 -d 10.0.1.100 -p tcp -m multiport --dports 80,443,8080 -m conntrack --ctstate NEW -j ACCEPT - 若还做了SNAT或MASQUERADE,确保OUTPUT链也按需放开源端口(用
--sports) - 禁止在FORWARD里混用
--dport和--sport逻辑,容易因方向错位导致策略失效
配合ipset做源地址+端口双维聚合
当不同IP段要访问不同端口组合时(如运维网段开22/9000,业务网段只开80/443),multiport单独不够用。
- 先建两个ipset:
ipset create ops_vips hash:net、ipset create app_nets hash:net - 再分别绑定端口组:
iptables -I INPUT 1 -m set --match-set ops_vips src -p tcp -m multiport --dports 22,9000 -m conntrack --ctstate NEW -j ACCEPTiptables -I INPUT 2 -m set --match-set app_nets src -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT - 这样既保持规则精简,又实现细粒度访问控制,且ipset查表是O(1),不随IP数量线性变慢











