Linux防火墙:iptables与firewalld详解
摘要:本文系统介绍了Linux防火墙的两种主流工具iptables和firewalld。首先阐述了防火墙的核心价值是作为网络流量的访问控制机制,通过规则实现流量过滤、服务暴露限制和日志记录。其次详细解析了iptables的"四表五链"架构、规则语法和操作命令,以及firewalld基于"区域+服务"的动态管理模型。通过典型场景对比两种工具的实现方式,如SSH
一、防火墙基础认知:先搞懂 “防火墙的本质”
这部分解决 “为什么需要防火墙”“Linux 防火墙的定位”,为后续工具学习铺垫宏观认知。
1. 防火墙的核心价值
-
定义:防火墙是运行在主机或网络边界的访问控制设备 / 软件,通过预先定义的 “规则” 允许或拒绝网络数据包(如 TCP/UDP 报文)的进出,本质是 “网络流量的守门人”。
-
核心作用:
-
保护主机 / 网络免受未授权访问(如阻止陌生 IP 登录 SSH 服务)。
-
限制服务暴露范围(如只允许特定 IP 访问数据库 3306 端口)。
-
记录网络流量日志(用于审计和攻击溯源)。
-
-
分类
-
硬件防火墙:需通过专用接口配置参数,管理复杂但性能稳定。
以专用硬件设备形式存在,直接集成防火墙功能(如专用芯片或嵌入式系统),性能高、独立于主机资源,但成本较高
-
软件防火墙:通过操作系统界面管理,灵活性高但依赖主机资源。
-
主机防火墙:管理集中于单机策略(如应用程序权限)。
-
网关防火墙:需全局流量规则设置,关注网络边界安全
-
2. Linux 防火墙的两种主流工具:iptables 与 firewalld
Linux 内核本身集成了 “netfilter” 防火墙框架(内核态),而 iptables 和 firewalld 是用户态工具,用于配置 netfilter 的规则。两者关系如下:

