知识点简介
防火墙是服务器的第一道安全防线。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-cmd 和 iptables 直接操作规则,否则可能导致规则冲突。如果必须用原生 iptables 语法,建议关闭 firewalld 并单独使用 iptables 服务。
📌 容器环境注意
Docker 默认会操作 iptables 规则(--iptables=true),可能与 firewalld 产生冲突。如果你在用 Docker + firewalld,Docker 的端口映射(-p)需要手动在 firewalld 中开放,否则外部可能无法访问。