Linux 防火墙管理 — firewalld 实战

知识点简介

防火墙是服务器的第一道安全防线。CentOS 7+/RHEL 8+ 默认使用 firewalld 作为防火墙管理工具,它基于内核的 nftables/iptables,提供动态管理的 zone(区域)模型,支持运行时和永久规则分离,比传统 iptables 更易用、更灵活。理解 firewalld 是运维工程师的必备技能。


核心命令整理

1️⃣ 服务与状态管理

命令 说明
systemctl status firewalld 查看防火墙运行状态
systemctl start firewalld 启动防火墙
systemctl stop firewalld 停止防火墙
systemctl enable firewalld 设置开机自启
systemctl disable firewalld 禁用开机自启
firewall-cmd --state 快速查看运行状态(running / not running)

2️⃣ 区域(Zone)管理

firewalld 通过 zone 管理规则,默认区域是 public

命令 说明
firewall-cmd --get-default-zone 查看默认区域
firewall-cmd --set-default-zone=trusted 修改默认区域
firewall-cmd --get-active-zones 查看活跃区域及绑定的网卡
firewall-cmd --zone=public --list-all 查看指定区域的完整配置
firewall-cmd --get-zones 列出所有可用区域

常用 Zone 说明:

  • drop --- 丢弃所有入站流量(最严格)
  • block --- 拒绝所有入站(返回 icmp-host-prohibited)
  • public --- 默认,仅允许选中的服务/端口
  • internal --- 内网区域,信任度较高
  • trusted --- 完全信任,放通所有流量

3️⃣ 服务与端口规则

bash 复制代码
# 允许服务(基于服务名)
firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=https

# 开放端口
firewall-cmd --zone=public --add-port=8080/tcp
firewall-cmd --zone=public --add-port=3000-4000/tcp  # 端口范围

# 移除规则
firewall-cmd --zone=public --remove-service=http
firewall-cmd --zone=public --remove-port=8080/tcp

# 🚨 永久生效(必须加 --permanent,且需要 reload)
firewall-cmd --permanent --zone=public --add-port=8443/tcp
firewall-cmd --reload

重要 :不加 --permanent 的规则仅运行时生效,重启后丢失。永久规则的修改需执行 firewall-cmd --reload 使配置生效。

4️⃣ 富规则(Rich Rules)

适用于更精细的管控,如限制来源 IP:

bash 复制代码
# 仅允许 192.168.1.0/24 访问 22 端口
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="22" accept'

# 拒绝特定 IP 访问
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.5" reject'

# 限制单位时间连接数(防暴力破解)
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="ssh" limit value="5/m" accept'

实操示例:安全加固 Web 服务器

场景:一台公网服务器,需开放 80/443 给所有用户,22 端口仅允许办公内网访问,数据库端口仅限内网连通。

bash 复制代码
# 1. 查看当前状态
firewall-cmd --state

# 2. 放通 Web 服务
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https

# 3. 限制 SSH 仅办公内网访问
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port protocol="tcp" port="22" accept'
# 移除默认的 ssh 服务放行(如果有)
firewall-cmd --permanent --zone=public --remove-service=ssh

# 4. 内网区域放通 MySQL(假设内网网卡为 eth1,区域设为 internal)
firewall-cmd --permanent --zone=internal --add-service=mysql
# 将 eth1 绑定到 internal 区域
firewall-cmd --permanent --zone=internal --add-interface=eth1

# 5. 重载配置使永久规则生效
firewall-cmd --reload

# 6. 验证规则
firewall-cmd --zone=public --list-all
firewall-cmd --zone=internal --list-all

常见坑点 / 注意事项

🚫 把自己锁在外面

bash 复制代码
# ❌ 危险操作:远程执行下面命令后 SSH 会立刻断开
firewall-cmd --zone=public --remove-service=ssh
firewall-cmd --reload

# ✅ 正确做法:先用富规则添加来源 IP 白名单,再移除 ssh 服务

安全操作口诀:先放行 → 确认连通 → 再删除默认规则。建议至少保留 2 个不同的远程访问通道(如 SSH + 带外管理)。

⚠️ --permanent 与 --reload 的关系

bash 复制代码
# 错误理解:
firewall-cmd --permanent --add-port=9090/tcp
# ↑ 此时规则不可见(未加载到运行时配置)

# 必须执行重载:
firewall-cmd --reload
# 此时 --permanent 规则会刷入运行时

Tips:调试阶段先不加 --permanent,确认规则生效后再补加一次 --permanent 版本。或者使用 --runtime-to-permanent 一键将当前运行时规则写入永久配置。

🔄 firewalld 与 iptables 的关系

firewalld 底层仍可调用 iptables,但规则管理方式不同。不要混用 firewall-cmdiptables 直接操作规则,否则可能导致规则冲突。如果必须用原生 iptables 语法,建议关闭 firewalld 并单独使用 iptables 服务。

📌 容器环境注意

Docker 默认会操作 iptables 规则(--iptables=true),可能与 firewalld 产生冲突。如果你在用 Docker + firewalld,Docker 的端口映射(-p)需要手动在 firewalld 中开放,否则外部可能无法访问。

相关推荐
Csvn1 小时前
`functools.lru_cache` —— 一行代码搞定缓存加速
后端·python
leeyi2 小时前
Multi-Agent:让多个 AI 分工协作完成复杂任务
后端·aigc·agent
长栎2 小时前
你的策略模式是 Map<String, Strategy>?那不过是最廉价的 if-else 替代品
后端
长栎2 小时前
你写的 abstract class 里全是钩子方法——模板模式不是让你填空,是让你别越界
后端
ping某2 小时前
语法树,到底是一棵什么形状的树?
后端
_柳青杨2 小时前
一文吃透 Node.js 事件循环:从原理到 Node 20+ 重大变更
javascript·后端
Alson_Code2 小时前
人机协作项目文档--HITL-AgentScope
后端·aigc·ai编程
IT_陈寒3 小时前
Java 并行流把我坑惨了,这6小时加班值了
前端·人工智能·后端
葫芦和十三3 小时前
图解 MongoDB 03|CRUD 全链路:一条 find 怎么穿过 WiredTiger
后端·mongodb·agent