-
netfilter:内核中的数据包处理模块(真正执行过滤逻辑),是 “底层引擎”。
-
iptables:传统的命令行工具,直接操作 netfilter 规则,属于 “静态防火墙”(规则变更需重启服务或手动刷新)。
-
firewalld:CentOS 8+ 引入的动态防火墙管理工具,基于 netfilter,通过 “区域” 和 “服务” 简化规则配置,支持动态更新(无需重启服务)。
一句话总结:netfilter 是内核 “引擎”,iptables 和 firewalld 是操作引擎的 “遥控器”,只是遥控器的操作逻辑不同。
二、iptables 核心原理与配置:传统防火墙的 “规则链” 逻辑
iptables 是最经典的 Linux 防火墙工具,需掌握其 “四表五链” 的核心结构,这是理解规则配置的基础。
1. iptables 的核心模型:四表五链(必须讲透)
iptables 通过 “表(table)” 和 “链(chain)” 组织规则,“表” 按功能分类,“链” 按数据包流经的位置分类。
(1)五链:数据包流经的 “关卡”
链是内核中预定义的 “数据包处理点”,数据包从进入到离开主机,会依次经过这些关卡:
| 链名称 | 位置(数据包流经时机) | 作用示例 |
|---|---|---|
PREROUTING |
数据包进入主机后,路由之前(还未决定是否转发或本地处理) | 用于端口映射(DNAT)、修改数据包目的地 |
INPUT |
数据包被主机本地接收(路由后确定目标是本机) | 控制哪些外部流量能访问本机服务(如允许 80 端口) |
FORWARD |
数据包被主机转发(路由后确定目标是其他主机) | 控制本机作为网关时,转发哪些跨网段流量 |
OUTPUT |
主机向外发送数据包(从本机产生,准备发出) | 控制本机能访问哪些外部服务(如禁止访问 80 端口) |
POSTROUTING |
数据包离开主机前(转发或本地发出的最后一步) | 用于源地址转换(SNAT)、修改数据包源地址 |
(2)四表:规则的 “功能分类”
表是 “规则的集合”,每个表专注于一类功能,优先级从高到低为:raw → mangle → nat → filter(同一链中,高优先级表的规则先执行)。
| 表名称 | 核心功能 | 包含的链(规则可配置在哪些关卡) | 最常用场景 |
|---|---|---|---|
filter |
过滤数据包(允许 / 拒绝),默认表 | INPUT、FORWARD、OUTPUT |
日常访问控制(如禁止特定 IP 访问) |
nat |
网络地址转换(修改数据包的源 / 目的 IP / 端口) | PREROUTING、INPUT、OUTPUT、POSTROUTING |
端口映射(如公网 IP:80 → 内网 IP:8080)、共享上网 |
mangle |
修改数据包标记(如 TOS、TTL),用于高级路由 | 所有五链 | 流量整形、QoS 服务质量控制 |
raw |
关闭数据包的连接跟踪(提升性能) | PREROUTING、OUTPUT |
高并发场景(如 Web 服务器)优化 |
(3)表与链的关系:“在哪里” 执行 “什么功能”
-
规则必须配置在 “表” 中,且该表必须包含对应的 “链”(如
filter表的规则只能放在INPUT/FORWARD/OUTPUT链)。 -
数据包流经某条链时,会依次执行该链上所有表的规则(按表优先级),直到匹配到一条规则并执行目标动作。
2. iptables 规则的核心要素:匹配条件 + 目标动作
每条 iptables 规则由 “匹配条件” 和 “目标动作” 组成,格式简化为:iptables [-t 表名] 动作(如 -A 添加) 链名 匹配条件 -j 目标动作
(1)匹配条件:哪些数据包会被这条规则处理?
-
基本匹配(无需加载模块):
-
协议:
-p tcp/udp/icmp(如-p tcp匹配 TCP 协议)。 -
源 / 目的 IP:
-s 源IP(如-s 192.168.1.10)、-d 目的IP。 -
源 / 目的端口:
--sport 源端口、--dport 目的端口(仅用于 TCP/UDP,如--dport 80匹配目标端口 80)。 -
网卡:
-i 入站网卡(如-i eth0匹配从 eth0 进入的数据包)、-o 出站网卡。
-
-
扩展匹配(需加载模块,用
-m 模块名指定):-
多端口:
-m multiport --dports 80,443(匹配 80 或 443 端口)。 -
IP 范围:
-m iprange --src-range 192.168.1.10-192.168.1.20(匹配源 IP 范围)。 -
状态匹配:
-m state --state NEW,ESTABLISHED(匹配连接状态,如新建连接、已建立连接)。
-
(2)目标动作:匹配后对数据包做什么?
| 动作名称 | 含义 | 常用场景 |
|---|---|---|
ACCEPT |
允许数据包通过(继续处理后续规则或放行) | 允许正常服务的流量(如 80、22 端口) |
DROP |
直接丢弃数据包(不回复任何信息,客户端会超时) | 拒绝恶意 IP 或端口(隐蔽性好) |
REJECT |
拒绝数据包并回复 “拒绝信息”(如 ICMP 端口不可达) | 明确告知客户端 “被拒绝”(适合内部网络) |
SNAT |
源地址转换(修改数据包的源 IP,如共享上网时将内网 IP 转为公网 IP) | -j SNAT --to-source 公网IP |
DNAT |
目的地址转换(修改数据包的目的 IP / 端口,如端口映射) | -j DNAT --to-destination 内网IP:端口 |
LOG |
记录数据包信息到 /var/log/messages,不影响数据包流转(需配合其他动作) |
审计流量(如 LOG --log-prefix "DROP:") |
RETURN |
退出当前链,返回上一级链继续处理 | 自定义链中使用,避免规则嵌套过深 |
3. iptables 基本操作命令(核心必学)
1、RHEL9默认使用firewalld,需先禁用firewalld并安装iptables服务:
[root@kittod ~]# systemctl stop firewalld
[root@kittod ~]# systemctl disable --now firewalld
[root@kittod ~]# systemctl mask firewalld
2、安装iptables
dnf install iptables-services -y
systemctl enable --now iptables.service
systemctl status iptables.service
(1)查看规则
#查看指定表
[root@localhost ~]# iptables -L -t mangle -n
[root@localhost ~]# iptables -L -t nat -n
[root@localhost ~]# iptables -L -t raw -n
[root@localhost ~]# iptables -L -t filter -n
#规则链存储文件
vim /etc/sysconfig/iptables
#查看所有链的规则
iptables -L -nv --line-numbers
(2)添加规则
#1、追加规则到链尾
允许SSH通过TCP 22端口(追加到INPUT链末尾)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#2、插入规则到链的指定位置
在INPUT链的第2条位置插入规则,丢弃来自192.168.1.0/24网段的所有流量
iptables -I INPUT 2 -s 192.168.1.0/24 -j DROP
#3、指定表(如filter表)插入规则
允许目标为192.168.10.182的TCP 80-443端口流量通过FORWARD链
iptables -t filter -I FORWARD -d 192.168.10.182 -p tcp --dport 80:443 -j ACCEPT
(3)删除规则
#1、追加规则到链尾
允许SSH通过TCP 22端口(追加到INPUT链末尾)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#2、插入规则到链的指定位置
在INPUT链的第2条位置插入规则,丢弃来自192.168.1.0/24网段的所有流量
iptables -I INPUT 2 -s 192.168.1.0/24 -j DROP
#3、指定表(如filter表)插入规则
允许目标为192.168.10.182的TCP 80-443端口流量通过FORWARD链
iptables -t filter -I FORWARD -d 192.168.10.182 -p tcp --dport 80:443 -j ACCEPT
(4)设置默认策略(链的 “保底规则”)
当数据包不匹配链中任何规则时,执行默认策略:
# 设置 INPUT 链默认拒绝(只允许明确放行的流量,安全最佳实践)
iptables -P INPUT DROP
# 设置 FORWARD 链默认拒绝(非网关服务器建议关闭转发)
iptables -P FORWARD DROP
# 设置 OUTPUT 链默认允许(本机发出的流量通常无需严格限制)
iptables -P OUTPUT ACCEPT
#1\替换指定编号的规则
iptables -R INPUT 1 -s 192.168.1.1 -j REJECT
(5)保存与恢复规则
iptables 规则默认保存在内存中,重启后失效,需手动保存到/etc/sysconfig/iptables文件:
service iptables save
三、firewalld 核心原理与配置:动态防火墙的 “区域” 逻辑
firewalld 是为简化防火墙管理设计的动态工具,核心是 “区域(zone)” 和 “服务(service)”,需讲清其与 iptables 的设计理念差异。
1. firewalld 的核心模型:区域(zone)与服务(service)
(1)区域(zone):按 “信任级别” 分组的规则集合
firewalld 将网络环境按 “信任程度” 分为多个区域,每个区域包含预设的规则(允许哪些服务 / 端口),主机的网卡可绑定到某个区域,流量按区域规则处理。常用区域(从高信任到低信任):
| 区域名称 | 信任等级 | 核心特点 | 适用场景 | 默认开放服务 |
|---|---|---|---|---|
| trusted | 最高 | 允许所有传入、传出流量,无任何限制(完全信任) | 封闭测试环境、绝对安全的内部网络 | 所有端口 / 服务 |
| home | 高 | 允许家庭网络常用服务,限制外部非必要流量 | 家庭 WiFi、家用局域网 | ssh、mdns、samba-client、dhcpv6-client |
| internal | 中高 | 与 home 区规则一致,语义上区分 “内部网络” | 企业内网、办公室内部网络 | ssh、mdns、samba-client、dhcpv6-client |
| work | 中 | 仅开放办公基础服务,关闭非工作类服务(比 home/internal 限制更严) | 办公工位网络、企业工作网络 | ssh、dhcpv6-client |
| public | 中低 | 仅开放最基础无风险服务,严格限制其他流量(firewalld 默认区域) | 咖啡馆 WiFi、酒店网络、服务器公网接口 | ssh、dhcpv6-client |
| external | 低 | 启用 NAT 转发,仅允许 ssh 传入,拒绝其他外部主动连接 | 外网网关接口、路由器外网口 | ssh(默认启用 masquerade 伪装) |
| dmz | 较低 | 仅开放指定公网服务,隔离外网与内网核心设备 | Web 服务器、邮件服务器等公开服务部署 | 无(需手动开放 http/https 等特定服务) |
| block | 最低 | 拒绝所有传入流量,返回 ICMP 不可达响应;允许所有传出流量 | 高安全需求的内部网络 | 无(仅允许内部主动向外通信) |
| drop | 最低 | 丢弃所有传入流量,不做任何回应;仅允许所有传出流量(最严格) | 核心数据库、敏感业务服务器 | 无(仅允许内部主动向外通信) |
firewalld 默认提供的九个 zone 配置文件都保存在 “/usr/lib/firewalld/zones/” 目录下,分别为:block.xml drop.xml home.xml public.xml work.xml dmz.xml external.xml internal.xml trusted.xml
在 RHEL7 中,firewall 服务是默认的防火墙配置管理工具,他拥有基于 CLI(命令行界面)和基于 GUI(图形用户界面)的两种管理方式。firewall-config 和 firewall-cmd 是直接编辑 xml 文件,其中 firewall-config 是图形化工具,firewall-cmd 是命令行工具。
(2)服务(service):预定义的 “端口 + 协议” 集合
firewalld 将常用服务(如 HTTP、SSH)的 “端口 + 协议” 封装为 “服务”,避免用户手动输入端口,简化配置。例如:
-
ssh服务:对应tcp/22端口。 -
http服务:对应tcp/80端口。 -
自定义服务:可通过配置文件定义(
/usr/lib/firewalld/services/或/etc/firewalld/services/)。
(3)动态更新机制:规则变更无需重启服务
firewalld 通过 firewalld 服务进程管理规则,修改规则后执行 firewall-cmd --reload 即可生效(不中断现有连接),这是与 iptables(修改后需重启或手动刷新)的核心区别。
2. firewalld 基本操作命令(核心必学)
指令:
注意:
永久/运行时模式
runtime模式:运行时模式,立即生效,重启失效
permanent模式:永久模式,重启生效
--permanent参数需配合firewall-cmd --reload生效`紧急阻断流量:
firewall-cmd --panic-on,将当前运行时配置保存为永久配置firewall-cmd --runtime-to-permanent[root@localhost ~]# firewall-cmd --add-service=http --zone=internal success [root@localhost ~]# firewall-cmd --runtime-to-permanent success [root@localhost ~]# firewall-cmd --permanent --add-service=http --zone=external success [root@localhost ~]# firewall-cmd --reload success增
1. 添加服务规则
# 临时添加 HTTP 服务到默认区域
firewall-cmd --add-service=http
# 永久添加 HTTPS 服务到指定区域
firewall-cmd --permanent --zone=public --add-service=https
2. 添加端口规则
# 开放 TCP 端口 8080(临时生效)
firewall-cmd --add-port=8080/tcp
# 永久开放 UDP 端口范围 5000-6000
firewall-cmd --permanent --add-port=5000-6000/udp
3. 添加富规则 (Rich Rule)
# 允许特定 IP 段访问 MySQL 端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3306" accept'
4. 添加自定义区域
# 创建新区域 webzone 并永久保存
firewall-cmd --new-zone=webzone --permanent
# 关联网卡到指定区域
firewall-cmd --zone=webzone --add-interface=eth0
删
1. 删除服务规则
# 从默认区域移除 FTP 服务(临时)
firewall-cmd --remove-service=ftp
# 永久删除指定区域的 DNS 服务
firewall-cmd --permanent --zone=internal --remove-service=dns
2. 删除端口规则
# 移除临时 TCP 端口 3389
firewall-cmd --remove-port=3389/tcp
# 永久删除 UDP 端口 161
firewall-cmd --permanent --remove-port=161/udp
3. 删除富规则
# 删除特定 IP 访问规则
firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="10.0.0.5" accept'
4. 删除区域
# 永久删除自定义区域
firewall-cmd --delete-zone=oldzone --permanent
改
1. 修改默认区域
# 默认接口的将默认区域改为 dmz
firewall-cmd --set-default-zone=dmz
#修改指定网卡接口到指定区域
[root@localhost ~]# firewall-cmd --permanent --add-interface=ens224 --zone=public
2. 持久化运行时配置
# 将当前运行时配置保存为永久配置
firewall-cmd --runtime-to-permanent
3. 修改服务参数
# 为 SSH 服务添加额外端口
firewall-cmd --permanent --service=ssh --add-port=2222/tcp
4. 修改高级策略
# 设置区域默认动作为拒绝
firewall-cmd --permanent --zone=work --set-target=REJECT
查
1. 基础信息查询
# 查看当前激活区域
firewall-cmd --get-active-zones
# 列出 public 区域所有规则
firewall-cmd --list-all --zone=public
2. 服务端口查询
# 查询允许的服务列表
firewall-cmd --list-services
# 显示 external 区域的开放端口
firewall-cmd --list-ports --zone=external
3. 规则验证
# 检查配置语法
firewall-cmd --check-config
# 验证 IP 是否在 trusted 区域
firewall-cmd --zone=trusted --query-source=192.168.0.15
4. 高级状态监测
# 查看支持的 ICMP 类型
firewall-cmd --get-icmptypes
# 查询网卡绑定的区域
firewall-cmd --get-zone-of-interface=eth1
(1)查看状态与区域信息
# 查看 firewalld 服务状态
systemctl status firewalld
# 查看默认区域
firewall-cmd --get-default-zone
# 输出:public
# 查看所有区域及绑定的网卡
firewall-cmd --get-active-zones
# 输出示例:
# public
# interfaces: eth0
# 查看当前区域的规则(允许的服务/端口)
firewall-cmd --list-all # 查看默认区域
firewall-cmd --zone=public --list-all # 查看指定区域
(2)区域管理(切换默认区域、绑定网卡)
# 临时切换默认区域为 public(重启服务后失效)
firewall-cmd --set-default-zone=public
# 永久将 eth0 网卡绑定到 public 区域(需 --permanent,重启生效)
firewall-cmd --permanent --zone=public --add-interface=eth0
# 若网卡已绑定其他区域,先移除再添加
firewall-cmd --permanent --zone=home --remove-interface=eth0
(3)服务与端口管理(允许流量通过)
# 临时允许 public 区域的 http 服务(立即生效,重启服务失效)
firewall-cmd --zone=public --add-service=http
# 永久允许 public 区域的 ssh 服务(需 --permanent,reload 后生效)
firewall-cmd --permanent --zone=public --add-service=ssh
# 临时允许 public 区域的 tcp/8080 端口(非预定义服务用端口)
firewall-cmd --zone=public --add-port=8080/tcp
# 永久允许 public 区域的 udp/53 端口
firewall-cmd --permanent --zone=public --add-port=53/udp
(4)生效与删除规则
# 重新加载规则(使永久配置生效,不中断连接)
firewall-cmd --reload
# 临时删除 public 区域的 http 服务
firewall-cmd --zone=public --remove-service=http
# 永久删除 public 区域的 8080/tcp 端口
firewall-cmd --permanent --zone=public --remove-port=8080/tcp
(5)端口转发(类似 iptables 的 DNAT)
# 永久设置:将公网 IP 的 80 端口转发到内网 192.168.1.10 的 8080 端口
firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10:toport=8080
firewall-cmd --reload # 生效
四、iptables 与 firewalld 核心对比:何时用哪个?
学员最易混淆两者的适用场景,需通过表格明确差异:
| 对比维度 | iptables | firewalld | 核心差异点 |
|---|---|---|---|
| 设计理念 | 基于 “规则链”,需手动编写每条规则(灵活性高,复杂度高) | 基于 “区域 + 服务”,预定义规则模板(简化配置,灵活性低) | 逻辑:规则链自由组合 vs 区域模板化 |
| 规则生效方式 | 即时生效,但需手动保存(iptables-save),重启服务会中断连接 |
动态生效(--reload 不中断连接),永久配置需 --permanent |
生效:手动保存 + 可能中断 vs 动态重载 + 无中断 |
| 学习曲线 | 陡峭(需理解四表五链、匹配条件、动作) | 平缓(掌握区域、服务基本命令即可) | 难度:高 vs 低 |
| 适用场景 | 1. 复杂规则配置(如多条件匹配、自定义链);2. 脚本化批量部署;3. 对性能要求极高的场景(无守护进程) | 1. 简单服务开放(如 Web、SSH);2. 动态网络环境(需频繁修改规则);3. 新手快速上手 | 场景:复杂定制 vs 简单动态 |
| 底层关系 | 直接操作 netfilter 内核模块 | 作为 iptables 的前端工具,底层仍调用 netfilter | 定位:直接操作 vs 前端管理 |
五、实践操作:典型场景配置(对比演示)
通过 “同一需求用两种工具实现” 的对比实验,让学员理解两者的操作逻辑差异。
场景 1:允许 SSH(22)和 HTTP(80)服务,拒绝其他入站流量
用 iptables 实现:
# 1. 清空现有规则(谨慎!生产环境避免)
iptables -F # 清空所有链
iptables -X # 删除自定义链
# 2. 设置默认策略(INPUT 拒绝,OUTPUT 允许,FORWARD 拒绝)
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
# 3. 允许已建立的连接(避免 SSH 连接被断开)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 4. 允许 SSH(22 端口)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 5. 允许 HTTP(80 端口)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 6. 保存规则
iptables-save > /etc/sysconfig/iptables
用 firewalld 实现:
# 1. 确保 firewalld 启动
systemctl start firewalld
systemctl enable firewalld
# 2. 切换默认区域为 public(已预设基本规则)
firewall-cmd --set-default-zone=public
# 3. 永久允许 ssh 和 http 服务
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
# 4. 重新加载生效
firewall-cmd --reload
# 5. 验证(public 区域应包含 ssh 和 http)
firewall-cmd --list-all
场景 2:禁止特定 IP(192.168.1.100)访问本机
用 iptables 实现:
# 添加规则到 INPUT 链(拒绝 192.168.1.100 的所有流量,规则需在允许规则前)
iptables -I INPUT -s 192.168.1.100 -j DROP # -I 插入到链的开头(优先级高)
用 firewalld 实现:
# 临时拒绝 192.168.1.100(立即生效)
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.100" reject'
# 永久拒绝(需 --permanent)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" reject'
firewall-cmd --reload
(rich-rule 是 firewalld 的高级规则语法,支持复杂条件匹配)
场景 3:端口映射(公网 IP:80 → 内网 192.168.1.20:8080)
用 iptables 实现(需开启内核转发):
# 1. 开启内核 IP 转发(临时)
echo 1 > /proc/sys/net/ipv4/ip_forward
# 2. 在 nat 表 PREROUTING 链添加 DNAT 规则
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.20:8080
# 3. 在 filter 表 FORWARD 链允许转发到 192.168.1.20:8080
iptables -A FORWARD -p tcp -d 192.168.1.20 --dport 8080 -j ACCEPT
用 firewalld 实现:
# 1. 开启 masquerade(类似 SNAT,允许转发)
firewall-cmd --permanent --zone=public --add-masquerade
# 2. 添加端口转发规则
firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.20:toport=8080
# 3. 重新加载生效
firewall-cmd --reload
六、常见问题排查:规则不生效的原因与解决
学员实操时最常遇到 “规则配置了但不生效”,需讲清排查思路:
| 问题现象 | 可能原因 | 排查步骤与解决方法 |
|---|---|---|
| 规则添加后,流量仍被拒绝 | 1. 规则顺序错误(拒绝规则在允许规则后);2. 默认策略为 DROP,但未允许相关流量;3. 规则未保存(iptables)或未 reload(firewalld)。 | 1. iptables 用 iptables -L --line-numbers 查顺序,用 -I 插入到前面;2. 检查默认策略(iptables -P 或 firewall-cmd --list-all);3. iptables 执行 iptables-save,firewalld 执行 firewall-cmd --reload。 |
| 重启后规则丢失 | 1. iptables 未执行 iptables-save;2. firewalld 未加 --permanent 选项。 |
1. iptables 保存规则:iptables-save > /etc/sysconfig/iptables;2. firewalld 重新添加规则并加 --permanent,再 reload。 |
| 端口转发不生效 | 1. 未开启内核 IP 转发;2. FORWARD 链默认拒绝(iptables);3. firewalld 未开启 masquerade。 | 1. 开启转发:echo 1 > /proc/sys/net/ipv4/ip_forward(永久需改 /etc/sysctl.conf);2. iptables 允许 FORWARD:iptables -P FORWARD ACCEPT;3. firewalld 开启 masquerade:--add-masquerade。 |
iptables实验
原则:最严格的限制条件放在前面
主机防火墙的配置策略: 1、所有都禁止,有明确的许可才可放行
2、所有都放行,把明确的不合法的请求禁止
实验:禁止192.168.48.131 网段的地址进行ping
[root@localhost ~]# iptables -D INPUT 3
[root@localhost ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@localhost ~]# iptables -I INPUT 3 -p icmp -j ACCEPT
[root@localhost ~]# iptables -L --line-number
[root@localhost ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
实验:配置火墙,搭建web服务器,设置任何人都能通过80端口访问http
[root@server ~]# mkdir -p /www/web
[root@server ~]# echo "hello world" > /www/web/index.html
[root@server ~]# yum install nginx -y
[root@server ~]# vim /etc/nginx/nginx.conf
root /www/web;
[root@server ~]# systemctl start nginx
[root@server ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
[root@server ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@server ~]# systemctl restart iptables
[root@server ~]# iptables -nL --line-numbers
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
实验:配置火墙,禁止所有人使用ssh进行远程登录
[root@server ~]# iptables -F # 清空
[root@server ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
# 此时ssh已断开连接
# 恢复ssh连接
[root@server ~]# iptables -D INPUT 1 # 删除INPUT链中第1条规则,恢复ssh
[root@server ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
[root@server ~]# service iptables save # 保存服务
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@server ~]# systemctl restart iptables # 重启服务
实验:配置火墙,禁止某主机(192.168.48.131) ssh远程登录,允许访问web服务
[root@server ~]# iptables -F
[root@server ~]# iptables -I INPUT -p tcp -s 192.168.48.131 --dport 22 -j REJECT # -I 表示在已存在的记录之前插入一条新纪录
[root@server ~]# iptables -I INPUT -p tcp -s 192.168.48.131 --dport 80 -j ACCEPT
[root@server ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.48.131 0.0.0.0/0 tcp dpt:80
REJECT tcp -- 192.168.48.131 ipt 0.0.0.0/0 tcp dpt:22 reject-with icmp-port-unreachable
[root@server ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@server ~]# systemctl restart iptables
系统中火墙管理工具的切换
[root@localhost ~]# systemctl stop iptables.service
[root@localhost ~]# systemctl --now disable iptables.service
[root@localhost ~]# systemctl unmask firewalld.service
[root@localhost ~]# systemctl enable --now firewalld.service
firewall实验
永久/运行时模式
runtime模式:运行时模式,立即生效,重启失效
permanent模式:永久模式,重启生效
--permanent参数需配合firewall-cmd --reload生效`紧急阻断流量:
firewall-cmd --panic-on,将当前运行时配置保存为永久配置firewall-cmd --runtime-to-permanent
实验
实验:firewalld区域中添加http服务,使其为放行状态
[root@server ~]# yum install nginx -y
[root@server ~]# systemctl start nginx
# 浏览器测试网页,被拒绝
[root@server ~]# firewall-cmd --get-default-zone
[root@server ~]# firewall-cmd --list all # 查看当前区域中开方的服务
[root@server ~]# firewall-cmd --permanent --zone=public --add-service=http
success
[root@server ~]# firewall-cmd --permanent --zone=public --add-port=80/tcp
success
[root@server ~]# firewall-cmd --reload
success
[root@server ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens32
sources:
services: cockpit dhcpv6-client http ssh
ports: 80/tcp
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
# 浏览器测试通过
# 放行服务格式:
firewall-cmd --permanent --zone=public --add-service=服务名
# 放行端口格式:
firewall-cmd --permanent --zone=public --add-port=端口号/传输协议
#扩展:当nginx修改端口号为666,那再次测试回出现什么问题?
firewall-cmd --permanent --add-port=666/tcp
firewall-cmd --reload
#扩展:指定网段的ip才能够访问
firewall-cmd --permanent --add-source 192.168.5.0/24 --zone=trusted
firewall-cmd --reload
实验:某些服务需要编辑zone文件才能添加服务,添加nginx服务
[root@server ~]# firewall-cmd --get-services # 查看所有区域支持的服务
[root@server ~]# yum install nginx -y # 安装nginx
[root@server ~]# firewall-cmd --add-service=nginx --permanent # 报错,需要编辑区域文件
[root@server ~]# cp /usr/lib/firewalld/services/http.xml /usr/lib/firewalld/services/nginx.xml # 编辑服务配置文件,添加:
<service>
<short>Nginx</short>
<description>nginx</description>
<port protocol="tcp" port="80"/>
<port protocol="tcp" port="443"/>
</service>
# 再次添加服务
[root@server services]# firewall-cmd --permanent --add-service=nginx
# 重置
[root@server services]# firewall-cmd --reload
# 查看当前区域支持的服务
[root@server services]# firewall-cmd --zone=public --list-service
实验:禁止192.168.48.131 网段的地址进行ping
-
firewalld 富规则:用于更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有正对性的策略配置
-
富规则优先级最高
[root@server ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.48.131/24" protocol value="icmp" reject'
success
[root@server ~]# firewall-cmd --reload # 重置
success
public (active)
target: default
icmp-block-inversion: no
interfaces: ens32
sources:
services: dhcpv6-client mdns nginx ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="192.168.48.131" protocol value="icmp" reject
# 客户端输入ping 192.168.48.130 进行测试,发现无法ping,成功
# 注意:恢复客户端ping,不能在服务端添加一条放行富规则,应为禁止的富规则还在,ping还是无法通信,如:
[root@server ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.48.131" protocol value="icmp" accept'
[root@server ~]# firewall-cmd --reload
# 客户端测试ping 192.168.48.130 失败
# 注意:只需删除对应规则即可
实验:端口转发
192.168.50.128:80 --防火墙端口转发--> 192.168.50.128:99
web本身监听:99 防火墙:端口转发 用户访问:192.168.50.128:80
[root@localhost ~]# netstat -lntup | grep nginx
tcp 0 0 0.0.0.0:99 0.0.0.0:* LISTEN 3576/nginx: master
tcp6 0 0 :::80 :::* LISTEN 3576/nginx: master
[root@localhost ~]# firewall-cmd --add-rich-rule=' rule family="ipv4" source address="192.168.50.1" forward-port port="80" protocol="tcp" to-port="99" '
[root@localhost ~]# firewall-cmd --runtime-to-permanent
success
[C:\~]$ curl 192.168.50.128:80
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13 100 13 0 0 3286 0 --:--:-- --:--:-- --:--:-- 4333
test page
实验:地址和端口转发
环境与目标梳理
| 设备 | 网卡模式 | IP 地址 | 角色 |
|---|---|---|---|
| Windows | NAT 模式 | 192.168.223.1 | 客户端(发起请求) |
| 虚拟机 1 | NAT 模式 | 192.168.223.135 | 转发节点(中间服务器) |
| 虚拟机 1 | 仅主机模式 | 192.168.32.129 | 转发节点(仅主机网卡) |
| 虚拟机 2 | 仅主机模式 | 192.168.32.128 | 目标服务器(提供 98 端口服务) |
目标:Windows 访问 192.168.223.135:80 → 虚拟机 1 转发到 192.168.32.128:98
步骤 1:确保基础网络连通性
1. 验证 Windows 与虚拟机 1 的 NAT 网卡连通
在 Windows 命令提示符中执行:
ping 192.168.223.135
要求:能 ping 通(若不通,检查 VMware NAT 网络配置,确保两者在同一网段)。
2. 验证虚拟机 1 与虚拟机 2 的仅主机网络连通
在虚拟机 1 中执行:
ping 192.168.32.128
要求:能 ping 通(若不通,检查仅主机网络是否在同一网段,关闭虚拟机 2 防火墙或开放 ICMP)。
3. 确保虚拟机 2 的 98 端口服务正常
验证:在虚拟机 1 中测试访问虚拟机 2 的 98 端口:
curl 192.168.32.128:98 # 或 telnet 192.168.32.128 98,能连接则服务正常
步骤 2:在虚拟机 1 上开启 IP 转发(核心)
Linux 默认关闭跨网卡转发,需手动开启(虚拟机 1 执行):
1. 临时开启 IP 转发(立即生效,重启失效)
echo 1 > /proc/sys/net/ipv4/ip_forward
2. 永久开启 IP 转发(重启后生效)
# 编辑sysctl配置文件
vim /etc/sysctl.conf
# 添加或修改以下行
net.ipv4.ip_forward = 1
# 生效配置
sysctl -p
3. 验证 IP 转发是否开启
sysctl net.ipv4.ip_forward
预期输出:net.ipv4.ip_forward = 1(表示已开启)。
步骤 3:强制开启 “伪装(masquerade)” 功能(核心!)
跨网段转发(NAT 网卡 → 仅主机网卡)时,RHEL 9 的 firewalld 需要开启 源地址转换(SNAT),否则虚拟机 2 收到的请求源 IP 是 Windows 的 192.168.223.1,但虚拟机 2 的路由无法回传数据到该网段(仅主机网络与 NAT 网络隔离)。
在虚拟机 1 的 仅主机网卡所在区域 开启伪装(假设仅主机网卡绑定到 public 区域):
# 临时开启伪装(立即生效)
firewall-cmd --add-masquerade
# 永久开启(重启后生效)
firewall-cmd --add-masquerade --permanent
firewall-cmd --reload
验证伪装是否开启:
firewall-cmd --query-masquerade # 返回 yes 表示已开启
步骤 4:配置虚拟机 1 的 firewalld 端口转发规则
通过 firewalld 的富规则,将虚拟机 1 的 192.168.223.135:80 流量转发到虚拟机 2 的 192.168.32.128:98(虚拟机 1 执行)。
1. 查看当前防火墙区域(默认是 public)
firewall-cmd --get-default-zone
2. 永久生效规则(可选,避免重启后失效)
firewall-cmd --add-rich-rule='
rule family="ipv4"
source address="192.168.223.1"
forward-port port=80 protocol=tcp
to-addr="192.168.32.128"
to-port=98
' --permanent
# 重新加载防火墙使永久规则生效
firewall-cmd --reload
3. 验证规则是否添加成功
firewall-cmd --list-rich-rules
预期输出:包含上述添加的规则,表示配置正确。
步骤 5:测试转发是否生效
在 Windows 中通过浏览器或命令行访问目标地址,验证转发结果:
1. 用 curl 测试
curl http://192.168.223.135:80
2. 用浏览器测试
打开浏览器,访问 http://192.168.223.135:80
更多推荐
所有评论(0)