Linux 防火墙实战:iptables 与 firewalld 全面解析

引言

“我的服务器怎么访问不了了?!”

相信不少运维新手都经历过这样的时刻——应用服务正常运行,端口也监听着,但浏览器就是打不开。折腾半天,最后试探性地执行了一条命令:

systemctl stop firewalld

网页瞬间恢复访问。你顿时明白:原来是防火墙在“搞鬼”。

在 Linux 系统中,防火墙是保障网络安全的第一道防线。而说到 Linux 防火墙,绕不开两个名字:iptablesfirewalld。它们到底是什么关系?有什么区别?日常工作中该用哪个?今天这篇文章就带你彻底搞明白。

一、Netfilter:一切防火墙的“地基”

在讲 iptables 和 firewalld 之前,有必要先认识一下 Netfilter

Netfilter 是 Linux 内核中的一个框架,它在网络协议栈的关键路径上设置了一系列“挂载点”(钩子函数)。当数据包经过这些挂载点时,内核会依次调用挂载点上所有的钩子函数,直到数据包的处理结果被明确为接受、拒绝或丢弃。

iptables 和 firewalld 都不是真正的防火墙本身,它们只是用来定义防火墙规则的管理工具。真正执行这些规则的是内核中的 Netfilter 框架。你可以这样理解:

  • Netfilter = 内核里的“执行引擎”
  • iptables / firewalld = 用户用来下命令的“控制台”

明确了这一点,后面的内容就更好理解了。

二、iptables:Linux 防火墙的“元老”

2.1 核心架构:表、链、规则

iptables 采用 “表(Table)-链(Chain)-规则(Rule)” 三级结构来管理网络流量。

四表(Table)

表名 作用
filter 默认表,用于数据包过滤(ACCEPT / DROP / REJECT)
nat 网络地址转换(SNAT / DNAT / MASQUERADE),用于端口转发或共享上网
mangle 修改数据包头部(如 TTL、TOS),用于 QoS 或流量标记
raw 绕过 Netfilter 的连接跟踪,提升性能

五链(Chain)

链名 作用
PREROUTING 数据包进入路由决策之前
INPUT 过滤发往本机的流量
FORWARD 过滤经过本机转发的流量(路由器场景)
OUTPUT 过滤本机发出的流量
POSTROUTING 数据包离开网卡之前

💡 规则优先级:raw > mangle > nat > filter

Iptables的4表5链
在这里插入图片描述
Iptables数据包转发流程
在这里插入图片描述

数据包先经过PREOUTING,由该链确定数据包走向:

  • 目的地址是本地,则发送到INPUT,让INPUT决定是否接收下来送到用户空间,流程为①—>②;
  • 若满足PREROUTING的nat表上的转发规则,则发送给FORWARD,然后再经过POSTROUTING发送出去,流程为:①—>③—>④—>⑥;
  • 主机发送数据包时,流程则是⑤—>⑥;
  • 其中PREROUTING和POSTROUTING指的是数据包的流向,如上图所示POSTROUTING指的是发往服务器发出的数据包,而PREROUTING指的是来自服务器外部的数据包。
    在这里插入图片描述

2.2 iptable命令用法

iptables的用法可以参考下图:
在这里插入图片描述

table:

- -t 使用的表,包括filter、nat、mangle、raw,默认不指明是filter.

command

-A 顺序添加,添加一条新规则,添加到末尾
-I 插入,插入一条新规则 -I 后面加一数字表示插入到哪行
-R 修改, 删除一条新规则 -D 后面加一数字表示删除哪行
-D 删除,删除一条新规则 -D 后面加一数字表示删除哪行
-N 新建一个链
-X 删除一个自定义链,删除之前要保证次链是空的,而且没有被引用
-L 查看(1.iptables -L -n 以数字的方式显示  2. iptables -L -v显示详细信息 3. iptables -L -x 显示精确信息)
-E 重命名链
-F 清空链中的所有规则
-Z 清除链中使用的规则
-P 设置默认规则

match:

隐含匹配:
   -p  tcp udp icmp
   --sport指定源端口
   --dport指定目标端
   -s 源地址
   -d 目的地址
   -i 数据包进入的网卡
   -o 数据包出口的网卡
扩展匹配:
   -m state --state   匹配状态的
   -m mutiport --source-port   端口匹配 ,指定一组端口
   -m limit --limit 3/minute   每三分种一次
   -m limit --limit-burst  5   只匹配5个数据包
   -m string --string --algo bm|kmp --string"xxxx"  匹配字符串
   -mtime--timestart 8:00 --timestop 12:00  表示从哪个时间到哪个时间段
   -mtime--days    表示那天
   -m mac --mac-source xx:xx:xx:xx:xx:xx 匹配源MAC地址
   -m layer7 --l7proto qq   表示匹配腾讯qq的 当然也支持很多协议,这个默认是没有的,需要我们给内核打补丁并重新编译内核及iptables才可以使用 -m layer7 这个显示扩展匹配

