# Firewalld 防火墙
# 1. Firewalld 基本介绍
# 1.1 什么是 Firewalld
在 Centos7 系统集成了多款防火墙管理工具,默认启用的是 Firewalld(动态防火墙管理器),Firewalld 支持 CLI 及 GUI 的两种管理方式。
对于接触 Linux 较早的人员对 Iptables 比较熟悉。
由于 Iptables 的规则比较麻烦,并且网络有一定要求,所以学习成本较高。
但是 Firewalld 的学习对网络并没有那么高的要求,相对 Iptables 来说要简单不少。

# 1.2 Firewalld 默认策略
如果开启 Firewalld 防火墙,默认情况会阻止流量流入,但允许流量流出。

# 2. Firewalld 区域概念
相较于传统的 Iptables 防火墙,firewalld 支持动态更新,并加入了区域 zone 的概念。
# 2.1 什么是区域
简单来说,区域就是 firewalld 预先准备了几套防火墙策略集合(策略模板),用户可以根据不用的场景而选择不同的策略模板,从而实现防火墙策略之间的快速切换。

# 2.2 区域与网络接口
一个网卡仅能绑定一个区域,比如:eth0-->A 区域
但是一个区域可以绑定多个网卡,比如:B 区域 -->eth0、eth1
可以根据不同的策略来配置不同的规则,可以根据来源的地址设定不同的规则。比如:所有人能访问 80 端口,但只有公司的 IP 才允许访问 22 端口。
# 2.3 默认区域规则
| 区域 | 默认区域规则 |
|---|---|
| trusted(信任区域) | 允许所有的传入流量 |
| home(家庭区域) | 拒绝流入流量,除非与流出的流量相关;而如果流量与 ssh、mdns、ipp-client、amba-client 与 dhcpv6-client 服务相关,则允许流量 |
| internal(内部区域) | 等同于 home 区域 |
| work(工作区域) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh、ipp-client 与 dhcp6-client 服务相关,则允许流量 |
| public(公共区域) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh、dhcp6-client 与服务相关,则允许流量 |
| external(外部区域) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh 服务相关,则允许流量 |
| dmz(隔离区域也称为非军事区域) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh 服务相关,则允许流量 |
| block(限制区域) | 拒绝流入的流量,除非与流出的流量相关 |
| drop(丢弃区域) | 拒绝流入的流量,除非与流出的流量相关 |
# 3. Firewalld 命令语法
# 3.1 区域命令语法
--get-default-zone:查询默认区域的名称 | |
--set-default-zone=<区域名称>:设置默认的区域,使其永久生效 | |
--get-active-zones:显示当前正在使用的区域与网卡名称 | |
--get-zones:显示总共可用的区域 | |
--new-zone=<zone>:新增区域 |
# 3.2 接口命令语法
--add-interface=<网卡名称>:将源自该网卡的所有流量都导向某个指定区域 | |
--change-interface=<网卡名称>:将网卡关联至对应的区域 |
# 3.3 服务命令语法
--get-services:列出所有支持的服务名称 | |
--add-services:允许服务放行 | |
--remove-services:拒绝服务放行 | |
--query-services:查看服务是否放行 |
# 3.4 端口命令语法
--add-port=<端口号/协议>:允许端口放行 | |
--remove-port=<端口号/协议>:拒绝端口放行 |
# 3.5 管理命令语法
--list-all:显示当前区域的网卡配置参数、资源、端口以及服务等信息 | |
--reload:让"永久生效"的配置规则立即生效,并覆盖当前的配置规则 |
# 4. Firewalld 区域配置
# 4.1 查询区域及规则
firewalld 启动后,我们需要知道使用的是什么区域,区域的规则明细又有那些
#1、通过 --get-default-zone 获取当前默认使用的区域 | |
[root@route ~]# firewall-cmd --get-default-zone | |
public | |
#2、通过 --get-active-zone 查看当前正在使用的区域与网卡名称 | |
[root@route ~]# firewall-cmd --get-active-zone | |
public | |
interfaces: eth0 eth1 | |
#3、通过 --list-all 查看当前默认区域配置了哪些规则 | |
[root@route ~]# firewall-cmd --list-all | |
public (active) | |
target: default | |
icmp-block-inversion: no | |
interfaces: eth0 eth1 | |
sources: | |
services: dhcpv6-client ssh | |
ports: | |
protocols: | |
masquerade: no | |
forward-ports: | |
source-ports: | |
icmp-blocks: | |
rich rules: |
# 4.2 多区域组合应用
使用 firewalld 各个区域规则结合配置
调整默认 public 区域拒绝所有流量,但如果来源 IP 是 10.0.0.0/24 网段则允许
#1、临时移除默认区域的规则策略 | |
[root@route ~]# firewall-cmd --remove-service=ssh --remove-service=dhcpv6-client | |
#2、添加来源是 10.0.0.0/24 网段,将其加入白名单 (更精细化控制使用富规则) | |
[root@route ~]# firewall-cmd --add-source=192.168.40.0/24 --zone=trusted | |
#3、查看当前活动的区域 | |
[root@route ~]# firewall-cmd --get-active-zone | |
public | |
interfaces: eth0 eth1 | |
trusted | |
sources: 192.168.40.0/24 |
# 5. Firewalld 规则配置
# 5.1 配置端口规则
放行 80/tcp 端口流量
#1. 单个端口 (临时) | |
firewall-cmd --add-port=80/tcp | |
#2. 多个端口 (临时) | |
firewall-cmd --add-port={80/tcp,8080/tcp} | |
#3. 多个端口 (永久) | |
firewall-cmd --add-port={80/tcp,8080/tcp} --permanent | |
firewall-cmd --reload | |
#4. 查看放行端口 | |
firewall-cmd --list-ports | |
#5. 移除端口规则 (临时) | |
firewall-cmd --remove-port={80/tcp,8080/tcp} |
# 5.2 配置服务规则
放行 http、https 服务流量
#1. 放行单个服务 | |
[root@route ~]# firewall-cmd --add-service=http | |
#2. 放行多个服务 | |
[root@route ~]# firewall-cmd --add-service={http,https} | |
#3. 自定义服务名称 | |
[root@route ~]# cd /usr/lib/firewalld/services | |
[root@route ~]# cp ssh.xml zabbix-agent.xml | |
<?xml version="1.0" encoding="utf-8"?> | |
<service> | |
<short>zabbix-agent</short> | |
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description> | |
<port protocol="tcp" port="10050"/> | |
</service> | |
[root@route ~]# firewall-cmd --reload | |
[root@route ~]# firewall-cmd --add-service=zabbix-agent | |
#4. 查看火墙可以控制的所有服务 | |
[root@route ~]# firewall-cmd --get-services |
# 6. Firewalld 实现 NAT
# 6.1 DNAT 应用场景
- 基本概念:端口转发是指传统的目标地址映射,实现外网访问内网资源
- 实现原理:firewalld 使用的是代理方式来实现地址映射,会占用随机端口
- 实现语法:
firewall-cmd --permanent --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址> |
- 配置场景:将请求的 10.0.0.200:5555 端口转发至后端 172.16.1.9:22 端口

