一、firewalld 核心概念

概念

说明

区域(Zone)

预定义的安全级别集合,按信任度从高到低:trusted(完全信任)→ homeworkpublic(默认)→ externaldmzblockdrop(拒绝所有)

服务(Service)

预定义的端口 / 协议组合(如 ssh 对应 22/tcp、http 对应 80/tcp),无需手动指定端口号

端口(Port)

直接开放单个或范围端口(如 8080/tcp、1000-2000/udp),适用于非预定义服务

二、启停命令

类型

命令

查看状态

sudo systemctl status firewalld

停止(临时关闭,重启后恢复)

sudo systemctl stop firewalld

重启(配置变更后需重启或重载)

sudo systemctl restart firewalld

重载(推荐!动态加载配置,不中断现有连接)

sudo firewall-cmd --reload

查看当前区域的所有规则(端口/服务/转发等)

sudo firewall-cmd --list-all

开机自启动

sudo systemctl enable firewalld

禁用开机启动

systemctl disable --now firewalld

三、端口控制命令

类型

命令

开放指定端口

sudo firewall-cmd --add-port=3306/tcp --add-port=53/udp --permanent && sudo firewall-cmd --reload

开放端口范围

sudo firewall-cmd --add-port=1000-2000/tcp --permanent && sudo firewall-cmd --reload

移除端口

sudo firewall-cmd --remove-port=8080/tcp --permanent && sudo firewall-cmd --reload

端口转发

# 1. 临时启用 ip_forward(重启后失效)
echo 1 > /proc/sys/net/ipv4/ip_forward

# 2. 永久启用 ip_forward(修改 sysctl 配置)
vi /etc/sysctl.conf
# 添加/修改:net.ipv4.ip_forward = 1
sysctl -p  # 生效

# 3. 配置端口转发(临时):将 80/tcp 转发到 8080/tcp
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:to-port=8080

# 4. 永久配置转发(需指定区域,如 public)
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:to-port=8080 --permanent && sudo firewall-cmd --reload

# (可选)转发到其他主机(如将本地 80 转发到 192.168.1.100:8080)
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:to-port=8080 --permanent && sudo firewall-cmd --reload

限制特定 IP 访问

# 永久允许 192.168.1.0/24 网段访问 ssh(22/tcp)
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' --permanent

# 永久拒绝 10.0.0.5 访问 80 端口
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.5" port port="80" protocol="tcp" reject' --permanent && sudo firewall-cmd --reload

允许特定 IP 段访问所有端口(信任网段)

sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="172.16.0.0/16" accept' --permanent && sudo firewall-cmd --reload

四、实际案例

案例

说明

命令

多网卡多区域隔离(Web 服务器 + 内网数据库场景)

一台服务器部署 Web 服务(80/443 端口) 和 MySQL 数据库(3306 端口),需实现:

  • 网卡 eth0 接公网(信任度低),绑定 dmz 区域,仅开放 80/443(对外提供 Web 服务);

  • 网卡 eth1 接内网(信任度高),绑定 internal 区域,仅开放 3306(供内网应用访问数据库);

  • 禁止公网直接访问 3306 端口,禁止内网无意义端口暴露。

##板顶网卡目标区域
# 将 eth0 绑定到 dmz 区域(公网服务区)
firewall-cmd --zone=dmz --add-interface=eth0 --permanent

# 将 eth1 绑定到 internal 区域(内网信任区)
firewall-cmd --zone=internal --add-interface=eth1 --permanent

# 验证绑定结果(应显示对应区域)
firewall-cmd --get-zone-of-interface=eth0  # 输出:dmz
firewall-cmd --get-zone-of-interface=eth1  # 输出:internal

###2、按区域开放端口
# dmz 区域(eth0 公网):开放 80(HTTP)、443(HTTPS)
firewall-cmd --zone=dmz --add-port=80/tcp --add-port=443/tcp --permanent

# internal 区域(eth1 内网):开放 3306(MySQL),仅允许内网网段访问(通过富规则增强安全)
firewall-cmd --zone=internal --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept' --permanent

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

##3、验证配置
# 查看 dmz 区域规则(应包含 80/tcp、443/tcp)
firewall-cmd --zone=dmz --list-all

# 查看 internal 区域规则(应包含 3306/tcp 的富规则)
firewall-cmd --zone=internal --list-all

# 查看所有区域的网卡绑定关系
firewall-cmd --list-all-zones | grep -E "Zone|interface"

单网卡单区域 + IP 限制(仅内网访问的应用服务)

一台服务器仅一张网卡 eth0,部署内网办公系统(端口 8080/tcp),需实现:

  • 绑定 public 区域(默认区域,无需额外绑定网卡);

  • 仅允许内网 10.0.0.0/16 网段访问 8080 端口;

  • 拒绝其他所有 IP 访问 8080 端口。

1. 按区域 + IP 限制开放端口(永久生效)

# public 区域:仅允许 10.0.0.0/16 访问 8080/tcp(富规则实现IP限制)
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/16" port port="8080" protocol="tcp" accept' --permanent

# (可选)拒绝所有其他IP访问 8080(默认未匹配规则会拒绝,显式配置更清晰)
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" port port="8080" protocol="tcp" reject' --permanent

# 重载配置
sudo firewall-cmd --reload

2. 验证配置

# 查看 public 区域的富规则
sudo firewall-cmd --zone=public --list-rich-rules

五、配置管理(备份/恢复/导出)

类型

命令

备份当前配置

# 备份到 /etc/firewalld/backup/ 目录(自动生成时间戳)
sudo firewall-cmd --runtime-to-permanent  # 先将临时规则同步到永久配置
cp -r /etc/firewalld/ /etc/firewalld_backup_$(date +%Y%m%d)

恢复配置(从备份目录)

sudo systemctl stop firewalld
rm -rf /etc/firewalld/
cp -r /etc/firewalld_backup_20241001/ /etc/firewalld/
sudo systemctl start firewalld

导出配置为 XML 文件

sudo firewall-cmd --zone=public --list-all --permanent --xml > public_zone.xml

六、日志

# 实时查看 firewalld 日志
sudo journalctl -u firewalld -f

# 查看内核防火墙日志(iptables 底层日志)
sudo dmesg | grep -i firewall