动作:

     DROP 直接丢掉
     ACCEPT 允许通过
     REJECT 丢掉,但是回复信息
-j   LOG --log-prefix"说明信息,自己随便定义" ,记录日志
     SNAT       源地址转换
     DNAT       目标地址转换
     REDIRECT   重定向
     MASQUERAED 地址伪装

2.3 iptables常用命令

iptables 的命令语法虽然有一定学习曲线,但掌握核心的几个命令就足够应对日常工作了。

查看规则

# 查看所有链的规则(默认 filter 表)
iptables -L

# 查看特定链的规则,带行号
iptables -L INPUT -n --line-numbers

# 查看 nat 表的规则
iptables -t nat -L

添加规则

# 在 INPUT 链末尾追加规则:允许 SSH(端口22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 在 INPUT 链首位插入规则:禁止 ICMP(ping)
iptables -I INPUT 1 -p icmp -j DROP

# 允许来自特定 IP 的访问
iptables -A INPUT -s 192.168.1.100 -j ACCEPT

删除规则

# 按行号删除(先查看行号)
iptables -D INPUT 1

# 按内容删除
iptables -D INPUT -p tcp --dport 80 -j ACCEPT

设置默认策略(白名单模式):

# 默认拒绝所有入站流量
iptables -P INPUT DROP

# 再逐条开放必要服务
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

保存与恢复规则

# 保存当前规则
iptables-save > /etc/sysconfig/iptables

# 恢复规则
iptables-restore < /etc/sysconfig/iptables

2.3 高级应用:NAT 与端口转发

SNAT(源地址转换) :让内网主机通过防火墙访问外网:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

DNAT(目的地址转换) :将外部请求转发到内网服务器:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

2.4 连接状态跟踪:提升性能的关键

利用 conntrack 模块,可以避免对已建立的连接重复匹配规则:

# 允许已建立的连接和相关连接通过
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 仅允许新的 SSH 连接
iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 22 -j ACCEPT

这样做的好处是:一旦 SSH 连接建立成功,后续的数据包直接放行,不再逐条匹配规则,大幅提升效率。

三、firewalld:更友好的“动态管家”

3.1 设计理念:区域 + 服务

firewalld 是建立在 iptables 之上的动态防火墙管理工具,提供了更高层次的抽象。它从 RHEL/CentOS 7 开始成为默认防火墙。

firewalld 的核心优势在于 支持运行时动态修改规则,无需重启防火墙服务,不会中断现有连接

核心概念

概念 说明
区域(Zone) 按信任级别划分的网络环境,如 public(默认)、trusted(完全信任)、block(拒绝所有)等
服务(Service) 预定义的端口和协议组合,如 httpsshmysql
源地址(Source) 基于 IP 或网段绑定特定区域
富规则(Rich Rule) 支持复杂条件(IP、端口、协议、时间等)的自定义规则

3.2 常用命令

firewalld 的核心管理工具是 firewall-cmd

状态与区域管理

# 查看防火墙状态
firewall-cmd --state

# 查看所有可用区域
firewall-cmd --get-zones

# 查看默认区域
firewall-cmd --get-default-zone

# 查看指定区域的详情
firewall-cmd --zone=public --list-all

服务与端口管理

# 添加服务到默认区域(永久生效需加 --permanent)
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent

# 开放端口
firewall-cmd --add-port=3306/tcp --permanent

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

# 查看已开放的服务和端口
firewall-cmd --list-services
firewall-cmd --list-ports

💡 关键区别:不加 --permanent 的修改只对当前运行生效,重启后丢失;加了 --permanent 需要执行 --reload 才能生效。

源地址控制

# 允许特定子网访问
firewall-cmd --zone=public --add-source=192.168.1.0/24 --add-service=ssh --permanent

# 拒绝特定 IP
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.5" reject' --permanent

3.3 自定义服务

如果应用使用非标准端口,可以创建自定义服务文件:

<!-- /etc/firewalld/services/custom_http.xml -->
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Custom HTTP</short>
  <description>Custom HTTP service on port 8080</description>
  <port protocol="tcp" port="8080"/>
</service>
firewall-cmd --reload
firewall-cmd --add-service=custom_http --permanent

3.4 富规则与端口转发

富规则支持更复杂的条件控制:

# 允许特定 IP 访问特定端口,仅在工作时间
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="8080" protocol="tcp" accept' --permanent

端口转发

# 开启伪装(端口转发的前提)
firewall-cmd --add-masquerade --permanent

# 将本机 8080 端口转发到 80 端口
firewall-cmd --add-forward-port=port=8080:proto=tcp:toport=80 --permanent

四、iptables vs firewalld:一张表看懂区别

