用firewalld配合ipset封禁大量ip的核心是“一条规则管一个集合”,即创建hash:net类型blacklist集合,批量导入cidr段,再通过一条rich-rule绑定ipset实现高效封禁,避免规则爆炸。

用 firewalld 配合 ipset 封禁大量 IP,核心是“一条规则管一个集合”,避免逐条加 rich-rule 导致规则爆炸、性能下降。关键不在命令多不多,而在结构是否清晰、操作是否可维护。
先建一个专用的 IP 集合
ipset 类型必须匹配用途:封 IP 段就用 hash:net,别用 hash:ip(它只认单个地址)。
- 创建名为 blacklist 的集合:
firewall-cmd --permanent --new-ipset=blacklist --type=hash:net - 执行后会在
/etc/firewalld/ipsets/blacklist.xml生成配置文件,后续所有增删都基于这个文件 - 类型确认方式:
firewall-cmd --get-ipset-types,确保系统支持 hash:net
把 IP 段批量加进集合
手动一条条加只适合调试;生产环境务必用脚本批量导入,且要防误封自己。
- 准备纯文本文件
ip_list.txt,每行一个 CIDR 格式段,例如:192.168.100.0/24203.123.45.0/22 - 执行导入(注意:不加
--permanent会立即生效但不持久):while read ip; do firewall-cmd --permanent --ipset=blacklist --add-entry="$ip"; done - 务必在运行前检查文件内容,切勿包含你自己的公网或内网段
用一条规则封掉整个集合
这才是高效的关键——firewalld 不需要为每个 IP 段生成独立规则,只认集合名。
- 绑定集合到 drop 行为:
firewall-cmd --permanent --add-rich-rule='rule source ipset=blacklist drop' - 这条规则放在哪个 zone?默认用
public即可;如需更细粒度控制,可指定 zone:firewall-cmd --permanent --zone=public --add-rich-rule='rule source ipset=blacklist drop' - 注意:不要混用
--zone=drop,firewalld 的 drop zone 是预设区域,不是“丢弃动作”的意思
验证与日常维护
封完不验证等于没封;规则多了不清理,迟早出问题。
- 重载生效:
firewall-cmd --reload - 查看当前封了哪些段:
ipset list blacklist(不是 firewall-cmd 命令) - 删错了一条?马上回滚:
firewall-cmd --permanent --ipset=blacklist --remove-entry=192.168.100.0/24 && firewall-cmd --reload - 想临时停用整个黑名单?不用删规则,直接移除 rich-rule:
firewall-cmd --permanent --remove-rich-rule='rule source ipset=blacklist drop' && firewall-cmd --reload











