ipset 配合 iptables 是应对大规模 ip 黑名单性能最优方案,因 ipset 用哈希等高效结构实现 o(1) 查找,而纯 iptables 线性匹配导致 10 万规则时最坏需遍历全部,显著拖慢吞吐、增加 cpu 负载。

iptables 配合 ipset 是应对大规模 IP 黑名单(如数万至百万级)最实用、性能最优的方案之一。单纯用 iptables -s 链式匹配,规则越多,匹配越慢,内核需逐条遍历;而 ipset 将 IP(或网段、端口等)预构建为高效哈希或树结构,iptables 只需一次查表即可完成判断,吞吐几乎不受黑名单规模影响。
为什么不用纯 iptables 做大名单?
iptables 规则本质是线性链表。每包进入 INPUT/FORWARD 链时,从上到下依次比对条件。若黑名单有 10 万条 -s 1.2.3.4 --jump DROP,最坏情况要检查 10 万次才能匹配最后一条——这会显著拖慢连接建立、增加 CPU 负载,甚至导致丢包或服务延迟。
ipset 把海量 IP 归入一个命名集合(如 blackv4),底层用高效的内核数据结构(hash:ip、hash:net、list:set 等)索引。iptables 只需一条规则:-m set --match-set blackv4 src -j DROP,查一次哈希表即完成判定,平均时间复杂度 O(1)。
快速部署 ipset + iptables 黑名单流程
以下以 IPv4 黑名单为例,假设你有一份含 IP 的文本文件 blacklist.txt(每行一个 IP 或 CIDR,如 192.168.1.100 或 203.0.113.0/24):
- 安装并加载模块:apt install ipset(Debian/Ubuntu)或 yum install ipset(CentOS/RHEL),确保 ip_set_hash_ip 和 ip_set_hash_net 模块已载入(lsmod | grep ip_set_hash)
- 创建集合:ipset create blackv4 hash:net maxelem 2000000(支持最多 200 万网段/IP,可根据实际调整)
- 导入名单:while read ip; do [ -n "$ip" ] && ipset add blackv4 "$ip"; done
- 添加 iptables 规则:iptables -I INPUT -m set --match-set blackv4 src -j DROP(-I 插入最前,确保优先生效)
- 保存规则(持久化):ipset save blackv4 > /etc/ipset.blackv4;iptables-save > /etc/iptables.rules;再配置开机自动 restore(如通过 systemd service 或 /etc/network/if-pre-up.d/ 脚本)
进阶技巧提升稳定性与可维护性
- 区分精度,混合使用类型:对单 IP 用 hash:ip,对大量小网段(如 /24)改用 hash:net;避免把 100 万个 /32 当作 net 导入,否则哈希冲突升高
- 动态更新不中断服务:用 ipset swap tempv4 blackv4 实现“先建新集、再原子切换”,避免 reload 过程中短暂放行
- 限制匹配速率防误伤:结合 hashlimit,例如只封连续 5 秒内发起 10 次失败 SSH 登录的源 IP,而非全量拉黑——用 -m hashlimit --hashlimit-name sshbrute --hashlimit-above 10/sec --hashlimit-burst 5 --hashlimit-mode srcip -j SET --add-set blackv4 src
- 监控与清理:定期用 ipset list blackv4 | wc -l 查数量;用 ipset timeout 支持自动过期(需创建时加 timeout 3600);对长期未触发的 IP 可脚本化清理
常见踩坑提醒
- 忘记加载内核模块(modprobe ip_set_hash_ip),导致 ipset create 失败
- 集合 maxelem 设太小,导入中途报 “Set is full”,建议按峰值预留 20% 余量
- iptables 规则未加 -m set 模块依赖,或拼写错误(如写成 --matchet)导致规则无效
- IPv6 黑名单需单独建 blackv6 集合,并配 ip6tables 规则,不能混用
- 云环境(如 AWS、阿里云)注意安全组/网络 ACL 在 iptables 前生效,黑名单需在更外层部署或确认流量路径










