linux服务-firewalld原理及示例详解
Firewalld 原理及示例详解
一、 防火墙简介与核心原理
在深入配置之前,理解
firewalld的工作原理及其与底层框架的关系至关重要。
1.1、firewalld、iptables、netfilter的关系
-
原理说明
-
netfilter: 这是 Linux 内核中内置的一套网络数据包处理框架,它是防火墙的 “心脏”。它负责检查、修改、转发或丢弃网络数据包。
-
iptables: 这是一个命令行工具,是
netfilter的 “用户态接口”。管理员通过iptables命令直接与netfilter交互,定义具体的数据包处理规则(如允许、拒绝、转发等)。 -
firewalld:这是一个动态防火墙管理工具,它是
iptables的 “前端” 或 “封装层”。它不直接操作netfilter,而是提供了更友好、更高级的抽象(如区域、服务),并在后台将用户的配置转换为iptables规则。
-
-
分层示意图(从上到下:用户操作 → 内核处理)
+-------------------------------------------------------------------------+ | 第一层:用户空间(管理员操作界面) | | [ firewalld ] [ iptables 命令行 ] | (动态防火墙管理工具) (直接操作netfilter的命令工具) | - 提供区域、服务、富规则等高级抽象 - 直接编写链和规则,无抽象 | - 后台自动转换为iptables规则 - 需手动管理规则顺序和持久化 +-------------------------------------------------------------------------+↓(firewalld生成的规则最终通过iptables工具提交) +-------------------------------------------------------------------------+ | 第二层:内核空间(netfilter框架) | | [ netfilter 核心模块 ] | - 内核内置的数据包处理引擎(防火墙“心脏”) | - 包含钩子函数(如INPUT、OUTPUT、FORWARD),拦截网络数据包 | - 执行匹配规则(允许、拒绝、转发、修改) +-------------------------------------------------------------------------+↓(处理后的数据包继续流转或被丢弃) +-------------------------------------------------------------------------+ | 第三层:网络协议栈(TCP/IP协议族) | | [ 网卡 → 链路层 → 网络层 → 传输层 → 应用层 ] | - 数据包的接收、解析、封装和发送 +-------------------------------------------------------------------------+ -
核心关系比喻
组件 对应安保角色 / 设备 核心作用 netfilter 小区安保核心(保安团队 + 门禁系统) 内核级 “硬件”,负责拦截所有进出小区的 “数据包人员”,执行检查 / 放行 / 拦截动作 iptables 保安手里的 “纸质登记本” 用户态工具,直接定义 “登记规则”(如:“允许 1 号楼住户进入”“拒绝陌生车辆入内”),需手动编写和维护 firewalld 小区智能安保管理平台(APP / 中控) 高级管理工具,提供 “区域分组”(如:住户区、访客区、办公区)、“服务白名单”(如:快递员、维修员)等简化操作,后台自动将配置转化为 “纸质登记本规则” -
数据包流转流程(实际工作逻辑)
以 外部机器访问服务器 80 端口(HTTP 服务) 为例:
- 数据包到达服务器网卡,进入内核网络协议栈;
- netfilter 钩子函数拦截数据包(如 INPUT 链,针对流入本机的数据包);
- 检查规则来源:
- 若管理员用
firewalld配置过 “允许 HTTP 服务”,则firewalld已提前将该配置转化为 iptables 规则(如:-A INPUT -p tcp --dport 80 -j ACCEPT),并提交给netfilter; - 若管理员直接用
iptables命令编写过该规则,netfilter会直接读取;
- 若管理员用
- netfilter 执行规则:匹配到 “允许 80 端口 TCP 协议”,数据包被放行,继续向上层协议栈传递,最终到达 HTTP 应用程序;
- 若未匹配到允许规则,
netfilter执行默认策略(如丢弃数据包),外部机器无法访问。
-
核心区别总结
特性 netfilter iptables firewalld 所处层面 内核空间(核心引擎) 用户空间(命令工具) 用户空间(管理工具) 操作方式 内核自动执行,无直接接口 手动编写链和规则 图形化 / 命令行(抽象配置) 核心优势 高效、内核级集成 灵活、无依赖 动态重载、简化复杂配置 适用场景 所有 Linux 防火墙的底层依赖 简单规则、脚本自动化 多区域、动态规则、日常运维 - 最后我们能清晰理解三者的 “分层协作” 关系:firewalld 简化配置,iptables 作为桥梁,netfilter 负责实际数据包处理。
1.2、firewalld的核心优势
- 动态配置:
firewalld支持动态加载规则,通过firewall-cmd --reload命令可以在不重启服务、不中断现有网络连接的情况下应用新的配置。这是它相比传统iptables服务最大的优势。 - 区域(Zone)管理:
firewalld将网络环境按信任级别划分为不同的区域(如public,home,trusted)。每个区域可以有独立的防火墙策略,简化了多场景下的规则管理。 - 服务(Service)抽象:预定义了常见服务(如
ssh,http,https)及其对应的端口和协议,使得配置更加简单直观。 - 富规则(Rich Rule):支持创建复杂的、条件化的规则,例如基于源 IP 地址、端口范围、协议、日志记录、连接速率限制等组合条件来允许或拒绝流量。
二、 核心概念详解
2.1、区域(Zone)
区域(Zone)是 firewalld 最核心的设计,本质是按网络信任等级划分的 “规则集合容器” —— 每个区域预设了不同严格程度的防火墙策略,通过将网络接口绑定到对应区域,实现对不同网络环境的差异化安全管控。
-
核心概念拆解
- 本质是 “规则分组”:每个区域都包含一套独立的防火墙规则(允许 / 拒绝的服务、端口、IP 等),相当于为不同网络环境定制的 “安全模板”。
- 核心关联 “网络接口”:服务器的每个网络接口(如 eth0、wlan0)必须绑定到一个区域(默认绑定 public 区域),数据包通过该接口流入 / 流出时,会自动应用其绑定区域的规则。
- 信任等级决定规则严格度:区域按 “信任度从高到低” 排序,信任度越高,规则越宽松;信任度越低,规则越严格(默认拒绝的请求越多)。
-
内置区域(按信任度从高到低排序):
区域名称(Zone) 信任级别 核心特点与适用场景 trusted 最高 允许所有网络连接,无任何限制,适用于完全可信的内部网络环境。 home 高 信任网络内其他计算机,仅开放家庭场景必要服务(如文件共享、打印机等),适用于家庭网络。 internal 高 与 home 区域特性类似,侧重内部办公或私有网络,信任同网段设备,开放基础内部服务。 work 中 信任网络内其他计算机,但限制比 home/internal 更严格,仅开放工作必需服务(如邮件、办公软件),适用于办公网络。 public 中低 默认区域,不信任网络内其他设备,仅开放最基础的公共服务(如 ssh、http/https),适用于公共网络(如咖啡馆、机房外网)。 external 低 用于防火墙作为网关的外部网络,开启 NAT 伪装功能,保护内网地址不暴露,适用于路由器对外接口场景。 dmz 低 放置公开可访问的服务器(如 Web 服务器),限制其对内网的访问,隔离外网风险,适用于服务器对外提供服务的场景。 block 最低 拒绝所有传入网络连接,仅允许本机主动发起的传出连接,不返回拒绝响应。 drop 最低 丢弃所有传入网络连接,无任何响应,仅允许本机传出连接,安全性最高,隐蔽性强。 -
关键注意点
- 一个接口只能绑定一个区域:但一个区域可以绑定多个接口(如多块外网网卡可同时绑定 public 区域);
- 默认区域的作用:未手动绑定区域的接口,会继承默认区域(默认 public)的规则
- 规则优先级:区域内的规则(富规则 > 服务 / 端口规则)仅对绑定该区域的接口生效,不同区域的规则互不干扰。
2.2、服务(Service)
服务(Service)是 firewalld 中用于简化端口管理的核心抽象,其本质是将特定应用的“端口+协议+辅助配置”封装为一个可直接调用的逻辑单元。例如,http 服务对应 80/tcp 端口,ssh 服务对应 22/tcp 端口,相比直接配置端口,服务能避免记忆复杂的端口号和协议组合,同时支持更灵活的场景适配(如多端口服务、辅助模块加载等),是 firewalld 日常配置的首选方式。
服务配置文件:
| 路径 | 类型 | 优先级 |
|---|---|---|
/usr/lib/firewalld/services/ | 系统预定义的服务文件 | 低 |
/etc/firewalld/services/ | 用户自定义的服务文件 | 高 |
2.3、富规则(Rich Rule)
富规则是 firewalld 实现精细化防火墙管控的核心工具,解决基础端口/服务配置无法满足的复杂场景。它允许你组合多个条件(如源 IP、目标 IP、端口、协议、MAC 地址等)并执行更复杂的动作(如允许、拒绝、日志记录、限速等)。
-
语法说明
参数结构 核心含义 必填性 family=“ipv4|ipv6” 指定网络协议版本,默认适配ipv4+ipv6 可选 source address=“IP/掩码” [invert=“True”] 来源IP条件,invert=True表示反向匹配(除指定IP外) 可选(核心条件之一) destination address=“IP/掩码” [invert=“True”] 目标IP条件,用法同source 可选 service name=“服务名” 指定服务(如ssh、http),关联预定义端口协议 可选(与port二选一) port port=“端口” protocol=“tcp|udp” 指定端口+协议,适用于无预定义服务的场景 可选(与service二选一) log prefix=“日志前缀” level=“日志级别” 记录匹配日志,级别:debug/info/warning/err/crit 可选 limit value=“速率/时长” 限制连接速率,防止暴力攻击 可选 accept|reject|drop 最终动作:允许/拒绝(返回提示)/丢弃(无提示) 必选
2.4、运行时配置与永久配置
firewalld 支持两种配置模式,分别适配“临时测试”和“长期部署”场景,核心区别在于配置的生效时机和持久化能力。
-
运行时配置 (
runtime):- 配置立即生效,但仅在当前
firewalld服务运行期间有效。 - 重启
firewalld服务或重启系统后,配置会丢失。 - 不带
--permanent参数的firewall-cmd命令修改的是运行时配置。
- 配置立即生效,但仅在当前
-
永久配置 (
permanent):- 配置被保存在
/etc/firewalld/目录下的 XML 文件中。 - 不会立即生效,需要通过
firewall-cmd --reload命令重载配置才能生效。 - 重启
firewalld服务或系统后,配置依然保留。 - 使用
--permanent参数的firewall-cmd命令修改的是永久配置。
- 配置被保存在
-
核心差异对比表
对比维度 运行时配置(Runtime) 永久配置(Permanent) 生效速度 立即生效 需 --reload后生效存储位置 内存中 /etc/firewalld/目录 XML 文件重启后状态 丢失 保留 操作参数 无 --permanent带 --permanent典型用途 临时测试、短期授权 生产环境长期策略
最佳实践:为了让配置立即生效且永久保存,可以同时执行运行时和永久配置命令,然后重载。
| 操作需求 | 命令组合 | 效果说明 |
|---|---|---|
| 仅临时开放 http 服务(重启丢失) | firewall-cmd --add-service=http | 执行后立即生效,重启 firewalld 或系统后,http 服务自动关闭 |
| 仅永久开放 http 服务(需重载生效) | firewall-cmd --permanent --add-service=httpfirewall-cmd --reload | 第一条命令写入配置文件,第二条命令重载后生效;重启后配置保留 |
| 临时+永久开放 http 服务(立即生效且保留) | firewall-cmd --permanent --add-service=httpfirewall-cmd --add-service=http | 第一条命令做永久配置,第二条命令做临时配置;无需重载即可立即生效,且重启后保留 |
| 取消配置(对应永久/临时) | 永久取消:firewall-cmd --permanent --remove-service=http临时取消:firewall-cmd --remove-service=http均需配合 --reload(永久取消时) | 取消命令需与配置命令的“永久/临时”属性对应,否则无法正确删除 |
2.5、基础操作命令
-
服务管理
命令 说明 systemctl start firewalld.service立即启动防火墙服务,仅当前会话有效 systemctl stop firewalld.service立即停止防火墙服务,仅当前会话有效 systemctl restart firewalld.service先停止再启动服务,会中断现有连接 systemctl status firewalld.service显示服务运行状态(running/stopped)及详细信息 systemctl enable firewalld.service系统重启后自动启动防火墙,永久生效 systemctl disable firewalld.service系统重启后不再自动启动防火墙,永久生效 -
状态与规则查看
命令 说明 firewall-cmd --state返回 running表示正在运行,not running表示已停止firewall-cmd --list-all显示默认区域的名称、接口、服务、端口、富规则等所有配置 firewall-cmd --list-all-zones列出系统中所有区域的完整配置,包括每个区域的接口、服务、端口、富规则等 firewall-cmd --get-active-zones显示所有已绑定网络接口的区域,及每个区域绑定的接口列表 firewall-cmd --get-zone-of-interface=eth0查看 eth0接口当前绑定的区域(将eth0替换为实际接口名)firewall-cmd --get-services列出 firewalld 支持的所有预定义服务名称(如 ssh、http、https等) -
配置重载与模式切换
命令 说明 firewall-cmd --reload加载永久配置并应用到运行时,不中断现有连接,是使永久配置生效的首选方式 firewall-cmd --runtime-to-permanent将当前运行时配置保存为永久配置 firewall-cmd --panic-on立即启用紧急模式,拒绝所有进出网络连接,仅保留本地连接(如本地登录),需谨慎使用 firewall-cmd --panic-off退出紧急模式,恢复之前的防火墙配置,网络连接恢复正常 -
核心操作补充(不带–permanent就是临时运行,带的就是永久)
规则类型 操作需求 命令示例 说明 富规则 查看已配置的富规则 (永久) firewall-cmd --permanent --list-rich-rules列出保存在配置文件中的所有富规则。 删除富规则 (永久) firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'删除一条永久配置的富规则。删除后需要执行 firewall-cmd --reload才能在运行时生效。规则内容必须与添加时完全一致。服务 查看已开放的服务 (永久) firewall-cmd --permanent --list-services列出在默认区域永久开放的所有服务。 删除开放的服务 (永久) firewall-cmd --permanent --remove-service=http从永久配置的默认区域中移除 http服务。删除后需要reload生效。端口 查看已开放的端口 (永久) firewall-cmd --permanent --list-ports列出在默认区域永久开放的所有端口。 删除开放的端口 (永久) firewall-cmd --permanent --remove-port=8080/tcp从永久配置的默认区域中移除 8080/tcp端口。删除后需要reload生效。
三 、 核心规则配置详解
3.1、区域
# 返回系统当前设置的默认区域(默认通常为 public)
firewall-cmd --get-default-zone# 设置默认区域
firewall-cmd --set-default-zone=public# 永久把 eth0 接口绑定到public区域,需执行 firewall-cmd --reload 生效(替换 eth0 为实际接口名)
firewall-cmd --permanent --zone=public --add-interface=eth0# 永久从 public 区域永久移除 eth0 接口,需执行 firewall-cmd --reload 生效
firewall-cmd --permanent --zone=public --remove-interface=eth0
3.2、服务
# 设置默认区域为 public
firewall-cmd --permanent --set-default-zone=public# 永久开放指定服务(如 http)
firewall-cmd --permanent --zone=public --add-service=http# 永久移除已开放的服务(如 http)
firewall-cmd --permanent --zone=public --remove-service=http# 查看指定区域已开放的服务
firewall-cmd --zone=public --list-services# 查看指定区域永久开放的服务
firewall-cmd --permanent --zone=public --list-services# 重载防火墙配置(使永久服务配置生效)
firewall-cmd --reload
3.3、端口管理
# 永久开放 TCP 端口 8080
firewall-cmd --permanent --zone=public --add-port=8080/tcp# 永久开放 UDP 端口范围 5060-5061
firewall-cmd --permanent --zone=public --add-port=5060-5061/udp# 查看端口是否开放
firewall-cmd --zone=public --query-port=8080/tcp# 永久移除已开放的端口
firewall-cmd --permanent --zone=public --remove-port=8080/tcp# 重载配置使更改生效
firewall-cmd --reload# 1. 设置默认区域为 public
firewall-cmd --permanent --set-default-zone=public
3.4、富规则
-
允许特定 IP (192.168.1.1) 访问 SSH 服务
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.1" service name="ssh" accept' success [root@localhost ~]# firewall-cmd --reload success [root@localhost ~]# firewall-cmd --list-rich rule family="ipv4" source address="192.168.1.1" service name="ssh" accept -
拒绝某个 IP 段 (10.0.0.0/24) 访问 80 端口,并记录日志
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port protocol="tcp" port=80 log prefix="HTTP_REJECT" level="warning" reject' success [root@localhost ~]# firewall-cmd --reload success [root@localhost ~]# firewall-cmd --list-rich rule family="ipv4" source address="10.0.0.0/24" port port="80" protocol="tcp" log prefix="HTTP_REJECT" level="warning" reject # 定义规则 rule family="ipv4" source 源地址="x.x.x.x/24" port 端口协议是tcp 保存日志 reject -
删除一条富规则
[root@localhost ~]# firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.1" service name="ssh" accept' success [root@localhost ~]# firewall-cmd --reload success--remove-rich-rule='原模原样删除,使用firewall-cmd --list-rich查看' -
端口转发与 NAT
# 1. 开启内核 IP 转发(必须步骤) echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -p# 2. 开启伪装(MASQUERADE),通常在 external 区域 # 这允许局域网内的机器通过该主机访问外网(SNAT) firewall-cmd --permanent --zone=external --add-masquerade# 3. 配置端口转发(DNAT) # 将所有发往本机 80 端口的 TCP 请求转发到内部服务器 192.168.1.100 的 8080 端口 firewall-cmd --permanent --zone=public --add-rich-rule=' rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080" to-addr="192.168.1.100"'# 4. 重载配置 firewall-cmd --reload
四、firewalld 与 iptables 规则对照表
| 操作场景 | iptables 命令 (临时生效) | firewalld 命令 (推荐永久生效) |
|---|---|---|
| 查看规则 | iptables -L -n | firewall-cmd --list-all |
| 开放端口 (如 80/tcp) | iptables -A INPUT -p tcp --dport 80 -j ACCEPT | firewall-cmd --permanent --add-port=80/tcp firewall-cmd --reload |
| 开放服务 (如 http) | iptables -A INPUT -p tcp --dport 80 -j ACCEPT | firewall-cmd --permanent --add-service=http firewall-cmd --reload |
| 仅允许特定 IP 访问端口 | iptables -A INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT | firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'``firewall-cmd --reload |
| 拒绝特定 IP | iptables -A INPUT -s 10.0.0.5 -j DROP | firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" drop' firewall-cmd --reload |
| 端口转发 (DNAT) | iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.200:80 | firewall-cmd --permanent --add-masquerade firewall-cmd --permanent --add-rich-rule='rule family="ipv4" forward-port port="8080" protocol="tcp" to-port="80" to-addr="192.168.1.200"' firewall-cmd --reload |
| 网络伪装 (SNAT) | iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE | firewall-cmd --permanent --zone=external --add-masquerade``firewall-cmd --reload |
| 保存规则 | service iptables save 或 iptables-save > /etc/sysconfig/iptables | firewall-cmd --runtime-to-permanent (将当前运行时规则保存为永久规则) |
| 删除规则 (假设是最后一条) | iptables -D INPUT -p tcp --dport 80 -j ACCEPT | firewall-cmd --permanent --remove-port=80/tcp firewall-cmd --reload |
五、 DROP 与 REJECT 的区别及应用场景
| 动作类型 | 核心行为 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| DROP(丢弃) | 直接丢弃数据包,不返回任何响应 | 隐蔽性强,攻击者难以判断主机 / 端口是否存活 | 合法用户排错困难,无法区分是网络问题还是防火墙拦截 | 不可信外部网络(如 public 区域)、屏蔽恶意 IP / 端口扫描 |
| REJECT(拒绝) | 拒绝数据包,向客户端发送响应包(TCP RST/ICMP Port Unreachable) | 明确告知客户端连接被拒绝,便于快速诊断问题 | 泄露主机存在信息,可能被攻击者利用 | 内部网络(如 home/work 区域)、需明确拒绝已知 IP 的场景 |
六、 常见故障排查
- 配置不生效:
- 忘记添加
--permanent参数,导致重启后配置丢失。 - 添加了
--permanent参数,但忘记执行firewall-cmd --reload。 - 规则配置在错误的区域,而网络接口绑定在另一个区域。使用
firewall-cmd --get-active-zones检查。
- 忘记添加
- 无法访问外部网络(NAT 场景):
- 未开启内核 IP 转发 (
net.ipv4.ip_forward = 1)。 - 未在正确的区域(如
external)开启伪装 (--add-masquerade)。
- 未开启内核 IP 转发 (
- 规则冲突:
- 富规则的优先级高于普通的端口 / 服务规则。一条
reject或drop的富规则可能会覆盖后续的accept规则。 - 检查规则顺序和逻辑,使用
firewall-cmd --list-all和firewall-cmd --list-rich-rules仔细排查。
- 富规则的优先级高于普通的端口 / 服务规则。一条