对比维度 iptables firewalld
定位 底层、精细控制的防火墙工具 高层、易用的动态管理工具
配置模型 基于“链+规则”的底层模型 基于“区域+服务”的高层抽象
规则更新 修改后需全部刷新,可能中断连接 动态更新,不中断现有连接
学习曲线 较陡峭,需理解表、链、匹配条件 更友好,通过“区域”概念简化配置
配置文件 /etc/sysconfig/iptables /usr/lib/firewalld//etc/firewalld/
默认策略 默认允许所有,需要拒绝的才限制 默认拒绝所有传入流量
图形界面 firewall-config
后端支持 直接操作 netfilter 可使用 iptables 或 nftables 后端
适用场景 精细控制、复杂规则、脚本化部署 快速配置、日常运维、云环境

一句话总结:iptables 是“乐高”——什么都能搭,但需要自己动手;firewalld 是“精装房”——拎包入住,省心省力

五、实战:两个工具解决同一个需求

假设我们要完成一个常见任务:开放 Web 服务(80 和 443 端口),并允许 SSH 管理(22 端口),其余入站流量全部拒绝

用 iptables 实现

# 1. 设置默认策略:拒绝所有入站
iptables -P INPUT DROP
iptables -P FORWARD DROP

# 2. 允许已建立的连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 3. 开放必要端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 4. 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 5. 保存规则
iptables-save > /etc/sysconfig/iptables

用 firewalld 实现

# 1. 确保默认区域是 public(默认拒绝入站)
firewall-cmd --get-default-zone  # 应该是 public

# 2. 添加服务
firewall-cmd --add-service=ssh --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent

# 3. 重新加载生效
firewall-cmd --reload

# 4. 验证
firewall-cmd --list-services

对比一下,firewalld 只需要 4 条命令,而 iptables 需要 6 条命令加一个保存操作。对于日常运维场景,firewalld 的简洁性显而易见。

六、常见问题与排错指南

Q1:firewalld 和 iptables 能同时用吗?

不建议同时启用。两者都操作同一套 netfilter 规则,同时启用可能导致规则冲突。如果启用了 firewalld,建议禁用 iptables 服务:

systemctl stop iptables
systemctl disable iptables
systemctl enable --now firewalld

Q2:修改了 firewalld 规则为什么不生效?

检查两个地方:

  1. 是否加了 --permanent 但没有执行 --reload
  2. 是否修改了正确的区域(--zone 参数)

Q3:iptables 规则重启后消失了?

iptables 规则默认是临时的,需要手动保存:

# CentOS/RHEL
service iptables save

# 通用方法
iptables-save > /etc/sysconfig/iptables

Q4:服务启动失败,怎么排查?

服务启动失败可以参考如下步骤排查:

# 1. 查看防火墙状态
systemctl status firewalld
firewall-cmd --state

# 2. 查看当前规则
firewall-cmd --list-all
iptables -L -n -v

# 3. 临时关闭防火墙测试(仅用于排查)
systemctl stop firewalld
# 如果关闭后服务正常,说明是防火墙规则问题
# 4. 查看selinux状态
getenforce

Q5:找不到iptables服务,报错Unit iptables.service could not be found.

Centos 7以后默认没有安装iptables服务,需要通过yum install -y iptables-services之后就可以通过systemctl管理iptables服务了

七、iptables和firewalld到底应该选哪一个?

什么时候用 firewalld?

  • 大多数现代 Linux 系统(CentOS 7+、RHEL、Fedora)
  • 日常服务器运维、快速配置端口和服务
  • 需要动态调整防火墙策略的场景(如云环境)
  • 运维新手或不想花太多时间研究防火墙细节的人

什么时候用 iptables?

  • 需要极致精细的流量控制
  • 复杂的 NAT 和路由策略
  • 嵌入式系统或资源受限的环境
  • 维护已有的大量 iptables 脚本

📌 一句话建议:对于绝大多数新建 Linux 服务器,优先使用 firewalld;只有在 firewalld 无法满足的复杂场景下,才考虑降级到 iptables。对于一些较老的服务器iptables用得较多,一些比较资深的运维人员也比较习惯使用iptables作为linux的防火墙。

总结

从 iptables 到 firewalld,Linux 防火墙管理走过了一条从“底层精细”到“高层易用”的演进之路。两者都基于 Netfilter 框架,但设计理念截然不同:

  • iptables 是“工匠型”工具——强大、灵活,但需要你亲手搭建每一块砖。
  • firewalld 是“管家型”工具——开箱即用,日常运维省心省力。

记住三句话:

  1. Netfilter 是内核的执行引擎,iptables 和 firewalld 只是管理工具,不要搞混。
  2. 默认策略决定安全基调:iptables 默认允许,firewalld 默认拒绝——理解这一点,很多问题迎刃而解。
  3. 生产环境优先用 firewalld,复杂场景再用 iptables 补充。

防火墙是服务器的“守门人”,配置得当能挡住绝大部分恶意流量,配置失误也可能把自己挡在门外。希望这篇文章能帮你建立起清晰的防火墙管理思路,下次再遇到“服务访问不了”的问题,能快速定位是防火墙在“搞鬼”,还是真的程序出了 bug。

如果你有任何问题或经验分享,欢迎在评论区留言讨论!

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