目录
[2.1 理解"表"和"链"](#2.1 理解“表”和“链”)
[2.2 四表:规则的功能分类](#2.2 四表:规则的功能分类)
[2.3 五链:规则执行的时机](#2.3 五链:规则执行的时机)
[2.4 一个具体的数据包流转示例](#2.4 一个具体的数据包流转示例)
[3.1 为什么要引入firewalld?](#3.1 为什么要引入firewalld?)
[3.2 核心概念:区域(Zone)](#3.2 核心概念:区域(Zone))
[3.3 临时规则 vs 永久规则](#3.3 临时规则 vs 永久规则)
[4.1 基础服务管理](#4.1 基础服务管理)
[4.2 端口管理](#4.2 端口管理)
[4.3 富规则(Rich Rule):精确访问控制](#4.3 富规则(Rich Rule):精确访问控制)
[4.4 查看与删除规则](#4.4 查看与删除规则)
[4.5 完整配置示例](#4.5 完整配置示例)
[六、iptables vs firewalld:如何选择?](#六、iptables vs firewalld:如何选择?)
一、引言:你的服务器正在被扫描
在第19篇配置SSH密钥登录时,我们提到过:刚买来的云服务器,几分钟内就会收到来自全球的暴力破解尝试。
这些攻击之所以能到达你的服务器,是因为默认情况下,你开放了SSH端口。如果防火墙没有正确配置,攻击者可以不断尝试登录。
防火墙的作用就是:在服务器和外部网络之间设置一道"围墙",只放行你允许的流量,拒绝所有未经授权的访问。
Linux系统中最主流的防火墙工具有两个:
-
iptables:经典工具,直接操作内核规则,功能强大但稍显复杂
-
firewalld:iptables的现代封装,引入区域(zone)概念,动态管理更友好
它们的底层都基于Linux内核的netfilter框架,只是管理方式不同。
二、iptables核心概念:四表五链
2.1 理解"表"和"链"
iptables用表(table) 和**链(chain)**两个维度来组织规则:
-
表 :按功能的分类。决定了规则能做什么(过滤?地址转换?修改数据包?)
-
链 :按时机分类。决定了规则在数据包经过的哪个环节生效
可以这样类比:
-
表就像不同的职能部门(财务部、安保部、运输部)
-
链就像进出大楼的检查点(大门口、走廊、电梯口)
-
数据包就是在大楼中穿行的人,在每个检查点都可能被某个部门拦截处理
2.2 四表:规则的功能分类
| 表名 | 功能 | 优先级 | 典型场景 |
|---|---|---|---|
| raw | 控制连接追踪,可跳过状态跟踪 | 最高 | 高并发服务器、DDoS防护 |
| mangle | 修改数据包标记(TTL、TOS等) | 第二 | 流量整形、QoS控制 |
| nat | 网络地址转换(SNAT/DNAT) | 第三 | 端口映射、内网上外网 |
| filter | 数据包过滤(放行/拒绝) | 最低 | 最常用,端口访问控制 |
记忆技巧 :优先级从高到低------raw → mangle → nat → filter。filter优先级最低但使用频率最高。
其中filter表是默认表 ,如果不指定-t参数,iptables命令操作的就是filter表。日常的端口放行、IP黑名单都在这个表中配置。
2.3 五链:规则执行的时机
数据包进入服务器后,会按固定路径经过这些"检查点":
text
外网数据包
↓
PREROUTING ← 路由决策前的检查(DNAT在这里做)
↓
[路由决策:这个包是给我的,还是需要转发的?]
↓ ↓
给我 转发给别人
↓ ↓
INPUT FORWARD
↓ ↓
本机应用 转发处理
↓ ↓
OUTPUT [继续转发]
↓ ↓
POSTROUTING ← 离开本机前的最后检查(SNAT在这里做)
↓
离开服务器
简单记忆:
-
PREROUTING:进门安检(所有入站包先经过这里)
-
INPUT:进自己房间(目标是本机)
-
FORWARD:穿堂而过(本机做路由器时)
-
OUTPUT:从房间出去(本机发出的包)
-
POSTROUTING:出门检票(所有出站包最后经过这里)
2.4 一个具体的数据包流转示例
假设外网用户访问你服务器的80端口(Nginx):
-
数据包到达网卡 → 进入PREROUTING链(可以做DNAT修改目标地址)
-
内核判断:目标是本机 → 进入INPUT链
-
filter表在INPUT链的规则被匹配:允许80端口 → 放行
-
数据包交给Nginx处理
-
Nginx返回响应 → 进入OUTPUT链
-
响应包经过POSTROUTING链 → 离开网卡
三、firewalld:iptables的现代化封装
3.1 为什么要引入firewalld?
iptables虽然强大,但有几个痛点:
-
规则修改是一次性整体替换,修改一条规则需要重新加载全部配置
-
没有持久化机制,重启后规则丢失(需要
iptables-save手动保存) -
语法较复杂,新手容易写出有安全漏洞的规则
firewalld就是为了解决这些问题而设计的:
-
动态管理:修改规则立即生效,不影响现有连接
-
区域(Zone)概念:为不同网络环境预设信任级别
-
服务(Service)抽象 :可以直接放行
http而不需要记端口号
3.2 核心概念:区域(Zone)
firewalld用"区域"来表示网络的信任级别:
| 区域 | 信任级别 | 默认行为 | 适用场景 |
|---|---|---|---|
trusted |
最高 | 接受所有连接 | 完全可信任的内网 |
home |
较高 | 接受选定连接 | 家庭网络 |
work |
较高 | 接受选定连接 | 公司办公网络 |
internal |
中等 | 接受选定连接 | 内部网络 |
public |
默认 | 拒绝入站连接 | 公共网络(服务器默认用这个) |
dmz |
较低 | 拒绝入站连接 | 隔离区服务器 |
block |
极低 | 拒绝所有(回复ICMP) | 问题IP临时封锁 |
drop |
最低 | 丢弃所有(不回复) | 最高安全级别 |
查看当前使用的区域:
bash
firewall-cmd --get-default-zone # 通常输出 public
重要认知 :云服务器默认使用
public区域,这个区域默认拒绝所有入站连接,只允许你明确放行的服务或端口。
3.3 临时规则 vs 永久规则
firewalld区分两种规则:
| 类型 | 特点 | 生效时机 | 重启后 |
|---|---|---|---|
临时规则 (无--permanent) |
立即生效 | 立即可用 | 丢失 |
永久规则 (有--permanent) |
写入配置文件 | --reload后生效 |
保留 |
最佳实践 :先用临时规则测试,确认无误后再加--permanent保存。
四、firewall-cmd实战操作
4.1 基础服务管理
bash
# 查看当前区域的所有规则
firewall-cmd --list-all
# 允许HTTP服务(自动放行80端口)
sudo firewall-cmd --permanent --add-service=http
# 允许HTTPS服务(自动放行443端口)
sudo firewall-cmd --permanent --add-service=https
# 查看已允许的服务
firewall-cmd --list-services
# 移除服务
sudo firewall-cmd --permanent --remove-service=http
# 重载配置(让永久规则生效)
sudo firewall-cmd --reload
4.2 端口管理
bash
# 开放指定端口
sudo firewall-cmd --permanent --add-port=8080/tcp
# 开放端口范围
sudo firewall-cmd --permanent --add-port=3000-3100/tcp
# 查看已开放的端口
firewall-cmd --list-ports
# 关闭端口
sudo firewall-cmd --permanent --remove-port=8080/tcp
# 重载
sudo firewall-cmd --reload
4.3 富规则(Rich Rule):精确访问控制
普通的--add-port会让所有人 都能访问该端口。如果需要限制访问来源(如只允许特定IP访问SSH),就需要富规则。
bash
# 只允许 192.168.1.100 访问SSH(22端口)
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="192.168.1.100"
port protocol="tcp" port="22"
accept'
# 拒绝某个IP访问所有服务
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="203.0.113.50"
reject'
# 允许某个网段访问特定端口
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="10.0.0.0/24"
port protocol="tcp" port="3306"
accept'
sudo firewall-cmd --reload
富规则格式解读:
-
rule family="ipv4":规则作用于IPv4 -
source address="IP":限制来源IP -
port protocol="tcp" port="端口":限制协议和端口 -
accept / reject / drop:动作
4.4 查看与删除规则
bash
# 查看所有富规则
firewall-cmd --list-rich-rules
# 删除富规则(需要完全匹配规则内容)
sudo firewall-cmd --permanent --remove-rich-rule='
rule family="ipv4"
source address="192.168.1.100"
port protocol="tcp" port="22"
accept'
sudo firewall-cmd --reload
4.5 完整配置示例
以下是一个Web服务器的标准防火墙配置:
bash
# 1. 确认firewalld正在运行
sudo systemctl status firewalld
# 2. 查看默认区域
firewall-cmd --get-default-zone # 通常为 public
# 3. 开放HTTP和HTTPS(所有IP可访问)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# 4. SSH只允许公司IP访问(富规则)
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="203.0.113.0/24"
port protocol="tcp" port="22"
accept'
# 5. 移除SSH的通用开放(如果之前开放过)
sudo firewall-cmd --permanent --remove-service=ssh
# 6. 应用所有配置
sudo firewall-cmd --reload
# 7. 验证配置
firewall-cmd --list-all
五、紧急情况下的"拔网线"
如果服务器正在遭受DDoS攻击或发现被入侵,你需要立即切断所有网络流量 ,给自己留出排查时间。这就是firewalld的panic模式。
bash
# 紧急断网(阻断所有入站和出站流量,仅保留已有连接)
sudo firewall-cmd --panic-on
# 检查是否处于panic模式
firewall-cmd --query-panic
# 恢复正常(规则恢复为panic-on之前的状态)
sudo firewall-cmd --panic-off
什么时候使用?
-
发现服务器被DDoS攻击,流量异常
-
检测到可疑的网络行为(如未知进程在往外传数据)
-
正在进行安全事件应急响应,需要隔离服务器
⚠️ 注意 :panic模式会阻断所有网络流量 。如果你是SSH远程连接的,执行
panic-on后你的SSH连接也会断开!所以这个操作通常需要在有带外管理(如VNC控制台)的情况下使用。
六、iptables vs firewalld:如何选择?
| 对比维度 | iptables | firewalld |
|---|---|---|
| 出现年代 | Linux 2.4(2001年) | RHEL/CentOS 7(2014年) |
| 规则修改 | 整体替换,可能中断连接 | 动态修改,不影响现有连接 |
| 持久化 | 需手动iptables-save |
--permanent自动保存 |
| 易用性 | 语法复杂,需要理解表链 | Zone+Service抽象,更直观 |
| 底层 | 直接操作内核netfilter | 封装iptables或nftables |
选择建议:
| 场景 | 推荐 |
|---|---|
| 新系统、初学防火墙 | firewalld |
| 日常端口管理 | firewalld |
| 复杂NAT规则、特殊协议 | iptables |
| 老系统(CentOS 6) | iptables |
| Docker/K8s环境 | 直接用iptables(Docker自动管理) |
核心原则 :不要同时运行iptables和firewalld,否则规则会互相冲突。如果你在用CentOS 7+、RHEL 7+或Fedora,直接使用firewalld即可。
七、本篇小结
iptables核心:
-
四表:raw(连接追踪)→ mangle(数据包修改)→ nat(地址转换)→ filter(过滤,最常用)
-
五链:PREROUTING → INPUT/FORWARD → OUTPUT → POSTROUTING
-
数据包按表优先级和链顺序依次匹配规则
firewalld核心命令:
| 操作 | 命令 |
|---|---|
| 开放服务 | firewall-cmd --permanent --add-service=http |
| 开放端口 | firewall-cmd --permanent --add-port=8080/tcp |
| IP限制访问 | firewall-cmd --permanent --add-rich-rule='...' |
| 查看规则 | firewall-cmd --list-all |
| 重载配置 | firewall-cmd --reload |
| 紧急断网 | firewall-cmd --panic-on |
| 恢复网络 | firewall-cmd --panic-off |
关键原则:
-
最小权限:只开放必要的端口,能用富规则限制来源IP就不全局开放
-
先测试后保存 :临时规则确认无误后,再加
--permanent -
永远留后路:修改防火墙前确保有回滚方式(云服务器至少保留VNC控制台通道)
动手练习
bash
# 1. 检查防火墙状态
sudo systemctl status firewalld
firewall-cmd --state
# 2. 查看当前所有规则
firewall-cmd --list-all
# 3. 临时开放一个测试端口
sudo firewall-cmd --add-port=8888/tcp
firewall-cmd --list-ports
# 4. 移除并确认(不加--permanent,重启消失)
sudo firewall-cmd --remove-port=8888/tcp
# 5. 练习富规则(仅允许本机IP访问22端口——测试用,确认前不要加--permanent)
# firewall-cmd --add-rich-rule='rule family="ipv4" source address="你的IP" port port="22" protocol="tcp" accept'
# firewall-cmd --list-rich-rules
# firewall-cmd --remove-rich-rule='...' # 用同样的规则内容移除
八、下篇预告
防火墙保护了端口,但真正处理请求的是Web服务器。下一篇我们将进入Nginx入门------高性能Web服务器搭建 ,学习如何安装Nginx、配置虚拟主机、理解反向代理的概念,以及那个运维最常用的命令------nginx -s reload的平滑重启原理。
延伸思考 :为什么firewalld的public区域默认拒绝入站连接?这是安全上的"默认拒绝"原则------凡是没明确允许的,一律禁止。就像一栋大楼,默认所有门都锁着,只有你需要用的房间才配钥匙。这个原则也是纵深防御体系的基础。