CentOS / RHEL firewalld 防火墙操作手册
适用系统:CentOS 7/8、RHEL 7/8
防火墙工具:firewalld
整理自实际操作记录,可直接参照修改使用
一、基础概念
| 概念 | 说明 |
|---|---|
| firewalld | CentOS/RHEL 默认动态防火墙管理工具 |
| zone(区域) | 防火墙规则集合,默认使用 public zone |
--permanent |
规则永久生效,重启后不丢失(需配合 --reload) |
--reload |
重载配置使 permanent 规则立即生效 |
| rich rule | 富规则,支持按来源 IP、端口、协议精细控制 |
二、服务管理
启动 / 停止 / 重启
systemctl start firewalld # 启动
systemctl stop firewalld # 停止
systemctl restart firewalld # 重启
systemctl status firewalld # 查看运行状态
设置开机自启
systemctl enable firewalld # 开机自动启动
systemctl disable firewalld # 取消开机自启
验证是否运行
firewall-cmd --state
# 返回 running 表示正常
三、查看当前规则
# 查看所有规则(最常用)
firewall-cmd --list-all
# 只查看已开放的端口
firewall-cmd --list-ports
# 只查看富规则
firewall-cmd --list-rich-rules
# 查看已开放的服务
firewall-cmd --list-services
--list-all 输出示例说明:
public (active)
target: default
interfaces: eth0
services: ssh dhcpv6-client ← 已放行的服务
ports: 80/tcp 443/tcp 3306/tcp ← 已放行的端口(对所有人)
rich rules: ← 精细规则(可按 IP 控制)
四、端口管理
对所有人开放端口
# 开放单个端口(TCP)
firewall-cmd --permanent --add-port=1087/tcp
# 开放单个端口(UDP)
firewall-cmd --permanent --add-port=1087/udp
# 开放多个端口
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=8443/tcp
# 开放端口范围
firewall-cmd --permanent --add-port=8000-9000/tcp
# 重载生效
firewall-cmd --reload
关闭端口
firewall-cmd --permanent --remove-port=1087/tcp
firewall-cmd --reload
五、富规则(Rich Rule)--- 按 IP 精细控制
适用场景:只允许指定 IP 访问某端口,其他人拒绝
允许指定 IP 访问指定端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="1087" protocol="tcp" accept'
拒绝其他所有 IP 访问指定端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="1087" protocol="tcp" reject'
⚠️ 顺序很重要:allow 规则要先于 reject 规则添加,firewalld 按顺序匹配,指定 IP 先命中 accept 放行,其他 IP 往下匹配到 reject 拒绝。
完整示例:只允许两个 IP 访问 1087 端口
# 第一步:允许指定 IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="211.88.26.7" port port="1087" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="211.88.26.14" port port="1087" protocol="tcp" accept'
# 第二步:拒绝其他所有人
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="1087" protocol="tcp" reject'
# 第三步:重载生效
firewall-cmd --reload
# 第四步:验证
firewall-cmd --list-rich-rules
删除富规则
firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="211.88.26.7" port port="1087" protocol="tcp" accept'
firewall-cmd --reload
六、常见场景命令速查
场景 1:开放端口给所有人
firewall-cmd --permanent --add-port=端口号/tcp
firewall-cmd --reload
场景 2:只允许指定 IP 访问某端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="指定IP" port port="端口号" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="端口号" protocol="tcp" reject'
firewall-cmd --reload
场景 3:关闭某个端口
firewall-cmd --permanent --remove-port=端口号/tcp
firewall-cmd --reload
场景 4:限制 MySQL 3306 只允许应用服务器访问(安全加固)
# 先移除对所有人开放的 3306
firewall-cmd --permanent --remove-port=3306/tcp
# 只允许指定应用服务器 IP 访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="应用服务器IP" port port="3306" protocol="tcp" accept'
# 拒绝其他人
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="3306" protocol="tcp" reject'
firewall-cmd --reload
七、firewalld 与 Docker 共存问题
问题现象
启动 firewalld 时出现以下报错,随后服务自动退出:
WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -o docker0 -j DROP' failed
原因
Docker 自己管理 iptables 规则,firewalld 启动时尝试清理这些规则产生冲突。
解决方法
先启动 firewalld,再重启 Docker,让 Docker 在 firewalld 之后重新注册规则:
systemctl start firewalld
systemctl restart docker
systemctl status firewalld # 确认 active (running)
八、安全建议
| 建议 | 说明 |
|---|---|
| MySQL 3306 不要对公网全开 | 改为只允许应用服务器 IP 访问 |
| SSH 22 端口确认已放行再启动防火墙 | 避免把自己踢出服务器 |
| 使用非标准 SSH 端口时 | 启动防火墙前先手动 add-port,再 reload |
| 云服务器需同步配置安全组 | firewalld 和云控制台安全组是两层,都要放行 |
| 定期审查开放端口 | firewall-cmd --list-all 检查是否有多余的开放端口 |
九、故障排查
firewalld 启动后又停了
# 查看详细日志
journalctl -u firewalld -n 50 --no-pager
systemctl status firewalld
telnet 某端口不通
排查顺序:
-
确认 firewalld 规则是否已加:
firewall-cmd --list-all -
确认服务是否在监听该端口:
ss -tlnp | grep 端口号 -
云服务器还需检查控制台安全组是否放行
查看端口监听情况
ss -tlnp | grep 1087
测试连通性
telnet 目标IP 端口号
查看防火墙日志
tail -f /var/log/firewalld