iptables 的 mangle 表配合 ipset 可构建低延迟、高扩展的动态防火墙:mangle 在早期链(如 PREROUTING)用 -m set 标记流量,filter 表依据 MARK 或 ipset 统一裁决,实现 O(1) 匹配与解耦控制。

用 iptables 的 mangle 表配合 ipset,能构建出响应快、开销低的动态防火墙——不依赖状态跟踪,不走 conntrack 路径,适合高频封禁、标记分流或轻量级 QoS 场景。
mangle 表的核心用途不是过滤,而是打标与改包
mangle 表在 raw 之后、nat 和 filter 之前生效,所有五条链(PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING)都支持。它不决定“放不放行”,而是给数据包添加内核可识别的标记(如 MARK 或 CONNMARK),后续链(比如 filter 的 INPUT)可基于标记快速决策。
- 常用动作:–jump MARK –set-mark 0x1、–jump CONNMARK –save-mark
- 典型位置:PREROUTING 链中做入口标记,OUTPUT 或 POSTROUTING 中做出口标记
- 优势:标记操作在内核路径早期完成,不触发连接状态检查,延迟极低
ipset 提供 O(1) 级别的 IP/端口批量匹配能力
相比在 filter 表里写上百条 -s 1.2.3.4 -j DROP,ipset 把成千上万个 IP 存在哈希内存结构中,单次查表耗时恒定。mangle 表本身不直接支持 ipset 匹配,但可通过 -m set --match-set 模块在 mangle 链中调用:
- 创建高效集合:
ipset create badips hash:ip maxelem 65536 - 在 PREROUTING 中标记可疑流量:
iptables -t mangle -A PREROUTING -m set --match-set badips src -j MARK --set-mark 0x100 - 后续在 filter 表中统一拦截:
iptables -A INPUT -m mark --mark 0x100 -j DROP
这样就把“判断逻辑”下沉到 mangle,“执行动作”收敛到 filter,解耦清晰,规则数量几乎不随黑名单规模增长。
组合配置的典型工作流
以自动封禁暴力破解 SSH 的源 IP 为例,整个流程无需重启规则、不依赖日志轮转脚本:
- 先建 ipset:
ipset create sshblock hash:ip timeout 300(带 5 分钟自动过期) - 在 mangle PREROUTING 中检测并标记 SSH 新连接:
iptables -t mangle -A PREROUTING -p tcp --dport 22 -m state --state NEW -j SET --add-set sshblock src - 在 filter INPUT 中拦截已标记的源:
iptables -A INPUT -m set --match-set sshblock src -j DROP - 运维只需定时运行
ipset add sshblock 192.168.1.100 timeout 600即可动态加白/加黑
注意事项与避坑点
这套组合虽轻量,但几个细节不注意容易失效:
- mangle 表的规则必须加 -t mangle 显式指定表名,否则默认进 filter
- ipset 默认不持久化,重启后清空;需搭配
ipset save > /etc/ipset.conf和开机ipset restore < /etc/ipset.conf - 不要在 mangle 表中混用 -j DROP(mangle 不该做最终裁决),裁决应交给 filter 表完成
- 若需标记后继续处理(如同时记录日志),可用 -j CONNMARK --save-mark 保证连接双向一致

