实现地址转换,类似于代理模式,而非地址替换
#1. 开启 forward 转发 | |
[root@route ~]# sysctl -p | |
net.ipv4.ip_forward = 1 | |
#2、配置转发规则 | |
[root@route ~]# firewall-cmd --add-forward-port=port=5555:proto=tcp:toport=22:toaddr=172.16.1.7 --permanent | |
[root@route ~]# firewall-cmd --reload | |
[root@route ~]# firewall-cmd --list-all | |
public (active) | |
target: default | |
icmp-block-inversion: no | |
interfaces: eth0 eth1 | |
sources: | |
services: dhcpv6-client ssh | |
ports: 80/tcp 8080/tcp | |
protocols: | |
masquerade: no | |
forward-ports: port=5555:proto=tcp:toport=22:toaddr=172.16.1.7 | |
source-ports: | |
icmp-blocks: | |
rich rules: | |
#3. 如果使用 iptables 实现 | |
iptables -t nat -I PREROUTING -d 192.168.40.200 --dport 5555 -j DNAT --to 172.16.1.0:22 |
# 6.2 SNAT 应用场景
在指定的带有公网 IP 的服务器上启动 firewalld 实现内部集群共享上网

#1. 开启 forward 转发 | |
[root@route ~]# sysctl -p | |
net.ipv4.ip_forward = 1 | |
#2.firewalld 开启 masquerade | |
[root@route ~]# firewall-cmd --add-masquerade --permanent | |
[root@route ~]# firewall-cmd --reload | |
[root@route ~]# firewall-cmd --list-all | |
public (active) | |
target: default | |
icmp-block-inversion: no | |
interfaces: eth0 eth1 | |
sources: | |
services: dhcpv6-client ssh | |
ports: 80/tcp 8080/tcp | |
protocols: | |
masquerade: yes | |
forward-ports: port=5555:proto=tcp:toport=22:toaddr=172.16.1.7 | |
source-ports: | |
icmp-blocks: | |
rich rules: | |
#3. 客户端将网关指向 firewalld 服务器,并配置号 DNS | |
[root@web01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1 | |
TYPE="Ethernet" | |
PROXY_METHOD="none" | |
BROWSER_ONLY="no" | |
BOOTPROTO="none" | |
DEFROUTE="yes" | |
IPV4_FAILURE_FATAL="no" | |
IPV6INIT="yes" | |
IPV6_AUTOCONF="yes" | |
IPV6_DEFROUTE="yes" | |
IPV6_FAILURE_FATAL="no" | |
IPV6_ADDR_GEN_MODE="stable-privacy" | |
NAME="eth1" | |
DEVICE="eth1" | |
ONBOOT="yes" | |
IPV6_PRIVACY="no" | |
IPADDR="172.16.1.7" | |
PREFIX="24" | |
GATEWAY=172.16.1.200 | |
[root@web01 ~]# ifdown eth0 | |
[root@web01 ~]# ifdown eth1 && ifup eth1 |
# 7. Firewalld 富规则策略
# 7.1 Rule 基本介绍
firewalld 中的富规则表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置,优先级在所有的防火墙策略中也是最高的。
# 7.2 Rule 命令语法
#富规则相关命令 | |
--add-rich-rule='<RULE>' #在指定的区添加一条富规则 | |
--remove-rich-rule='<RULE>' #在指定的区删除一条富规则 | |
--query-rich-rule='<RULE>' #找到规则返回 0,找不到返回 1 | |
--list-rich-rule #列出指定区里的所有富规则 |
# 7.3 Rule 执行顺序
查看设定的规则,如果没有添加 --permanent 参数则重启 firewalld 会失效。富规则按先后顺序匹配,按先匹配到的规则生效。
[root@route ~]# firewall-cmd --list-rich-rules |
# 7.4 Rule 场景示例 1
1、比如允许 10.0.0. 主机能够访问 http 服务,允许 172.16.1.0/24 能访问 10050 端口
[root@route ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 service name=http accept' | |
[root@route ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.16.1.0/24 port port="10050" protocol="tcp" accept' |
# 7.5 Rule 场景示例 2
默认 public 区域对外开放所有人能通过 ssh 服务连接,但拒绝 172.16.1.0/24 网段通过 ssh 连接服务器
firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.16.1.0/24 service name=ssh drop' |
# 7.6 Rule 场景示例 3
使用 firewalld,允许所有人能访问 http,https 服务,但只有 10.0.0.1 主机可以访问 ssh 服务
firewall-cmd --add-service={http,https} | |
firewall-cmd --remove-service=ssh | |
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 service name=ssh accept' |
# 7.7 Rule 场景示例 4
当用户来源 IP 地址是 10.0.0.1 主机,则将用户请求的 5555 端口转发至后端 172.16.1.9 的 22 端口
firewall-cmd --add-masquerate | |
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.1/32 forward-port port=5555 protocol=tcp to-port=22 to-addr=172.16.1.9' |
