最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何在Linux中配置具体的系统级防火墙动态黑名单同步与更新任务
时间:2026-07-19 17:49:54 编辑:袖梨 来源:一聚教程网
firewalld用rich rule做动态IP黑名单必须加--permanent并执行--reload,否则临时规则在重载后消失;reject用于调试,drop用于静默丢弃;批量封禁推荐--direct直写iptables以提升性能。
firewalld 用 rich rule 做动态 IP 黑名单,必须加 --permanent
临时规则(不带 --permanent)在 firewall-cmd --reload 后就消失,根本起不到“黑名单”作用。很多人测试时用 --add-rich-rule 看似生效,一重载或重启就清空,误以为脚本没跑通。
正确写法必须带 --permanent,且后续一定要 firewall-cmd --reload 才能让规则真正落地:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.44" reject'<br>sudo firewall-cmd --reload
-
reject会让客户端收到明确拒绝响应(如 Connection refused),适合调试;生产环境若需静默丢弃,换成drop - 同一个 IP 重复添加不会报错,但也不会叠加——firewalld 不允许重复规则,第二次执行会提示
ERROR: timeout或静默忽略 - 删除时必须用完全一致的字符串,包括引号位置和空格:用
--remove-rich-rule时,source address和reject顺序不能颠倒
黑名单批量更新要避免逐条调用 firewall-cmd
直接在 shell 循环里反复调用 firewall-cmd,每条规则都触发 D-Bus 通信和规则链重编译,100 个 IP 就可能卡住或超时。实际线上环境建议合并操作。
推荐做法是:先收集所有待封 IP,生成一个临时 rich rule 文件,再用 --direct 批量注入内核链:
sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 203.0.113.44 -j REJECT<br>sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 192.168.5.101 -j REJECT
-
--direct绕过 firewalld 抽象层,直写 iptables 规则,性能高、无延迟,适合高频封禁场景 - 规则插入位置由数字(如
0)控制优先级,数字越小越靠前,确保黑名单早于白名单生效 - 这种规则默认不持久,重启 firewalld 或系统后丢失,必须配合
firewall-cmd --runtime-to-permanent或手动保存到/etc/firewalld/direct.xml
同步任务必须校验规则是否真实生效
很多自动化脚本只关注“命令返回 0”,却没验证规则是否真进链表。常见失效原因包括:zone 绑定错网卡、rich rule 被其他规则覆盖、firewalld 服务未运行。
校验不能只看 firewall-cmd --list-all,得查底层链:
- 确认当前活跃 zone:
firewall-cmd --get-active-zones,确保目标 IP 是落在你操作的 zone(比如public)里 - 查 rich rule 是否写入:
firewall-cmd --zone=public --list-rich-rules - 查底层 iptables 是否命中:
sudo iptables -L INPUT -n -v | grep 203.0.113.44 - 模拟测试:从被封 IP 机器上
curl -v http://your-server:80,应看到Connection refused或超时
CentOS 7 上持久化黑名单要特别注意 service 状态
CentOS Linux 7.9 已于 2024 年 6 月停止维护,但仍在不少旧系统中运行。它的 firewalld 默认启用,但部分镜像预装了 iptables-services 并设为开机启动,导致 firewalld 实际被屏蔽——此时你往 firewalld 加的任何规则都不生效。
检查并修复步骤:
- 确认真正运行的是哪个服务:
systemctl is-active firewalld和systemctl is-active iptables只能有一个是active (running) - 若
iptables在跑,停用它:sudo systemctl stop iptables && sudo systemctl disable iptables - 启用 firewalld:
sudo systemctl enable --now firewalld - 验证:
firewall-cmd --state必须输出running,且iptables -L输出中不应出现你手动加的 DROP 规则
规则持久化本身没问题,但旧系统里 service 冲突比想象中更常见,不检查就写脚本,等于往空配置里填数据。