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 中开放,否则外部可能无法访问。

相关推荐
程序员爱钓鱼11 小时前
Rust Trait Object详解:dyn Trait与动态分发
后端·面试·rust
To_OC18 小时前
Next.js + Redis 构建笔记系统:Redis Hash 实战与性能优化
redis·后端·next.js
北斗落凡尘21 小时前
LangGraph 入门实战(11)--输出模式
后端·python·langchain
demo007x1 天前
Hermes-Agent 技术架构
前端·后端·agent
__zRainy__1 天前
Node系列 · Node基础:net 模块
后端·node.js
Diligently_1 天前
Anolis 系统更新与密码设置&磁盘扩容
java·后端·spring
kyson_1 天前
大文件切片上传:从“能传”到“可靠”的 Vue 3 + Java 全栈实现
后端
张龙6871 天前
uv 全面指南:比 pip 快 100 倍的 Python 包管理器,从安装到团队落地
后端·python
用户40966601317511 天前
Guava 不止有 Lists 和 Maps:Cache、EventBus、Multimap 实战
java·后端