模块04:防火墙基础
安全域 + NAT + ACL,出口核心
拓扑
模块 3 基础上添加 2 台 Cisco ASAv + 3 台 DMZ 服务器 + 2 台二层接入交换机 + 1 台 ISP 路由器
练习内容
- ASAv Active/Standby HA 配置:配置同步,故障自动切换
- 安全域划分:Trust(内网)、Untrust(公网)、DMZ(服务器)
- 域间安全策略 :
- Trust→Untrust:允许所有内网上网
- Trust→DMZ:允许内网访问所有服务器
- Untrust→DMZ:仅允许 80/443/53 端口
- Untrust→Trust:默认拒绝所有
- NAT 三类实操 :
- 源 NAT(PAT):内网用户上网转换公网地址
- 目的 NAT(端口映射):
203.0.113.10:80→10.1.99.10:80 - 一对一 NAT:ERP 服务器固定公网 IP
203.0.113.11
验证:内网能正常上网;外网能访问 DMZ 的 WEB 服务器;防火墙主备切换上网不中断
实验拓扑与新增设备
1. 新增设备
| 设备类型 | 数量 | EVE-NG 命名 | 角色 |
|---|---|---|---|
| Cisco ASAv | 2 | ASA1(Active)、ASA2(Standby) | 出口防火墙(主备 HA) |
| Linux | 3 | DMZ-WEB、DMZ-DNS、DMZ-ERP | DMZ 区域服务器 |
| 二层交换机 | 1 | DMZ-SW | DMZ区域二层接入(汇聚ASA DMZ口与服务器) |
| 二层交换机 | 1 | ISP-SW | Outside区域二层接入(汇聚ASA Outside口与ISP) |
| 路由器 | 1 | ISP-Router | 模拟 ISP 公网路由器(提供外网测试源与公网路由) |
模块 3 所有设备(Core1、Core2、Access1-3、AR-Old、PC1-PC6)保持不变。
2. 新增 VLAN 规划
| VLAN | 名称 | 网段 | 用途 |
|---|---|---|---|
| VLAN 50 | FW-Inside | 10.1.50.0/24 |
核心↔防火墙内网互联 |
| VLAN 60 | FW-Outside | 203.0.113.0/24 |
防火墙公网出口(模拟 ISP) |
| VLAN 99 | DMZ | 10.1.99.0/24 |
DMZ 服务器区域 |
原有 VLAN 10/20/30/100/200/201 保持不变。AR-Old 仍通过 VLAN 200/201 连接核心,模拟老旧厂区专线。
3. ASAv 与 ISP-Router 接口 IP 规划
| 设备 | 接口 | 物理 IP | Standby IP | 虚拟 IP(Active 持有) | 安全域/角色 |
|---|---|---|---|---|---|
| ASA1/ASA2 | Gi0/0(Inside) | 10.1.50.1 / .2 |
10.1.50.2 / .1 |
10.1.50.1 |
Trust(内网) |
| ASA1/ASA2 | Gi0/1(Outside) | 203.0.113.1 / .2 |
203.0.113.2 / .1 |
203.0.113.1 |
Untrust(公网) |
| ASA1/ASA2 | Gi0/2(DMZ) | 10.1.99.1 / .2 |
10.1.99.2 / .1 |
10.1.99.1 |
DMZ(服务器) |
| ISP-Router | Gi0/0 | 203.0.113.253 |
- | - | ISP 公网网关 |
注意:Cisco ASA 的 Failover 机制中,Active 设备持有主 IP,Standby 设备持有 Standby IP。因此虚拟 IP 即为主 IP。
4. Failover 专用链路
| 用途 | 网段 | ASA1 | ASA2 |
|---|---|---|---|
| Failover 心跳(LAN Failover) | 192.168.255.0/30 |
Gi0/3 : 192.168.255.1 |
Gi0/3 : 192.168.255.2 |
| Stateful Failover(状态同步) | 192.168.254.0/30 |
Gi0/4 : 192.168.254.1 |
Gi0/4 : 192.168.254.2 |
5. 核心交换机新增 SVI
| 设备 | SVI | IP | 用途 |
|---|---|---|---|
| Core1 | VLAN 50 | 10.1.50.252/24 |
连接防火墙内网(VRRP VIP: 10.1.50.253) |
| Core2 | VLAN 50 | 10.1.50.251/24 |
连接防火墙内网(VRRP Backup) |
注意 :VLAN 50 的 VRRP VIP 设为 10.1.50.253。
核心交换机默认路由规划 :
由于 ASA 的 Active 设备持有 Inside 主 IP 10.1.50.1,核心交换机需配置浮动静态路由指向防火墙:
- 主默认路由指向 ASA1 (Active):
10.1.50.1 - 备用默认路由指向 ASA2 (Standby):
10.1.50.2
6. DMZ 服务器 IP 规划
| 服务器 | IP | 网关 | 服务 | NAT 映射 |
|---|---|---|---|---|
| DMZ-WEB | 10.1.99.10/24 |
10.1.99.1(FW虚拟IP) |
HTTP/HTTPS | 203.0.113.10:80 → 10.1.99.10:80 |
| DMZ-DNS | 10.1.99.20/24 |
10.1.99.1 |
DNS | 203.0.113.10:53 → 10.1.99.20:53 |
| DMZ-ERP | 10.1.99.30/24 |
10.1.99.1 |
ERP | 一对一 NAT: 203.0.113.11 ↔ 10.1.99.30 |
7. 物理连接表(EVE-NG 新增连线)
防火墙 ↔ 核心交换机(Inside 方向 - VLAN 50)
| 设备 A | 端口 | 设备 B | 端口 | 说明 |
|---|---|---|---|---|
| Core1 | Gi1/2 | ASA1 | Gi0/0 | Inside(Access VLAN 50) |
| Core2 | Gi1/2 | ASA2 | Gi0/0 | Inside(Access VLAN 50) |
为保证 Active 防火墙能同时与两台核心通信,Core1↔ASA1 和 Core2↔ASA2 的 Inside 链路均在同一 VLAN 50 广播域。由于 Core1↔Core2 之间有 LACP 聚合 Trunk(允许 VLAN 50),ASA1(Active)可通过 Core1→Core2 路径到达 Core2。
防火墙 ↔ ISP/公网(Outside 方向 - VLAN 60)
| 设备 A | 端口 | 设备 B | 端口 | 说明 |
|---|---|---|---|---|
| ISP-Router | Gi0/0 | ISP-SW | Gi0/0 | 公网路由器连接公网交换机 |
| ASA1 | Gi0/1 | ISP-SW | Gi0/1 | Outside 接入公网交换机 |
| ASA2 | Gi0/1 | ISP-SW | Gi0/2 | Outside 接入公网交换机 |
防火墙 ↔ DMZ(VLAN 99)
| 设备 A | 端口 | 设备 B | 端口 | 说明 |
|---|---|---|---|---|
| ASA1 | Gi0/2 | DMZ-SW | Gi0/0 | ASA1 DMZ 接口接入 DMZ 交换机 |
| ASA2 | Gi0/2 | DMZ-SW | Gi0/1 | ASA2 DMZ 接口接入 DMZ 交换机 |
| DMZ-WEB | e0 | DMZ-SW | Gi0/2 | Web 服务器接入 |
| DMZ-DNS | e0 | DMZ-SW | Gi0/3 | DNS 服务器接入 |
| DMZ-ERP | e0 | DMZ-SW | Gi1/0 | ERP 服务器接入 |
三台 DMZ 服务器与两台 ASA 的 DMZ 接口通过 DMZ-SW 连接在同一 VLAN 99 广播域。
ASA Failover 直连
| 设备 A | 端口 | 设备 B | 端口 | 说明 |
|---|---|---|---|---|
| ASA1 | Gi0/3 | ASA2 | Gi0/3 | Failover 心跳线 |
| ASA1 | Gi0/4 | ASA2 | Gi0/4 | Stateful Failover 状态同步线 |
拓扑图

实现
一、基础配置准备
1. 核心交换机新增 VLAN 与 Trunk 调整
(1)Core1、Core2 均执行(VLAN 创建)
在核心交换机 Core1/Core2 上创建 VLAN 50(FW-Inside,用于与防火墙互联)和 VLAN 99(DMZ,用于规划服务器区域)的二层 VLAN 实例。
bash
Core1# configure terminal
# 创建防火墙内网互联 VLAN
Core1(config)# vlan 50
Core1(config-vlan)# name FW-Inside
Core1(config-vlan)# exit
# 创建 DMZ VLAN
# VLAN 99 仅用于 ASA DMZ 接口与 DMZ-SW 之间的二层互联
# 核心交换机不创建 SVI、不加入 Trunk、不宣告 OSPF,此处仅为规划完整性
Core1(config)# vlan 99
Core1(config-vlan)# name DMZ
Core1(config-vlan)# exit
命令解析
vlan 50vlan: 创建/进入 VLAN 配置子模式的关键字,固定写法50: VLAN ID(VLAN编号),自主命名,但有严格约束
约束要求:
- 标准 VLAN 范围:
1-1005(其中 1 为默认 VLAN,1002-1005 为保留用途,不可删除)- 扩展 VLAN 范围:
1006-4094- VLAN 1 是默认 VLAN,不可删除
- 同设备内 VLAN ID 必须唯一
- 建议:关键业务使用 2-999 之间,避免使用 1 和接近上限的编号
name FW-Insidename: 为 VLAN 命名的关键字,固定写法FW-Inside: VLAN 的描述性名称,自主命名
约束要求:
- 名称长度建议不超过 32 个字符
- 不能包含空格,通常使用连字符
-或下划线_连接- 区分大小写(实际存储大小写,但不影响功能)
- 命名建议见名知意,如
FW-Inside表示"防火墙内网互联",DMZ表示"非军事区"- 可为空(不配置 name 也不影响 VLAN 功能),但强烈建议配置便于运维
(2)Core1 新增物理接口配置(连接 ASA1 Inside)
在 Core1 上将 Gi1/2 配置为 access 模式,划入 VLAN 50,并激活接口,用于与 ASA1 的 inside 接口互联。
bash
Core1(config)# interface GigabitEthernet1/2
Core1(config-if)# description To_ASA1_Inside
Core1(config-if)# switchport mode access
Core1(config-if)# switchport access vlan 50
Core1(config-if)# no shutdown
Core1(config-if)# exit
(3)Core2 新增物理接口配置(连接 ASA2 Inside)
在 Core2 上将 Gi1/2 配置为 access 模式,划入 VLAN 50,并激活接口,用于与 ASA2 的 inside 接口互联。
bash
Core2(config)# interface GigabitEthernet1/2
Core2(config-if)# description To_ASA2_Inside
Core2(config-if)# switchport mode access
Core2(config-if)# switchport access vlan 50
Core2(config-if)# no shutdown
Core2(config-if)# exit
命令解析
interface GigabitEthernet1/2interface: 进入特定接口配置子模式的关键字,固定写法,可缩写为intGigabitEthernet1/2: 接口类型与编号,半固定半约束
约束要求:
- 接口类型关键字(固定写法):
GigabitEthernet(千兆电口/光口),可缩写为Gi或G/g- 编号格式(由硬件决定,不可改):
1/2表示"槽位 1 / 端口 2",不同设备编号规则不同- 必须匹配物理设备上实际存在的接口编号,否则会报错
- 可用
show ip interface brief查看设备上所有可用接口
description To_ASA2_Insidedescription: 为接口添加备注说明的关键字,固定写法,可缩写为descTo_ASA2_Inside: 接口的描述性名称,自主命名
约束要求:
- 描述文本支持空格(整条描述用空格连接也可,如
To ASA2 Inside),但示例使用下划线是常见规范- 长度一般最多 240 字符
- 纯备注性质,不影响任何功能,建议务必填写以方便运维排查
- 推荐命名规范:方向/用途_对端设备_对端接口 ,如
To_ASA2_Inside表示"去往 ASA2 的 Inside 接口"
switchport mode accessswitchport: 将接口设为二层交换模式的关键字,固定写法mode: 指定接口模式的子关键字,固定写法access: 模式类型 access (接入模式),固定写法(多选项之一)
约束要求:
- switchport mode 的可选值(固定枚举):
- access:接入模式,只能属于一个 VLAN,用于连接终端/服务器/防火墙物理接口
- trunk:干道模式,可承载多个 VLAN,用于交换机之间互联
- access 与 trunk 互斥,一个接口不能同时配两种模式
- 某些三层口(如路由器接口)默认没有 switchport,需先执行 switchport 把它变成二层口才可继续配置
switchport access vlan 50switchport access: 指定 access 接口归属 VLAN 的关键字组合,固定写法vlan: VLAN 关键字,固定写法50: 归属的 VLAN ID,自主命名,但有约束
约束要求:
- 该 VLAN 必须已在设备上创建(即之前需执行过
vlan 50),否则接口虽然能配但实际流量不通- VLAN ID 范围
1-4094- 默认情况下,不配置此命令时接口归属于 VLAN 1
- 仅对
switchport mode access的接口有意义;对 trunk 口无效(trunk 口使用switchport trunk allowed vlan等命令)
(4)调整 LACP 聚合口(Po1)允许的 VLAN 列表
Core1 和 Core2 均执行,将 VLAN 50 加入核心互联 Trunk
bash
Core1(config)# interface Port-channel 1
Core1(config-if)# switchport trunk allowed vlan add 50
Core1(config-if)# exit
⚠️ 注意:add 关键字是在原有允许列表基础上追加,不会覆盖已有的 VLAN 10,20,30,100。
命令解析
interface Port-channel 1interface: 进入特定接口配置子模式的关键字,固定写法,可缩写为intPort-channel: 聚合接口(EtherChannel)类型关键字,固定写法,可缩写为Po/po1: Port-channel编号(聚合组编号),自主命名,但有约束
约束要求:
- 编号范围通常为 1-64(不同平台可能支持到 48 或 256)
- Port-channel 接口是逻辑接口,由多个物理接口捆绑而成,与物理接口
GigabitEthernet不同- 必须先有物理接口加入对应聚合组(如物理接口配置
channel-group 1 mode on/active/passive),此 Port-channel 才真正有流量承载- 编号在同一设备内必须唯一
- 可通过
show etherchannel summary查看聚合组状态
switchport trunk allowed vlan add 50switchport: 二层交换模式关键字,固定写法trunk: trunk模式相关关键字,固定写法allowed: 允许通行的 VLAN 相关关键字,固定写法vlan: VLAN 关键字,固定写法add: "追加"模式关键字(在已有允许列表基础上新增),固定写法(多选项之一)50: 要追加允许通过的 VLAN ID,自主命名,但有约束
约束要求:
switchport trunk allowed vlan的完整选项(固定枚举):
switchport trunk allowed vlan 10,20,30--- 覆盖式设置,只允许指定 VLAN(最常见,推荐)switchport trunk allowed vlan add 50--- 追加,在已有允许列表基础上新增 50switchport trunk allowed vlan remove 50--- 移除,从允许列表中删除 50switchport trunk allowed vlan all--- 允许所有 VLAN(默认情况,但不推荐)switchport trunk allowed vlan except 100-200--- 除指定范围外全部允许- 关于
add的特别提醒:
add是"增量添加",不会覆盖已有配置。这意味着如果之前 trunk 允许了 VLAN 1-49,执行add 50后将允许 1-50- 如果是新配置的 trunk 接口,应直接使用
switchport trunk allowed vlan 1,50,99(明确列出),而不使用 addadd更适用于修改已有 trunk 配置的场景- VLAN ID 约束:
- VLAN 必须已在本设备创建
- 可指定单个(
50)、列表(1,50,99)、范围(10-20)或组合(1,10-20,50)- 两端 trunk 接口允许的 VLAN 必须匹配,否则该 VLAN 不通
- 先决条件:
- 必须先将接口模式设为 trunk:
switchport mode trunk(或通过协商成为 trunk)- 此命令对 access 模式的接口无效
2. 核心交换机 VLAN 50 SVI 与 VRRP 配置
(1)Core1(VRRP Master)
在 Core1 上创建 VLAN 50 的 SVI 接口,配置 IP 10.1.50.252/24,并启用 VRRP 组 50(虚拟网关 10.1.50.253,优先级 150,可抢占),作为核心交换机与防火墙互联的主网关。
bash
Core1(config)# interface Vlan50
Core1(config-if)# ip address 10.1.50.252 255.255.255.0
# VRRP 组 50,虚拟网关 IP 指向 10.1.50.253
Core1(config-if)# vrrp 50 ip 10.1.50.253
Core1(config-if)# vrrp 50 priority 150
Core1(config-if)# vrrp 50 preempt
Core1(config-if)# no shutdown
Core1(config-if)# exit
(2)Core2(VRRP Backup)
在 Core2 上创建 VLAN 50 的 SVI 接口,配置 IP 10.1.50.251/24,并启用 VRRP 组 50(虚拟网关 10.1.50.253,优先级 100,可抢占),作为核心交换机与防火墙互联的备用网关。
bash
Core2(config)# interface Vlan50
Core2(config-if)# ip address 10.1.50.251 255.255.255.0
Core2(config-if)# vrrp 50 ip 10.1.50.253
Core2(config-if)# vrrp 50 priority 100
Core2(config-if)# vrrp 50 preempt
Core2(config-if)# no shutdown
Core2(config-if)# exit
命令解析
interface Vlan50interface: 进入接口配置模式的关键字,固定写法,可缩写为intVlan: VLAN 的 SVI(Switch Virtual Interface,VLAN三层虚拟接口)类型关键字,固定写法,可缩写为vl50: VLAN ID,自主命名,但有约束
约束要求:
- VLAN 必须已在设备上创建(vlan 50),此 SVI 才真正关联到 VLAN
- 对应 VLAN 内必须至少有一个物理接口处于 up/up 状态,SVI 才会 up
- 同一设备上同一 VLAN 的 SVI 只能有一个
ip address 10.1.50.252 255.255.255.0ip address: IP 地址关键字,固定写法10.1.50.252: 接口的实际 IP 地址,自主命名,但有约束255.255.255.0: 子网掩码,自主命名,但受网络规划约束
约束要求:
- 子网掩码必须一致;同 VLAN 内所有设备 IP 必须在同一子网内
- Master 和 Backup 的物理 IP 必须不同(252 和 251),但在同一子网
- 虚拟网关 IP(253)也必须在同一子网内
- 三台设备(252、251、253)之间不能冲突
- 主机位全 0 是网络地址、全 1 是广播地址,不可用
vrrp 50 ip 10.1.50.253vrrp: VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)关键字,固定写法50: VRRP 组号(Group ID),自主命名,但有约束ip: 指定虚拟 IP 的子关键字,固定写法10.1.50.253: 虚拟网关 IP 地址,自主命名,但有约束
约束要求:
- VRRP 组号范围通常
1-255- Master 和 Backup 必须使用相同的组号(此处都是 50)才能组成一个虚拟路由器
- 虚拟 IP 必须与 SVI 接口的物理 IP 同子网
- 虚拟 IP 不能与任何物理 IP 相同(253 既不是 252 也不是 251)
- 虚拟 IP 作为该 VLAN 下所有主机的默认网关
- 两端设备配置必须有一台设备为 Master,另一台为 Backup
vrrp 50 priority 150vrrp: VRRP 关键字,固定写法50: VRRP 组号(Group ID),自主命名,但有约束priority: 优先级子关键字,固定写法150: 优先级值,自主命名,但有约束
约束要求:
- 优先级范围
1-254,默认值 100- 优先级高为 Master(此处 Core1=150,Core2=100,因此 Core1 为 Master)
- 同一 VRRP 组内,优先级最高的设备成为 Master
- 如果配置
vrrp 50 ip <ip>接口上配置了虚拟 IP 与接口 IP 相同(即"地址拥有者",其优先级强制为 255,始终为 Master 且不可抢占)
vrrp 50 preemptvrrp 50: 指定 VRRP 组 50 关键字,固定写法preempt: 抢占模式关键字,固定写法
约束要求:
- 无参数,整条命令格式固定
- 显式声明 VRRP 启用抢占模式
- 配置
preempt后:当高优先级设备恢复后,会自动抢占回 Master- 推荐两端都配置
preempt,保证高优先级始终为 Master,主备角色可预测
3. 核心交换机默认路由指向防火墙
Core1 和 Core2 均执行
在 Core1 和 Core2 上配置两条浮动静态默认路由:主路由指向 ASA1 的 Inside 主 IP(10.1.50.1),备用路由指向 ASA2 的 Inside Standby IP(10.1.50.2,优先级 20),实现防火墙主备切换时的自动路径切换。
bash
# 将主默认路由指向防火墙 Inside 主 IP (ASA1 Active)
Core1(config)# ip route 0.0.0.0 0.0.0.0 10.1.50.1
# 将备用默认路由指向防火墙 Inside Standby IP (ASA2 Standby),优先级设为 20
Core1(config)# ip route 0.0.0.0 0.0.0.0 10.1.50.2 20
Core2(config)# ip route 0.0.0.0 0.0.0.0 10.1.50.1
Core2(config)# ip route 0.0.0.0 0.0.0.0 10.1.50.2 20
原有的
default-information originate always会将此默认路由通过 OSPF 下发给接入层交换机。
命令解析
ip route 0.0.0.0 0.0.0.0 10.1.50.1ip route: 配置静态路由的关键字,固定写法0.0.0.0: 目标网络地址(此处代表所有网络,即默认路由),固定写法,0.0.0.0是固定的"任意网络"写法0.0.0.0: 目标网络掩码(此处与地址配合代表匹配所有),固定写法,与地址0.0.0.0配合组成默认路由,表示不检查任何位,即匹配所有目标地址10.1.50.1: 下一跳 IP 地址(数据包发往此地址),自主命名,受网络拓扑约束
约束要求:
0.0.0.0 0.0.0.0组合表示"匹配任意目标网络",即默认路由(default route),用于所有未匹配到更精确路由的数据包- 下一跳 IP(10.1.50.1)必须是直连可达的地址,即必须在设备某接口的直连子网内(此处 10.1.50.1 是 ASA1 的 Inside 接口 IP,Core1 通过 VLAN 50 的 SVI 直连可达)
- 下一跳 IP 不能是本地接口自身的 IP
- 默认管理距离(Administrative Distance)为 1(静态路由默认值),不写参数即使用默认值
ip route 0.0.0.0 0.0.0.0 10.1.50.2 20ip route 0.0.0.0 0.0.0.0: 默认路由固定写法,固定写法10.1.50.2: 备用下一跳 IP(ASA2 的 Inside 接口),自主命名20: 管理距离(AD 值),自主命名,有约束
关键要点:浮动静态路由(Floating Static Route)
- 管理距离(Administrative Distance, AD)的含义:
- AD 值越小,路由来源越可信,越优先被使用
- 常见 AD 值(固定值):
- 直连路由:0
- 静态路由:1
- EIGRP 汇总:5
- OSPF:110
- RIP:120
- 不达:255
20的作用:
- 正常静态路由默认 AD=1,这条手动改为 AD=20
- 当第一条默认路由(AD=1,下一跳 10.1.50.1)有效时,仅第一条进入路由表,AD=20 的备用路由被隐藏
- 当第一条失效(例如 ASA1 Inside 不可达,或 Core1 到 ASA1 的链路故障),AD=1 的路由从路由表移除,AD=20 的浮动路由自动浮出进入路由表生效
- 当主路由恢复后,AD=1 更优,自动切回主路由
- AD 的约束:
- 范围
1-255- 主路由与备用路由的 AD 必须不同,否则会形成等成本负载均衡(ECMP),两条同时生效,而非主备切换
- 备用路由的 AD 必须大于主路由的 AD,且建议大于所有动态路由协议的 AD(例如如果运行 OSPF,备用静态路由 AD 应大于 110),避免意外覆盖动态路由
- 建议值:主路由默认 1(不写),备用路由用 20、50、100 等
- 下一跳约束:
10.1.50.2同样必须是直连可达的地址(ASA2 的 Inside 接口,通过同一 VLAN 50 直连)
4. 核心交换机添加 DMZ 路由(覆盖黑洞路由)
Core1 和 Core2 均执行:
在 Core1 和 Core2 上添加指向 10.1.50.1 的精确静态路由 10.1.99.0/24,以确保内网访问 DMZ 时绕过原有 10.1.0.0/16 黑洞汇总路由,使流量正确转发至 ASA 防火墙。
bash
Core1(config)# ip route 10.1.99.0 255.255.255.0 10.1.50.1
Core2(config)# ip route 10.1.99.0 255.255.255.0 10.1.50.1
关键说明:
10.1.99.0/24比10.1.0.0/16掩码更长(/24 > /16),根据最长前缀匹配原则优先匹配- 黑洞路由
10.1.0.0/16无需删除,继续为模块02/03的 RIP 重分发提供防环保护 - 下一跳
10.1.50.1指向 ASA Inside 接口(由 ASA 负责转发到 DMZ)
⚠️ 前置依赖说明 :模块02 中配置了
ip route 10.1.0.0 255.255.0.0 Null0黑洞路由用于 OSPF 汇总防环和 RIP 重分发。由于 DMZ 网段
10.1.99.0/24落入该汇总范围,如果不添加更精确的路由,内网访问 DMZ 的流量将被 Null0 丢弃。
5. OSPF 宣告新增网段
Core1 和 Core2 的 OSPF 进程中追加 VLAN 50 网段
在 Core1 和 Core2 的 OSPF 进程中宣告 10.1.50.0/24 进入 Area 0,并将 VLAN 50 设为 passive-interface,使接入层通过 OSPF 学习到防火墙互联网段,同时避免在与 ASA 互联链路上建立 OSPF 邻居。
bash
Core1(config)# router ospf 1
Core1(config-router)# network 10.1.50.0 0.0.0.255 area 0
Core1(config-router)# passive-interface vlan 50
Core1(config-router)# exit
VLAN 50 设为被动接口,防止在防火墙互联口建立不必要的 OSPF 邻居。
命令解析
router ospf 1router: 进入路由协议配置模式的关键字,固定写法ospf: 指定路由协议为 OSPF 的关键字,固定写法1: OSPF 进程号(Process ID),自主命名,但有约束
约束要求:
- 进程号范围
1-65535- 进程号仅具有本地意义,不同路由之间可以不同,不影响建立邻居
- 同一台设备上可以运行多个 OSPF 进程,以进程号区分(不同进程互相独立)
- 本拓扑中 Core1 和 Core2 都用
1只是为了便于管理,并非必须一致
network 10.1.50.0 0.0.0.255 area 0network: 宣告网络进入 OSPF 的关键字,固定写法10.1.50.0: 网络号(Network),自主命名,但有约束0.0.0.255: 反掩码(Wildcard Mask,通配符掩码),自主命名,但有约束area: 指定区域的子关键字,固定写法0: OSPF 区域号(Area ID),自主命名,但有约束
约束要求:
network + 反掩码的作用是匹配接口 IP:只要某个接口 IP 在该范围内,该接口就加入此区域,并在该接口上启用 OSPF- 反掩码
0.0.0.255表示前 24 位精确匹配、后 8 位任意,等价于/24- 反掩码不是子网掩码,二者逻辑相反:反掩码中
0=必须匹配,255=任意- 区域号范围
0-4294967295,也可写成点分十进制(如area 0.0.0.0)- 骨干区域必须为
area 0(或area 0.0.0.0),所有非骨干区域必须直接连接骨干区域- 本命令宣告
10.1.50.0/24进入骨干区域0,使 VLAN 50 网段被其他 OSPF 邻居学习到
passive-interface vlan 50passive-interface: 配置被动接口的关键字,固定写法vlan 50: 指定接口类型为 VLAN SVI 的子关键字,固定写法50: VLAN ID,自主命名,但有约束
约束要求:
vlan 50必须是设备上已存在的接口(需先配置interface Vlan50)- 被动接口:只接收、不发送 OSPF Hello 报文,因此该接口上无法建立 OSPF 邻居
- 被动接口所在的网段仍然会被宣告进 OSPF(这正是我们的目的)
- 本拓扑中 VLAN 50 连接的是 ASA 防火墙,防火墙不运行 OSPF,因此设为 passive 避免发送无用的 Hello 报文
- 若省略此命令,Core1/Core2 会在 VLAN 50 上持续发送 Hello,浪费链路带宽且无法建立邻居
6. DMZ-SW 与 ISP-SW 基础二层配置
(1)DMZ-SW 配置
在 DMZ-SW 上创建 VLAN 99(DMZ),并将 Gi0/0-Gi0/3 和 Gi1/0 统一配置为 access 模式划入 VLAN 99 后激活,实现 ASA 防火墙 DMZ 接口与三台 DMZ 服务器在同一二层广播域内互联。
bash
DMZ-SW# configure terminal
# 将连接 ASA 和 服务器的接口全部划入 VLAN 99
DMZ-SW(config)# vlan 99
DMZ-SW(config-vlan)# name DMZ
DMZ-SW(config-vlan)# exit
DMZ-SW(config)# interface range Gi0/0 - 3 , Gi1/0
DMZ-SW(config-if-range)# switchport mode access
DMZ-SW(config-if-range)# switchport access vlan 99
DMZ-SW(config-if-range)# no shutdown
DMZ-SW(config-if-range)# exit
(2)ISP-SW 配置
在 ISP-SW 上创建 VLAN 60(Outside-Public),并将 Gi0/0-Gi0/2 统一配置为 access 模式划入 VLAN 60 后激活,实现两台 ASA 的 outside 接口与 ISP 路由器在同一公网二层广播域内互联。
bash
ISP-SW# configure terminal
# 将连接 ASA 和 ISP 路由器的接口全部划入 VLAN 60
ISP-SW(config)# vlan 60
ISP-SW(config-vlan)# name Outside-Public
ISP-SW(config-vlan)# exit
ISP-SW(config)# interface range Gi0/0 - 2
ISP-SW(config-if-range)# switchport mode access
ISP-SW(config-if-range)# switchport access vlan 60
ISP-SW(config-if-range)# no shutdown
ISP-SW(config-if-range)# exit
7. ISP-Router 基础配置
在 ISP-Router 上为 Gi0/0 配置公网 IP 203.0.113.253/24 并激活,同时添加一条指向 ASA outside 主 IP(203.0.113.1)的默认路由和两条 NAT 公网地址(.10/.11)的精确静态路由,以模拟公网路由器的回程路径。
bash
ISP-Router# configure terminal
ISP-Router(config)# interface GigabitEthernet0/0
ISP-Router(config-if)# ip address 203.0.113.253 255.255.255.0
ISP-Router(config-if)# no shutdown
ISP-Router(config-if)# exit
# 配置指向防火墙 Outside 主 IP 的默认路由(模拟公网回程路由)
ISP-Router(config)# ip route 0.0.0.0 0.0.0.0 203.0.113.1
# 配置指向 NAT 公网 IP 池的静态路由(让外网测试流量能到达 ASA)
ISP-Router(config)# ip route 203.0.113.10 255.255.255.255 203.0.113.1
ISP-Router(config)# ip route 203.0.113.11 255.255.255.255 203.0.113.1
二、ASAv Active/Standby HA 配置
1. ASA1 基础初始化
将 ASA1 主机名设置为 ASA1,并为 Gi0/0(inside,安全级 100,IP 10.1.50.1/standby .2)、Gi0/1(outside,安全级 0,IP 203.0.113.1/standby .2)、Gi0/2(dmz,安全级 50,IP 10.1.99.1/standby .2)三个接口分别命名安全域并激活,为 HA 主备集群奠定基础配置。
bash
ciscoasa> enable
ciscoasa# configure terminal
# 设置主机名
ciscoasa(config)# hostname ASA1
# 配置管理密码
# ASA1(config)# enable password Cisco123
# 配置接口
# ---- Inside 接口 (Gi0/0) ----
ASA1(config)# interface GigabitEthernet0/0
ASA1(config-if)# nameif inside
ASA1(config-if)# security-level 100
ASA1(config-if)# ip address 10.1.50.1 255.255.255.0 standby 10.1.50.2
ASA1(config-if)# no shutdown
ASA1(config-if)# exit
# ---- Outside 接口 (Gi0/1) ----
ASA1(config)# interface GigabitEthernet0/1
ASA1(config-if)# nameif outside
ASA1(config-if)# security-level 0
ASA1(config-if)# ip address 203.0.113.1 255.255.255.0 standby 203.0.113.2
ASA1(config-if)# no shutdown
ASA1(config-if)# exit
# ---- DMZ 接口 (Gi0/2) ----
ASA1(config)# interface GigabitEthernet0/2
ASA1(config-if)# nameif dmz
ASA1(config-if)# security-level 50
ASA1(config-if)# ip address 10.1.99.1 255.255.255.0 standby 10.1.99.2
ASA1(config-if)# no shutdown
ASA1(config-if)# exit
命令解析
nameif insidenameif: ASA 为接口指定逻辑名称的关键字,固定写法(ASA 特有命令)inside: 接口逻辑名称,自主命名,但有强烈约束(约定俗成)
约束要求:
- ASA 的
nameif是必须配置的,所有安全策略基于此名称匹配- 名称区分大小写,
inside和Inside是不同的名称- 约定俗成:
inside=内网(高安全)、outside=外网(低安全)、dmz=非军事区- 虽然可以自定义(如
lan、wan),但强烈建议使用 inside/outside/dmz,与行业惯例和安全策略模板保持一致- 同一 ASA 上接口名称不能重复
security-level 100security-level: ASA 为接口分配安全级别的关键字,固定写法(ASA 特有命令)100: 安全级别值,自主命名,但有约束和惯例
约束要求:
- 取值范围
0-100- 100 = 最可信(通常 inside 使用),0 = 最不可信(通常 outside 使用)
- 默认行为:高安全级别可以访问低安全级别(无需 ACL);低→高需要 ACL 放行
- 常用惯例:
inside=100、dmz=50、outside=0- 同一安全级别之间默认不能互访(如需互访需配置
same-security-traffic permit inter-interface)
ip address 10.1.50.1 255.255.255.0 standby 10.1.50.2ip address: IP 地址关键字,固定写法10.1.50.1: Active(主用)IP 地址,自主命名,但有约束255.255.255.0: 子网掩码,自主命名,但受网络规划约束standby: ASA Failover 中指定备用 IP 的关键字,固定写法10.1.50.2: Standby(备用)IP 地址,自主命名,但有约束
约束要求:
standby关键字是 ASA 故障转移(Failover)的特有写法,路由器/交换机上没有此写法- Active IP 和 Standby IP 必须在同一子网
- Active IP 配置在主 ASA(ASA1)上,Standby IP 配置在备 ASA(ASA2)上,两台配置完全相同
- Active IP ≠ Standby IP,且不能与同网段其他设备冲突(252、251、253 已被核心交换机使用)
- ASA1(Active)实际使用
.1,ASA2(Standby)实际使用.2;当故障切换时 IP 随之漂移- 同 VLAN 内所有设备(252/251/253/1/2)必须在
10.1.50.0/24同一子网
2. ASA2 基础初始化
将 ASA2 主机名设置为 ASA2,并为 Gi0/0(inside,安全级 100,IP 10.1.50.2/standby .1)、Gi0/1(outside,安全级 0,IP 203.0.113.2/standby .1)、Gi0/2(dmz,安全级 50,IP 10.1.99.2/standby .1)三个接口分别命名安全域并激活,作为 HA 集群的备用节点基础配置。
bash
ciscoasa> enable
ciscoasa# configure terminal
ciscoasa(config)# hostname ASA2
# ASA2(config)# enable password Cisco123
# ---- Inside 接口 (Gi0/0) ----
ASA2(config)# interface GigabitEthernet0/0
ASA2(config-if)# nameif inside
ASA2(config-if)# security-level 100
ASA2(config-if)# ip address 10.1.50.2 255.255.255.0 standby 10.1.50.1
ASA2(config-if)# no shutdown
ASA2(config-if)# exit
# ---- Outside 接口 (Gi0/1) ----
ASA2(config)# interface GigabitEthernet0/1
ASA2(config-if)# nameif outside
ASA2(config-if)# security-level 0
ASA2(config-if)# ip address 203.0.113.2 255.255.255.0 standby 203.0.113.1
ASA2(config-if)# no shutdown
ASA2(config-if)# exit
# ---- DMZ 接口 (Gi0/2) ----
ASA2(config)# interface GigabitEthernet0/2
ASA2(config-if)# nameif dmz
ASA2(config-if)# security-level 50
ASA2(config-if)# ip address 10.1.99.2 255.255.255.0 standby 10.1.99.1
ASA2(config-if)# no shutdown
ASA2(config-if)# exit
3. Failover 配置(ASA1 为主,ASA2 为备)
(1)ASA1(Primary 单位)
在 ASA1 上配置其为 HA 集群的 Primary 主节点,启用 Gi0/3 为心跳链路(192.168.255.1/30,备机 .2)、Gi0/4 为状态同步链路(192.168.254.1/30,备机 .2),开启 failover 并设置共享密钥,建立主备关系。
bash
ASA1(config)# failover lan unit primary
ASA1(config)# failover lan interface FAILOVER_LINK GigabitEthernet0/3
ASA1(config)# failover link STATEFUL_LINK GigabitEthernet0/4
ASA1(config)# failover interface ip FAILOVER_LINK 192.168.255.1 255.255.255.252 standby 192.168.255.2
ASA1(config)# failover interface ip STATEFUL_LINK 192.168.254.1 255.255.255.252 standby 192.168.254.2
# 启用 Failover
ASA1(config)# failover
# 设置 Failover 共享密钥(加密同步数据)
ASA1(config)# failover key MySecretKey123
(2)ASA2(Secondary 单位)
在 ASA2 上配置其为 HA 集群的 Secondary 备节点,使用与 ASA1 相同的 Gi0/3 心跳和 Gi0/4 状态同步链路参数及共享密钥,启用 failover 后自动与主节点协商建立主备关系。
bash
ASA2(config)# failover lan unit secondary
ASA2(config)# failover lan interface FAILOVER_LINK GigabitEthernet0/3
ASA2(config)# failover link STATEFUL_LINK GigabitEthernet0/4
ASA2(config)# failover interface ip FAILOVER_LINK 192.168.255.1 255.255.255.252 standby 192.168.255.2
ASA2(config)# failover interface ip STATEFUL_LINK 192.168.254.1 255.255.255.252 standby 192.168.254.2
# 启用 Failover
ASA2(config)# failover
# 设置相同的共享密钥
ASA2(config)# failover key MySecretKey123
命令解析
failover lan unit primaryfailover lan unit secondaryfailover: Failover 主命令关键字,固定写法lan: 指定为基于 LAN 的 Failover(而非串行 Failover),固定写法unit: 指定本设备在 Failover 中角色身份的子关键字,固定写法primary/secondary: 本设备角色,二选一,有约束
约束要求:
- 两台 ASA 必须配置为不同角色:一台 primary,另一台 secondary
primary不一定就是 Active(活动),只是初始配置角色标识;最终谁是 Active 由优先级等因素决定- 角色一旦设定,建议不要随意变更
failover lan interface FAILOVER_LINK GigabitEthernet0/3failover: Failover 主命令关键字,固定写法lan: 指定为基于 LAN 的 Failover(LAN-based Failover),固定写法interface: 指定心跳接口的子关键字,固定写法FAILOVER_LINK: 心跳链路的逻辑名称(Nameif),自主命名,建议使用 FAILOVER_LINKGigabitEthernet0/3: 心跳使用的物理接口,自主命名,但有约束
约束要求:
- 两台 ASA 上链路名称必须完全相同(此处都叫 FAILOVER_LINK)
- 两台 ASA 上物理接口建议相同(此处都用 Gi0/3),便于维护
- 该接口专门用于 Failover 心跳报文,不能再配置普通 nameif/IP 用作数据流量
- 心跳链路必须在两台 ASA 之间直连或通过专用 VLAN 二层互通
- 心跳接口推荐使用独立物理接口,不要与数据接口复用
failover link STATEFUL_LINK GigabitEthernet0/4failover: Failover 主命令关键字,固定写法link: 指定状态同步接口的子关键字,固定写法STATEFUL_LINK: 状态同步链路的逻辑名称(Nameif),自主命名,建议使用 STATEFUL_LINKGigabitEthernet0/4: 状态同步使用的物理接口,自主命名,但有约束
约束要求:
- 两台 ASA 上链路名称必须完全相同(此处都叫 STATEFUL_LINK)
- 与心跳链路必须使用不同的物理接口(心跳用 Gi0/3,状态同步用 Gi0/4)
- 状态同步链路用于会话表、连接表等状态信息同步,流量较大,推荐单独链路
- 若省略此命令,仅配置"无状态 Failover",故障切换时现有连接会中断
- 两台 ASA 之间必须二层互通
failover interface ip FAILOVER_LINK 192.168.255.1 255.255.255.252 standby 192.168.255.2failover: Failover 主命令关键字,固定写法interface: 指定心跳接口的子关键字,固定写法ip: 指定 Failover 接口 IP 地址的子关键字,固定写法FAILOVER_LINK: 链路逻辑名称,自主命名,但必须与前文failover lan interface中定义的名称一致192.168.255.1: 本端(Primary)心跳 IP,自主命名255.255.255.252: 子网掩码(/30),自主命名,有约束standby: 指定对端 IP 的关键字,固定写法192.168.255.2: 对端(Secondary)心跳 IP,自主命名
约束要求:
- 两台 ASA 上此命令完全相同(ASA1 和 ASA2 配置一模一样)
/30掩码(255.255.255.252)是最小可用子网,仅包含 2 个可用 IP,适合心跳链路(节约地址)- 两端 IP 必须在同一子网,不冲突
- 心跳网段建议使用私网保留地址(如 192.168.255.x),避免与业务网段冲突
192.168.255.1永远是 Primary 的 IP,.2永远是 Secondary 的 IP,与当前 Active/Standby 角色无关
failover interface ip STATEFUL_LINK 192.168.254.1 255.255.255.252 standby 192.168.254.2failover: Failover 主命令关键字,固定写法interface: 指定状态同步接口的子关键字,固定写法ip: 指定 Failover 接口 IP 地址的子关键字,固定写法STATEFUL_LINK: 链路名称,自主命名,但必须与前文failover link中定义的名称一致192.168.254.1: 本端(Primary)状态同步 IP,自主命名255.255.255.252: 子网掩码(/30),自主命名,有约束standby: 指定对端 IP 的关键字,固定写法192.168.254.2: 对端(Secondary)状态同步 IP,自主命名
约束要求:
- 与心跳链路命令结构完全相同
- 必须使用不同的网段(心跳用
192.168.255.0/30,状态同步用192.168.254.0/30)- 两台 ASA 上配置完全相同
failover: 启用 Failover 功能的关键字,固定写法
约束要求:
- 无参数,整条命令固定
- 执行后 Failover 功能才真正启动,开始与对端协商
- 两台 ASA 都需要执行此命令
failover key MySecretKey123failover: Failover 主命令关键字,固定写法key: 设置 Failover 加密密钥的子关键字,固定写法MySecretKey123: 共享密钥字符串,自主命名,但有约束
约束要求:
- 两台 ASA 上密钥必须完全一致,否则无法建立 Failover 通信
- 密钥用于加密两台 ASA 之间的 Failover 和状态同步报文,防止被篡改
- 密钥长度通常 1-63 个字符(不同版本略有差异)
- 生产环境建议使用更复杂的密钥,示例中的 MySecretKey123 仅为教学演示
- 密钥区分大小写
(3)在 ASA1 (Primary) 上手动唤醒接口
因为配置没同步,需要在 ASA1 上手动把 Gi0/4 唤醒,并确保 Gi0/3 也是 up 的:
bash
ASA1(config)# interface GigabitEthernet0/3
ASA1(config-if)# no shutdown
ASA1(config-if)# exit
ASA1(config)# interface GigabitEthernet0/4
ASA1(config-if)# no shutdown
ASA1(config-if)# exit
(4)在 ASA2 (Secondary) 上手动唤醒接口并清理错误状态
同样,在 ASA2 上也需要手动唤醒这两个接口,并且 ASA2 的 dmz 接口也是 shutdown 的,一并唤醒:
bash
ASA2(config)# interface GigabitEthernet0/3
ASA2(config-if)# no shutdown
ASA2(config-if)# exit
ASA2(config)# interface GigabitEthernet0/4
ASA2(config-if)# no shutdown
ASA2(config-if)# exit
ASA2(config)# interface GigabitEthernet0/2
ASA2(config-if)# no shutdown
ASA2(config-if)# exit
(5)重置 Failover 状态,强制重新协商
由于之前发生了"脑裂"(两边都以为自己是 Active),我们需要在 ASA2 (Secondary) 上重置一下 Failover 状态,让它重新向 ASA1 学习:
bash
ASA2(config)# no failover
ASA2(config)# failover
等待大约 15-30 秒,然后在 ASA1 上执行:
4. 验证 Failover 状态
bash
# 在 ASA1 上查看 Failover 状态
ASA1# show failover
预期输出关键信息
bash
ASA1(config)# show failover
Failover On
Failover unit Primary
Failover LAN Interface: FAILOVER_LINK GigabitEthernet0/3 (up)
Reconnect timeout 0:00:00
Unit Poll frequency 1 seconds, holdtime 15 seconds
Interface Poll frequency 5 seconds, holdtime 25 seconds
Interface Policy 1
Monitored Interfaces 3 of 61 maximum
MAC Address Move Notification Interval not set
Version: Ours 9.7(1), Mate 9.7(1)
Serial Number: Ours 9AX8NBLDB91, Mate 9AWTTQDPPW0
Last Failover at: 22:36:07 UTC Jul 4 2026
This host: Primary - Active
Active time: 176 (sec)
slot 0: empty
Interface inside (10.1.50.1): Normal (Monitored)
Interface outside (203.0.113.1): Normal (Monitored)
Interface dmz (10.1.99.1): Normal (Monitored)
Other host: Secondary - Standby Ready
Active time: 28 (sec)
Interface inside (10.1.50.2): Normal (Monitored)
Interface outside (203.0.113.2): Normal (Monitored)
Interface dmz (10.1.99.2): Normal (Monitored)
Stateful Failover Logical Update Statistics
Link : STATEFUL_LINK GigabitEthernet0/4 (up)
Stateful Obj xmit xerr rcv rerr
General 8 0 6 0
sys cmd 6 0 6 0
up time 0 0 0 0
RPC services 0 0 0 0
TCP conn 0 0 0 0
UDP conn 0 0 0 0
ARP tbl 0 0 0 0
Xlate_Timeout 0 0 0 0
IPv6 ND tbl 0 0 0 0
VPN IKEv1 SA 0 0 0 0
VPN IKEv1 P2 0 0 0 0
VPN IKEv2 SA 0 0 0 0
VPN IKEv2 P2 0 0 0 0
VPN CTCP upd 0 0 0 0
VPN SDI upd 0 0 0 0
VPN DHCP upd 0 0 0 0
SIP Session 0 0 0 0
SIP Tx 0 0 0 0
SIP Pinhole 0 0 0 0
Route Session 0 0 0 0
Router ID 0 0 0 0
User-Identity 2 0 0 0
CTS SGTNAME 0 0 0 0
CTS PAC 0 0 0 0
TrustSec-SXP 0 0 0 0
IPv6 Route 0 0 0 0
STS Table 0 0 0 0
Logical Update Queue Information
Cur Max Total
Recv Q: 0 17 77
Xmit Q: 0 42 189
bash
ASA2(config)# show failover
Failover On
Failover unit Secondary
Failover LAN Interface: FAILOVER_LINK GigabitEthernet0/3 (up)
Reconnect timeout 0:00:00
Unit Poll frequency 1 seconds, holdtime 15 seconds
Interface Poll frequency 5 seconds, holdtime 25 seconds
Interface Policy 1
Monitored Interfaces 3 of 61 maximum
MAC Address Move Notification Interval not set
Version: Ours 9.7(1), Mate 9.7(1)
Serial Number: Ours 9AWTTQDPPW0, Mate 9AX8NBLDB91
Last Failover at: 22:37:03 UTC Jul 4 2026
This host: Secondary - Standby Ready
Active time: 28 (sec)
slot 0: empty
Interface inside (10.1.50.2): Normal (Monitored)
Interface outside (203.0.113.2): Normal (Monitored)
Interface dmz (10.1.99.2): Normal (Monitored)
Other host: Primary - Active
Active time: 196 (sec)
Interface inside (10.1.50.1): Normal (Monitored)
Interface outside (203.0.113.1): Normal (Monitored)
Interface dmz (10.1.99.1): Normal (Monitored)
Stateful Failover Logical Update Statistics
Link : STATEFUL_LINK GigabitEthernet0/4 (up)
Stateful Obj xmit xerr rcv rerr
General 10 0 12 0
sys cmd 10 0 10 0
up time 0 0 0 0
RPC services 0 0 0 0
TCP conn 0 0 0 0
UDP conn 0 0 0 0
ARP tbl 0 0 0 0
Xlate_Timeout 0 0 0 0
IPv6 ND tbl 0 0 0 0
VPN IKEv1 SA 0 0 0 0
VPN IKEv1 P2 0 0 0 0
VPN IKEv2 SA 0 0 0 0
VPN IKEv2 P2 0 0 0 0
VPN CTCP upd 0 0 0 0
VPN SDI upd 0 0 0 0
VPN DHCP upd 0 0 0 0
SIP Session 0 0 0 0
SIP Tx 0 0 0 0
SIP Pinhole 0 0 0 0
Route Session 0 0 0 0
Router ID 0 0 0 0
User-Identity 0 0 2 0
CTS SGTNAME 0 0 0 0
CTS PAC 0 0 0 0
TrustSec-SXP 0 0 0 0
IPv6 Route 0 0 0 0
STS Table 0 0 0 0
Logical Update Queue Information
Cur Max Total
Recv Q: 0 17 288
Xmit Q: 0 1 10
三、安全域划分与域间安全策略
1. 安全域确认
ASAv 的 nameif + security-level 已隐式完成安全域划分:
| 安全域 | 接口名 | Security Level | 对应网段 |
|---|---|---|---|
| Trust(内网) | inside | 100 | 10.1.10.0/24, 10.1.20.0/24, 10.1.30.0/24 |
| Untrust(公网) | outside | 0 | 203.0.113.0/24 |
| DMZ(服务器) | dmz | 50 | 10.1.99.0/24 |
ASA 默认行为: 高安全级别接口可以主动访问低安全级别接口(inside→outside、inside→dmz),低安全级别不能主动访问高安全级别(outside→inside 默认拒绝)。
2. 域间安全策略(ACL)
策略一:Trust → Untrust(允许所有内网上网)
在 ASA1 上创建 INSIDE_IN 扩展 ACL 放行所有 IP 流量,并应用到 inside 接口入方向,明确允许内网(Trust)主动访问公网(Untrust)。
bash
# 创建 ACL:允许内网所有流量到公网
ASA1(config)# access-list INSIDE_IN extended permit ip any any
# 应用到 inside 接口入方向
ASA1(config)# access-group INSIDE_IN in interface inside
命令解析
access-list INSIDE_IN extended permit ip any anyaccess-list: 创建/编辑访问控制列表的关键字,固定写法INSIDE_IN: ACL 名称,自主命名,但有强烈命名规范建议extended: 指定 ACL 类型为扩展 ACL,固定写法permit: 动作关键字,固定写法(二选一:permit/deny)ip: 匹配协议,自主命名,但有约束any: 源地址,自主命名,但有约束any: 目标地址,自主命名,但有约束
约束要求:
- ACL 名称(INSIDE_IN):建议使用 <区域>_<方向> 格式,便于管理,例如:
- INSIDE_IN = inside 接口入方向
- OUTSIDE_IN = outside 接口入方向
- DMZ_IN = dmz 接口入方向
- extended:ASA 默认使用扩展 ACL(可以匹配源目 IP、协议、端口),区别于标准 ACL(仅匹配源 IP)。在较新的 ASA 版本中此关键字有时可省略,但建议保留以明确意图
- 动作 permit / deny:二选一,permit 放行,deny 拒绝
- 协议 ip:可以是 ip(所有 IP 协议)、tcp、udp、icmp、esp 等具体协议
- 源/目的地址:格式可选:
- any = 任意地址
- host 10.1.1.1 = 单个主机
- 10.1.1.0 255.255.255.0 = 网段+掩码(注意 ASA 使用子网掩码,不是反掩码)
- ASA ACL 默认行为:末尾隐含 deny ip any any,所有未显式 permit 的流量都会被拒绝
- 本命令含义:允许 inside 接口入方向上的所有 IP 流量通过(permit ip any any)
access-group INSIDE_IN in interface insideaccess-group: 将 ACL 绑定到接口的关键字,固定写法INSIDE_IN: 要应用的 ACL 名称,自主命名,但必须与已创建的 ACL 名称完全一致in: 方向关键字,固定写法(二选一:in/out)interface: 指定接口的子关键字,固定写法inside: 接口逻辑名称(nameif),自主命名,但必须与设备上已配置的 nameif 匹配
约束要求:
- ACL 名称:必须与之前
access-list中定义的名称完全一致(区分大小写)- 方向 in / out:
in= 入方向(流量从该接口进入 ASA 时检查)out= 出方向(流量从该接口离开 ASA 时检查)- 最佳实践:通常在入方向(
in)应用 ACL,早期拒绝非法流量- 接口 inside:必须是设备上已通过
nameif配置的接口名称(inside / outside / dmz 等)- 一个接口一个方向只能绑定一个 ACL:同一接口的
in方向不能同时绑定两个 ACL,后续绑定会覆盖之前的配置- 若要查看已绑定的 ACL,使用
show running-config access-group- 若要移除 ACL,使用
no access-group INSIDE_IN in interface inside
策略二:Trust → DMZ(允许内网访问所有服务器)
在 ASA1 的 INSIDE_IN ACL 中追加一条放行内网 10.1.0.0/16 访问 DMZ 10.1.99.0/24 的规则,显式允许内网主动访问 DMZ 服务器。
bash
# 此流量由 inside→dmz(100→50),ASA 默认允许
# 如需显式控制,可添加 ACL
ASA1(config)# access-list INSIDE_IN extended permit ip 10.1.0.0 255.255.0.0 10.1.99.0 255.255.255.0
命令解析
access-list INSIDE_IN extended permit ip 10.1.0.0 255.255.0.0 10.1.99.0 255.255.255.0access-list: 创建/编辑访问控制列表的关键字,固定写法INSIDE_IN: ACL 名称,自主命名,但有强烈命名规范建议extended: 指定 ACL 类型为扩展 ACL(可匹配源 IP、目的 IP、协议、端口等),固定写法(多选项之一)permit: 动作:允许匹配此规则的流量通过,固定写法(多选项之一)ip: 协议类型:匹配所有 IP 协议(包含 TCP、UDP、ICMP 等所有基于 IP 的协议),固定写法(多选项之一)10.1.0.0: 源网络地址,自主命名255.255.0.0: 源网络掩码,自主命名10.1.99.0: 目的网络地址,自主命名255.255.255.0: 目的子网掩码,自主命名
约束要求:
- ACL 名称(INSIDE_IN):建议使用
<区域>_<方向>格式,便于管理,例如:
- INSIDE_IN = inside 接口入方向
- OUTSIDE_IN = outside 接口入方向
- DMZ_IN = dmz 接口入方向
- ACL 名称在同一设备上必须唯一,区分大小写(
INSIDE_IN与inside_in视为不同 ACL)extended:ASA 流量过滤场景必须使用扩展 ACL(可匹配源目 IP、协议、端口),区别于标准 ACL(仅匹配源 IP)- 动作 permit / deny:二选一,permit 放行,deny 拒绝;ACL 按配置顺序自上而下匹配,首次命中即生效,末尾隐含 deny ip any any
- 协议 ip:可以是 ip(所有 IP 协议)、tcp、udp、icmp、esp 等具体协议;使用 tcp/udp 后可追加端口参数
- 源/目的地址格式(ASA 使用子网掩码,不是反掩码):
any= 任意地址host 10.1.99.10= 单个主机10.1.99.0 255.255.255.0= 网段 + 子网掩码- 子网掩码必须是连续的 1 后跟连续的 0(如 255.255.255.0),不允许不连续格式(如 255.0.255.0)
- 本命令含义:允许从 10.1.0.0/16(内网所有子网)发往 10.1.99.0/24(DMZ 子网)的所有 IP 流量
- 注意:本命令仅定义 ACL 规则,不会自动生效,必须通过
access-group INSIDE_IN in interface inside绑定到接口方向后才开始过滤流量- 注意:绑定 ACL 到接口后,ACL 末尾隐含的 deny ip any any 会覆盖 ASA 默认的高安全级别→低安全级别放行行为,因此必须显式 permit 需要放行的流量
策略三:Untrust → DMZ(仅允许 80/443/53 端口)
在 ASA1 上创建 OUTSIDE_IN 扩展 ACL,仅放行外网访问 DMZ-WEB(10.1.99.10)的 80/443 和 DMZ-DNS(10.1.99.20)的 53(TCP+UDP),其余流量显式拒绝并记录日志,最后应用到 outside 接口入方向。
bash
# 创建 ACL:仅允许外网访问 DMZ 的 HTTP、HTTPS、DNS
ASA1(config)# access-list OUTSIDE_IN extended permit tcp any host 10.1.99.10 eq 80
ASA1(config)# access-list OUTSIDE_IN extended permit tcp any host 10.1.99.10 eq 443
ASA1(config)# access-list OUTSIDE_IN extended permit tcp any host 10.1.99.20 eq 53
ASA1(config)# access-list OUTSIDE_IN extended permit udp any host 10.1.99.20 eq 53
# 显式拒绝其他所有流量(ASA ACL 末尾隐式 deny,此处显式声明便于日志记录)
ASA1(config)# access-list OUTSIDE_IN extended deny ip any any log
# 应用到 outside 接口入方向
ASA1(config)# access-group OUTSIDE_IN in interface outside
关键说明:
host 10.1.99.10: 指定目标为 DMZ-WEB 服务器的真实内网 IPeq 80: 仅允许 HTTP 端口eq 443: 仅允许 HTTPS 端口eq 53: 仅允许 DNS 端口(TCP + UDP 均需放行)log: 对被拒绝的流量记录日志,便于安全审计- ERP 服务器(10.1.99.30)不在放行列表中,外网无法直接访问
命令解析
access-group OUTSIDE_IN in interface outsideaccess-group: 将已定义的 ACL 绑定到接口方向的关键字,固定写法OUTSIDE_IN: 要应用的 ACL 名称,自主命名,但必须与已创建的 ACL 名称完全一致(区分大小写)in: 流量检查方向,固定写法(二选一:in / out)interface: 指定接口的子关键字,固定写法outside: 接口逻辑名称(nameif),自主命名,但必须与设备上已配置的 nameif 匹配
约束要求:
- ACL 名称(OUTSIDE_IN):必须与之前
access-list OUTSIDE_IN ...中定义的名称完全一致(区分大小写),若 ACL 尚未创建或名称不符,则此命令不会报错,但绑定的是一个空 ACL,实际效果等同于 deny ip any any- 方向 in / out:
in= 入方向(流量从该接口进入 ASA 时检查,推荐在入方向应用,可以在流量进入系统早期拒绝非法流量)out= 出方向(流量从该接口离开 ASA 时检查,较少使用)- 接口 outside:必须是设备上已通过
nameif outside命令配置的接口逻辑名称,不是物理接口编号(如 GigabitEthernet0/0)- 查看设备上已配置的 nameif:
show nameif- 查看接口 IP/状态:
show interface ip brief- 一个接口一个方向只能绑定一个 ACL :同一接口的
in方向不能同时绑定两个 ACL,后续绑定会覆盖之前的配置(不会报错,请谨慎操作)- 不同接口可以绑定同一个 ACL:一个 ACL 可以被多个接口/方向引用共享
- 若要查看当前所有已绑定的 ACL:
show running-config access-group- 若要查看 ACL 命中情况(每条规则被匹配了多少次):
show access-list OUTSIDE_IN- 若要移除 ACL:
no access-group OUTSIDE_IN in interface outside- 生产环境操作警告:在未充分测试 ACL 规则完整性 之前,不要在业务接口绑定新 ACL,否则 ACL 末尾隐含的
deny ip any any可能瞬间阻断所有合法流量- ASA 安全级别默认行为提醒:绑定 ACL 后,ACL 规则覆盖默认行为------即使是 inside(高)→ outside(低)这类默认放行的流量,如果 ACL 中没有显式 permit,也会被 ACL 末尾的隐含 deny 拒绝
- 本命令含义:将名为 OUTSIDE_IN 的扩展 ACL 绑定到 outside 接口的入方向,即所有从外网进入 ASA 的流量都将按 OUTSIDE_IN 的规则进行检查
策略四:Untrust → Trust(默认拒绝所有)
在 ASA1 的 OUTSIDE_IN ACL 中显式追加一条拒绝外网到内网 10.1.0.0/16 的规则并记录日志,强化 Untrust → Trust 的默认拒绝行为。
bash
# ASA 默认行为:低安全级别(0)不能访问高安全级别(100)
# 无需额外配置,ASA 已隐式拒绝
# 如需显式声明(最佳实践):
ASA1(config)# access-list OUTSIDE_IN extended deny ip any 10.1.0.0 255.255.0.0 log
命令解析
access-list OUTSIDE_IN extended deny ip any 10.1.0.0 255.255.0.0 logaccess-list: 创建/编辑访问控制列表的关键字,固定写法OUTSIDE_IN: 要应用的 ACL 名称,自主命名,但必须与已创建的 ACL 名称完全一致(区分大小写)extended: 指定 ACL 类型为扩展 ACL(可匹配源 IP、目的 IP、协议、端口等),固定写法(多选项之一)deny: 动作:拒绝匹配此规则的流量,固定写法(多选项之一,另一选项为 permit)ip: 协议类型:匹配所有 IP 协议(包含 TCP、UDP、ICMP 等所有基于 IP 的协议),固定写法(多选项之一)any: 源地址关键字,固定写法10.1.0.0: 目的网络地址,自主命名255.255.0.0: 目的子网掩码,自主命名(ASA 使用子网掩码,不是反掩码)log: 日志关键字,固定写法(可选关键字,表示匹配时记录日志)
约束要求:
- ACL 名称(OUTSIDE_IN):必须与之前
access-list OUTSIDE_IN ...中定义的名称完全一致(区分大小写),同一名下可配置多条 ACE,按配置顺序自上而下匹配- extended:扩展 ACL,可匹配源 IP、目的 IP、协议、端口等
- 动作 deny:拒绝匹配此规则的流量,另一选项为 permit;ACL 按配置顺序自上而下匹配,首次命中即生效,后续 ACE 不再检查
- 协议 ip:匹配所有 IP 协议;如需细粒度控制可改为 tcp/udp/icmp 等具体协议
- 地址格式(ASA 使用子网掩码,不是反掩码):
any= 任意地址host 10.1.99.10= 单个主机10.1.0.0 255.255.0.0= 网段 + 子网掩码- 子网掩码必须是连续的 1 后跟连续的 0(如 255.255.0.0),不允许不连续格式
- log 关键字:可选,匹配时记录日志到 ASDM/系统日志,建议在 deny 规则后加
log以便排查被拒绝的流量,permit 规则根据需要决定是否记录(生产环境通常只记录 deny,避免 permit 日志过多)- 匹配逻辑:本命令向 OUTSIDE_IN ACL 追加一条规则,拒绝从任意源地址 (any)发往内网 10.1.0.0/16 的所有 IP 流量,并记录日志**
- deny 规则与 ACL 末尾隐含 deny 的关系:ACL 末尾默认隐含
deny ip any any,显式写 deny 规则的目的是①控制拒绝位置(在 permit 之前拒绝特定流量,使部分流量在后续 permit 不会被误放)、②记录日志(隐含 deny 默认不记录)、③便于阅读维护(明确哪些流量被拒绝)- 查看 ACL 规则顺序和命中次数:
show access-list OUTSIDE_IN(会显示每条规则的行号和 (hitcnt=x)
策略五:DMZ → Untrust(允许 DMZ 服务器上网更新)
在 ASA1 上创建 DMZ_IN 扩展 ACL 放行 DMZ 服务器网段 10.1.99.0/24 到任意目标的所有流量,并应用到 dmz 接口入方向,允许服务器访问公网。
bash
# 允许 DMZ 服务器访问公网(用于系统更新、DNS 查询等)
ASA1(config)# access-list DMZ_IN extended permit ip 10.1.99.0 255.255.255.0 any
# 应用到 dmz 接口入方向
ASA1(config)# access-group DMZ_IN in interface dmz
3. 安全策略汇总表
| 方向 | 安全级别 | 策略 | ACL 名称 |
|---|---|---|---|
| Trust → Untrust | 100 → 0 | 允许所有内网上网 | INSIDE_IN |
| Trust → DMZ | 100 → 50 | 允许内网访问所有服务器 | INSIDE_IN(已涵盖) |
| Untrust → DMZ | 0 → 50 | 仅允许 80/443/53 | OUTSIDE_IN |
| Untrust → Trust | 0 → 100 | 默认拒绝所有 | OUTSIDE_IN(隐式deny) |
| DMZ → Untrust | 50 → 0 | 允许 DMZ 上网 | DMZ_IN |
四、NAT 三类实操
1. 源 NAT(PAT):内网用户上网转换公网地址
在 ASA1 上为内网各 VLAN(10/20/30,或汇总为 10.1.0.0/16)创建网络对象,并配置从 inside 到 outside 的动态 PAT,使内网主机上网时共享防火墙 outside 接口的公网 IP 进行源地址转换。
bash
# 定义需要 NAT 转换的内网网段对象
ASA1(config)# object network INSIDE_NET_10
ASA1(config-network-object)# subnet 10.1.10.0 255.255.255.0
ASA1(config-network-object)# nat (inside,outside) dynamic interface
ASA1(config-network-object)# exit
ASA1(config)# object network INSIDE_NET_20
ASA1(config-network-object)# subnet 10.1.20.0 255.255.255.0
ASA1(config-network-object)# nat (inside,outside) dynamic interface
ASA1(config-network-object)# exit
ASA1(config)# object network INSIDE_NET_30
ASA1(config-network-object)# subnet 10.1.30.0 255.255.255.0
ASA1(config-network-object)# nat (inside,outside) dynamic interface
ASA1(config-network-object)# exit
# 或使用汇总网段一次性配置
ASA1(config)# object network INSIDE_NET_ALL
ASA1(config-network-object)# subnet 10.1.0.0 255.255.0.0
ASA1(config-network-object)# nat (inside,outside) dynamic interface
ASA1(config-network-object)# exit
效果:所有内网用户上网时,源 IP 被转换为防火墙 outside 接口的公网 IP
命令解析
object network INSIDE_NET_10object network: 创建网络对象(用于定义 IP/子网/主机,供 NAT、ACL 等功能引用)的关键字,固定写法INSIDE_NET_10: 对象名称,自主命名,但建议见名知意
约束要求:
- 对象名称(INSIDE_NET_10/20/30/ALL):同设备上必须唯一,建议使用
用途_地址含义_其他格式,不建议含空格和中文- 命名示例:INSIDE_NET_10、DMZ_WEB_SERVER、OUTSIDE_PUBLIC_IP
- 区分大小写:
INSIDE_NET_10与inside_net_10视为不同对象
subnet 10.1.10.0 255.255.255.0subnet: 在网络对象内定义子网 (网段)的关键字,固定写法(同类选项还有host、range)10.1.10.0: 子网网络地址,自主命名255.255.255.0: 子网掩码,自主命名(ASA 使用子网掩码,不是反掩码)
约束要求:
subnet、host、range三选一互斥:一个对象只能用一种方式定义
subnet 10.1.10.0 255.255.255.0= 匹配一个网段(10.1.10.0/24)host 10.1.99.10= 匹配单个主机range 10.1.10.100 10.1.10.200= 匹配一个 IP 范围- 子网掩码必须是连续的 1 后跟连续的 0(如 255.255.255.0),不允许不连续格式
- 子网地址必须对齐:网络位后主机位必须全 0(如
10.1.10.0 255.255.255.0正确,10.1.10.5 255.255.255.0不推荐)
nat (inside,outside) dynamic interfacenat: 配置 NAT 规则的关键字,固定写法(inside,outside): NAT 的接口对,固定写法格式,括号内两个接口名用英文逗号分隔:(源接口, 目的接口)inside: 数据包的源接口(真实接口的 nameif),自主命名但必须匹配设备上已配置的 nameifoutside: 数据包的目的接口(真实接口的 nameif),自主命名但必须匹配设备上已配置的 nameifdynamic: NAT 类型为动态 NAT (PAT/NAPT,多对一/多对多映射,连接级别分配),固定写法(同类选项还有static、dynamic pat-pool等)interface: NAT 转换后使用出接口自身的 IP 地址作为转换后的源地址(即 PAT 到接口 IP),固定写法(同类选项还有具体 IP、IP 范围、pat-pool 名称等)
约束要求:
- NAT 接口对
(inside,outside)含义:数据包从 inside 进入,从 outside 出去时对其源 IP 进行转换- 接口名必须是设备上已通过
nameif配置的逻辑名称,不是物理接口编号(如 GigabitEthernet0/0)- 括号和逗号为固定语法,常见组合:
(inside,outside)、(dmz,outside)、(inside,dmz)dynamic interface是最常用的内网上网 PAT 方式:多个内网主机共享 outside 接口的公网 IP,通过不同源端口区分不同会话- 动态 NAT 的其他形式:
nat (inside,outside) dynamic 203.0.113.100= 转换到指定公网 IPnat (inside,outside) dynamic pat-pool MY_POOL= 转换到地址池nat (inside,outside) static 203.0.113.10= 静态一对一映射(用于服务器对外提供服务)- 汇总写法(INSIDE_NET_ALL):当多个网段使用相同 NAT 策略时,可汇总为
10.1.0.0 255.255.0.0减少重复;但拆分写法(INSIDE_NET_10/20/30)便于未来对特定网段单独调整- 查看已创建的网络对象:
show running-config object network- 查看 NAT 转换表:
show xlate(当前活跃的 NAT 会话映射)- 本命令完整含义:创建网络对象并配置 NAT 规则------凡从 inside 去往 outside 的该子网流量,将其源 IP 动态转换为 outside 接口自身的 IP 地址(PAT),实现内网共享公网 IP 上网
2. 目的 NAT(端口映射):外网访问 DMZ-WEB 服务器
在 ASA1 上为 DMZ-WEB(10.1.99.10)的 80/443 端口和 DMZ-DNS(10.1.99.20)的 53 端口(TCP+UDP)分别创建网络对象,配置从 dmz 到 outside 的静态端口映射到公网 IP 203.0.113.10,使外网可访问 DMZ 的指定服务。
bash
# ---- HTTP 端口映射 (80) ----
ASA1(config)# object network DMZ_WEB_HTTP
ASA1(config-network-object)# host 10.1.99.10
ASA1(config-network-object)# nat (dmz,outside) static 203.0.113.10 service tcp 80 80
ASA1(config-network-object)# exit
# ---- HTTPS 端口映射 (443) ----
ASA1(config)# object network DMZ_WEB_HTTPS
ASA1(config-network-object)# host 10.1.99.10
ASA1(config-network-object)# nat (dmz,outside) static 203.0.113.10 service tcp 443 443
ASA1(config-network-object)# exit
# ---- DNS 端口映射 (53) ----
ASA1(config)# object network DMZ_DNS_TCP
ASA1(config-network-object)# host 10.1.99.20
ASA1(config-network-object)# nat (dmz,outside) static 203.0.113.10 service tcp 53 53
ASA1(config-network-object)# exit
ASA1(config)# object network DMZ_DNS_UDP
ASA1(config-network-object)# host 10.1.99.20
ASA1(config-network-object)# nat (dmz,outside) static 203.0.113.10 service udp 53 53
ASA1(config-network-object)# exit
效果:外网用户访问 203.0.113.10:80,流量被转换到 10.1.99.10:80
命令解析
object network DMZ_WEB_HTTPobject network: 创建网络对象的关键字,固定写法DMZ_WEB_HTTP: 对象名称,自主命名
约束要求:
- 对象名称在同设备上必须唯一,建议见名知意,不建议含空格和中文
- 命名示例:DMZ_WEB_HTTP、DMZ_DNS_TCP、DMZ_ERP
host 10.1.99.10host: 在网络对象内定义单个主机 (而非子网/范围)的关键字,固定写法(同类选项:subnet、range)10.1.99.10: 主机的真实内网 IP 地址,自主命名
约束要求:
host/subnet/range三选一互斥:一个对象只能用一种方式host <IP>= 匹配单个主机,适用于端口映射(一个服务器的某端口)场景subnet 10.1.10.0 255.255.255.0= 匹配网段,适用于源 NAT/PAT 上网场景range 10.1.10.100 10.1.10.200= 匹配 IP 范围,适用于地址池
nat (dmz,outside) static 203.0.113.10 service tcp 80 80nat: 配置 NAT 规则的关键字,固定写法(dmz,outside): NAT 接口对,固定写法格式,(源接口, 目的接口)dmz: 数据包的源接口 nameif,自主命名但必须匹配已配置 nameifoutside: 数据包的目的接口 nameif,自主命名但必须匹配已配置 nameifstatic: NAT 类型为静态 NAT (固定一对一映射,不随连接变化),固定写法(同类选项:dynamic)203.0.113.10: 转换后的公网 IP 地址(映射到外网的地址),自主命名service: 端口 NAT(PAT 端口映射)子关键字,固定写法(可选:不写service则为全端口静态 NAT)tcp: 指定协议为 TCP,固定写法(同类选项:udp、icmp)80: 真实端口(内部服务的端口),自主命名80: 映射端口(对外暴露的端口),自主命名
约束要求:
- 接口对
(dmz,outside)含义:流量从 dmz 进入 ASA,从 outside 出去时,对其源 IP 进行映射;反向(外部→内部)流量目的 IP 为 203.0.113.10 时被转换到内部主机static代表静态映射:内部 IP ↔ 公网 IP 关系固定,不受连接数影响,用于服务器对外提供服务(区别于dynamic用于内网用户上网的动态分配)- 公网 IP(203.0.113.10):必须是运营商分配的可用公网 IP,且与 outside 接口同网段;不同服务器可以共享同一个公网 IP 通过端口区分(多个 service 映射到同一公网 IP)
service tcp 80 80含义:
- 格式:
service <协议> <真实端口> <映射端口>- 真实端口 = 服务器实际监听的端口
- 映射端口 = 对外暴露的公网端口
- 两者相同即为透明端口映射(80→80);不同即为端口重定向(如 8080→80)
- 端口值范围:1--65535;知名端口 1--1023:HTTP=80, HTTPS=443, SSH=22, DNS=53, SMTP=25, FTP=21
- TCP 与 UDP 独立:DNS 需要同时配置
service tcp 53 53(区域传输)和service udp 53 53(查询响应),两条命令分别独立- 同类命令(HTTP 80 / HTTPS 443 / DNS TCP 53 / DNS UDP 53)结构完全相同,仅对象名、内部主机 IP、协议和端口不同;均实现外网 → 公网 IP:端口 → 内部服务器真实 IP:端口 的目的 NAT(端口映射)
- 配套要求:端口映射后,还需在
OUTSIDE_INACL 中显式 permit 外部访问该公网 IP 的对应端口,否则流量会被 ACL 末尾隐含 deny 拒绝- 查看 NAT 转换表:
show xlate(可以看到端口映射条目,如TCP from dmz:10.1.99.10/80 to outside:203.0.113.10/80)- 对比一对一全端口 NAT:
nat (dmz,outside) static 203.0.113.11(不写 service 部分)表示映射所有端口,适用于 ERP 等需要多个端口暴露的场景;带service仅映射特定端口,安全性更高
3. 一对一 NAT:ERP 服务器固定公网 IP
在 ASA1 上为 DMZ-ERP(10.1.99.30)创建网络对象,并配置从 dmz 到 outside 的全端口一对一静态 NAT 到公网 IP 203.0.113.11。
bash
# ERP 服务器一对一 NAT
ASA1(config)# object network DMZ_ERP
ASA1(config-network-object)# host 10.1.99.30
ASA1(config-network-object)# nat (dmz,outside) static 203.0.113.11
ASA1(config-network-object)# exit
命令详解:
nat (dmz,outside) static 203.0.113.11:- 不指定 service 端口 = 全端口一对一映射
- 10.1.99.30 ↔ 203.0.113.11 所有端口双向映射
效果:ERP 服务器拥有固定公网 IP 203.0.113.11,内外网均可通过该 IP 访问
4. NAT 配置汇总
| NAT 类型 | 内部地址 | 公网地址 | 端口 | 用途 |
|---|---|---|---|---|
| 源 NAT(PAT) | 10.1.0.0/16 | 203.0.113.1 (接口 IP) | 所有 | 内网用户上网 |
| 目的 NAT | 10.1.99.10 | 203.0.113.10 | TCP 80 | 外网访问 WEB(HTTP) |
| 目的 NAT | 10.1.99.10 | 203.0.113.10 | TCP 443 | 外网访问 WEB(HTTPS) |
| 目的 NAT | 10.1.99.20 | 203.0.113.10 | TCP/UDP 53 | 外网访问 DNS |
| 一对一 NAT | 10.1.99.30 | 203.0.113.11 | 所有 | ERP 固定公网 IP |
五、防火墙路由配置
1. ASA 默认路由(指向公网 ISP)
在 ASA1 上配置指向 ISP-Router(203.0.113.253)的默认路由,使所有未知目标的流量从 outside 接口转发至公网。
ASA1 和 ASA2 配置(Failover 会自动同步)
bash
ASA1(config)# route outside 0.0.0.0 0.0.0.0 203.0.113.253
命令解析
route outside 0.0.0.0 0.0.0.0 203.0.113.253route: 配置静态路由(指定数据包转发路径)的关键字,固定写法outside: 出接口的 nameif 逻辑名称,自主命名但必须匹配设备上已配置的 nameif0.0.0.0: 目标网络地址,固定写法(全零表示匹配任意网络,即默认路由)0.0.0.0: 目标网络掩码,固定写法(全零表示匹配任意网络,与上一个 0.0.0.0 组合为默认路由)203.0.113.253: 下一跳 IP 地址(网关),自主命名,但必须是出接口直连可达的 IP
约束要求:
- 出接口(outside/inside 等):必须是设备上已通过
nameif配置的逻辑接口名称 ,不是物理接口编号(如 GigabitEthernet0/0);查看已配置 nameif:show nameif- 目标网络 + 掩码:
0.0.0.0 0.0.0.0组合为默认路由 (default route),表示匹配所有未知目标网络,所有未能在路由表中找到更精确匹配的流量都走这条路由;如需匹配特定子网写为:10.1.10.0 255.255.255.0(即 10.1.10.0/24)- 子网掩码必须是连续的 1 后跟连续的 0,不允许不连续格式
- 下一跳 IP(203.0.113.253 / 10.1.50.253):必须是出接口直连网段内的可达 IP,即该 IP 必须与 ASA 对应接口 IP 在同一子网内,ASA 可以直接 ARP 到下一跳;不能是跨多跳的远程 IP
- 一条路由表中同一目标网络只能有一条主路由;如需要冗余,需配置不同的下一跳但相同目标网络是不允许的(ASA 不支持等成本负载均衡的静态路由)
- 查看路由表:
show route或show running-config route- 本命令含义:配置一条默认路由,所有去往未知目标网络的流量都从 outside 接口转发至下一跳 203.0.113.253(ISP 路由器)
2. ASA 内网路由(指向核心交换机)
在 ASA1 上添加多条指向核心交换机 VRRP VIP(10.1.50.253)的 inside 静态路由,确保内网各 VLAN(10.1.10/20/30/100)及老旧厂区(10.2.0.0/24)的回程流量正确转发。
bash
# 将总部内网网段指向核心侧(通过 inside 接口)
ASA1(config)# route inside 10.1.10.0 255.255.255.0 10.1.50.253
ASA1(config)# route inside 10.1.20.0 255.255.255.0 10.1.50.253
ASA1(config)# route inside 10.1.30.0 255.255.255.0 10.1.50.253
ASA1(config)# route inside 10.1.100.0 255.255.255.0 10.1.50.253
# 老旧厂区路由(通过核心转发)
ASA1(config)# route inside 10.2.0.0 255.255.255.0 10.1.50.253
下一跳 10.1.50.253 为核心交换机 VLAN 50 的 VRRP VIP。
命令解析
route inside 10.1.10.0 255.255.255.0 10.1.50.253route: 配置静态路由的关键字,固定写法inside: 出接口的 nameif 逻辑名称,自主命名但必须匹配设备上已配置的 nameif10.1.10.0: 目标网络地址,自主命名255.255.255.0: 目标网络子网掩码,自主命名(ASA 使用子网掩码,不是反掩码)10.1.50.253: 下一跳 IP 地址,自主命名,但必须是出接口直连可达的 IP
约束要求:
- 命令格式固定为:
route <出接口nameif> <目标网络> <子网掩码> <下一跳IP>,四个参数全部为必需- 出接口(inside):流量通过 inside 接口转发,下一跳为核心交换机侧
- 目标网络(10.1.10.0/24):具体的内网子网地址,代表总部用户网段
- 子网掩码(255.255.255.0):/24 掩码,与目标网络严格对齐
- 下一跳(10.1.50.253):核心交换机 VLAN 50 的 VRRP 虚拟网关 IP,必须是 inside 接口直连可达
- 本命令含义:将去往 10.1.10.0/24 内网子网的流量通过 inside 接口转发至核心交换机 VRRP 网关 10.1.50.253,使防火墙知道如何到达内网各 VLAN 回程流量
- 同类命令(10.1.20.0 / 10.1.30.0 / 10.1.100.0 / 10.2.0.0):结构完全相同,仅目标网络不同,分别对应不同内网子网,下一跳统一指向核心 VRRP VIP,实现内网各区域的回程路由
- 汇总优化建议:如内网子网可合并,可简化为
route inside 10.1.0.0 255.255.0.0 10.1.50.253一条命令代替 10/20/30/100 四条,但保持拆分写法便于未来独立维护(如某子网迁移需单独调整路由)- 生产环境注意:修改默认路由和内网路由后需验证:
ping <目标IP>或traceroute <目标IP>确认路径正确- 与路由器静态路由区别:ASA 的
route命令中第一个参数是出接口 nameif ,而 Cisco IOS 路由器的ip route第一个参数是目标网络,语法顺序不同
3. 允许 ICMP(便于排错验证)
在 ASA1 上配置允许各安全域(inside/outside/dmz)入向 ICMP,并在全局策略的 inspection_default 中启用 ICMP 检测,使防火墙自身可响应 ping,便于排错验证。
bash
# 允许 ICMP 用于 ping 测试(实验室环境建议开启)
ASA1(config)# icmp permit any inside
ASA1(config)# icmp permit any outside
ASA1(config)# icmp permit any dmz
# 允许防火墙自身响应 ping
# 进入全局策略地图
ASA1(config)# policy-map global_policy
# 进入默认的检测类
ASA1(config-pmap)# class inspection_default
# 在这里开启 ICMP 检测
ASA1(config-pmap-c)# inspect icmp
ASA1(config-pmap-c)# exit
ASA1(config-pmap)# exit
命令解析
icmp permit any insideicmp: 配置 ICMP 协议(ping/echo 等)流量访问控制的关键字,固定写法permit: 动作:允许 ICMP 流量,固定写法(另一选项为deny)any: 源地址关键字,固定写法inside: 目标接口的 nameif 逻辑名称,自主命名但必须匹配设备上已配置的 nameif
约束要求:
icmp permit/deny控制的是目的地址为 ASA 自身接口 IP 的 ICMP 流量(即外部设备 ping 防火墙本身),与穿通防火墙的 ICMP 流量不同,后者由 ACL 控制- 源地址格式:
any= 任意地址;也可写为host 10.1.50.253(特定主机)或10.1.0.0 255.255.0.0(特定网段,ASA 使用子网掩码)- 目标接口(inside/outside/dmz):必须是已配置的 nameif,代表 ICMP 流量的入向接口(即从哪个接口进入 ASA 的 ping 响应)
- 同类命令(inside/outside/dmz 三条)结构完全相同,仅目标接口不同:分别允许从 inside、outside、dmz 三个接口进入的 ICMP 流量到达 ASA 自身,使防火墙能响应各方向的 ping
- 本命令含义:允许从 inside 接口进入的 ICMP 流量到达 ASA 自身 IP,即内网设备可以 ping 通防火墙 inside 接口
- 反向意义:如不配置此命令,即使路由可达,设备 ping 防火墙自身 IP 也会被 ASA 默认拒绝,防火墙不响应
- 与 ACL 的区别:
icmp permit是针对 ASA 自身的 ICMP 控制命令,独立于 ACL,不通过 access-group 绑定- 生产环境建议:
icmp permit通常建议限制源地址(如只允许管理网段 ping),避免any暴露防火墙位置
policy-map global_policypolicy-map: 创建或进入策略地图(policy map,用于绑定检测规则和流量类)的关键字,固定写法global_policy: 策略地图名称,自主命名,global_policy是 ASA 默认存在的全局策略地图名称(系统预定义)
约束要求:
global_policy是 ASA 默认全局策略地图,默认已通过service-policy global_policy global绑定到全局(所有接口)- 也可创建自定义策略地图名称,但需要配合
class-map和service-policy使用- 进入策略地图后提示符变为
ASA1(config-pmap)#- 查看策略地图配置:
show running-config policy-map
class inspection_defaultclass: 在策略地图内引用已有流量类(class-map)的子关键字,固定写法inspection_default: 流量类的名称,自主命名,inspection_default是 ASA 系统预定义的默认检测类(包含所有常见协议)
约束要求:
inspection_default是 ASA 预定义类,默认包含了match default-inspection-traffic(匹配所有常见应用层协议,如 HTTP/FTP/ICMP/SSH 等)- 也可自定义 class-map 名称匹配特定流量
- 进入类配置后提示符变为
ASA1(config-pmap-c)#- 查看 class map 配置:
show running-config class-map
inspect icmpinspect: 在策略地图的类内启用协议检测(Protocol Inspection)的关键字,固定写法icmp: 要启用检测的具体协议名称,固定写法(同类选项:http、ftp、dns、smtp、ssh、esmtp、rtsp等数十种)
约束要求:
inspect icmp对 ICMP 协议启用有状态检测:
- 检测 echo request/reply 的对应关系(有状态放行回程,类似 TCP 的 SYN/ACK 对应)
- 识别 ICMP 错误消息并与相关 TCP/UDP 会话关联(如 port-unreachable 与已建立会话关联放行)
- 未启用 inspect icmp 时,即使 ACL permit icmp,回程响应可能被 ASA 状态机制丢弃
- 协议检测(inspect)与 ACL 的关系:ACL 控制是否允许流量通过,inspect 控制 ASA 是否对该协议做应用层深度检测和状态维护,两者配合使用
- 可启用的常见协议:
inspect http、inspect ftp、inspect dns、inspect esmtp、inspect ssh、inspect h323、inspect sip、inspect icmp error等- ASA 默认部分协议已开启 inspect,查看默认状态:
show running-config policy-map global_policy- 本命令含义:在默认全局策略的默认检测类中启用 ICMP 协议的应用层检测,使 ASA 能正确维护 ICMP 会话状态,实现双向 ping 正常工作
- 查看全局策略绑定:
show running-config service-policy- 查看协议检测状态:
show service-policy inspect icmp
六、配置同步确认
Failover 启用后,ASA1(Active)的配置会自动同步到 ASA2(Standby)。
bash
# 验证配置同步状态
ASA1# show failover
⚠️ 重要: 所有后续配置(ACL、NAT、路由)只需在 ASA1(Active)上配置,会自动同步到 ASA2。
七、验证
验证 1:Failover 基线状态
bash
# 在 ASA1 上查看 HA 状态
ASA1# show failover
验证 2:安全策略验证
测试 A:内网 → 公网(Trust → Untrust)
bash
# PC1 (VLAN10, 10.1.10.1) ping 公网地址
VPC1> ping 203.0.113.253
# 预期:ping 通(源 NAT 转换后以防火墙公网 IP 出网)
# 在 ASA1 上查看 NAT 转换表
ASA1# show xlate
# 预期:看到 10.1.10.1 被转换为 203.0.113.x 的 PAT 条目
测试 B:内网 → DMZ(Trust → DMZ)
bash
# PC1 ping DMZ-WEB 服务器
VPC1> ping 10.1.99.10
# 预期:ping 通(inside 安全级别 100 > dmz 安全级别 50,默认允许)
测试 C:公网 → DMZ(Untrust → DMZ)
💡 说明 :由于普通 Cisco IOS 路由器不支持
curl命令,我们使用 ASA 防火墙内置的强大排错工具packet-tracer来模拟外网数据包进入防火墙的全过程。
bash
# 使用 packet-tracer 模拟外网 ISP (203.0.113.254) 访问 DMZ-WEB 的 HTTP 端口
# 格式:packet-tracer input <入接口> <协议> <源IP> <源端口> <目的IP> <目的端口>
ASA1# packet-tracer input outside tcp 203.0.113.254 12345 203.0.113.10 80
plaintext
# --- 预期输出(关键阶段摘录) ---
Phase: 2
Type: UN-NAT
Subtype: static
Result: ALLOW
Config:
object network DMZ_WEB_HTTP
nat (dmz,outside) static 203.0.113.10 service tcp www www
Additional Information:
NAT divert to egress interface dmz
Untranslate 203.0.113.10/80 to 10.1.99.10/80 <-- 【关键点1:目的NAT成功将公网IP转换为私网IP】
Phase: 3
Type: ACCESS-LIST
Subtype: log
Result: ALLOW
Config:
access-group OUTSIDE_IN in interface outside
access-list OUTSIDE_IN extended permit tcp any host 10.1.99.10 eq www <-- 【关键点2:外部ACL成功放行HTTP流量】
Phase: 12
Type: FLOW-CREATION
Result: ALLOW
Additional Information:
New flow created with id 297, packet dispatched to next module
Result:
input-interface: outside
output-interface: dmz
Action: allow <-- 【最终结果:允许通过】
bash
# 验证 NAT 端口映射表:
ASA1# show xlate | include 203.0.113.10
# 预期输出:
TCP PAT from dmz:10.1.99.10 80-80 to outside:203.0.113.10 80-80
TCP PAT from dmz:10.1.99.10 443-443 to outside:203.0.113.10 443-443
TCP PAT from dmz:10.1.99.20 53-53 to outside:203.0.113.10 53-53
UDP PAT from dmz:10.1.99.20 53-53 to outside:203.0.113.10 53-53
测试 D:公网 → Trust(Untrust → Trust)
bash
# 从公网尝试访问内网
ISP-Router# ping 10.1.10.1
# 预期:0% 成功率(超时)。
# 结论:证明 Untrust 区域无法主动发起对 Trust 区域的访问,安全隔离生效。
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.10.1, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
bash
# --- 进阶验证:查看防火墙 Deny 日志 ---
# 当 ISP-Router ping 10.1.10.1 失败时,ASA 防火墙会生成 syslog 日志。
# 我们可以直接在 ASA 上查看这些被拒绝的记录。
# 1. 开启 ASA 日志缓冲区(如之前未配置)
ASA1(config)# logging enable
ASA1(config)# logging buffered informational
# 2. 减小日志记录间隔(默认 300 秒,改为 1 秒便于测试观察)
ASA1(config)# access-list OUTSIDE_IN extended deny ip any any log informational interval 1
# 3. 从外部路由器发起被拒绝的流量
ISP-Router# ping 10.1.10.1
# 预期结果:Success rate is 0 percent (0/5)
# 4. 回到 ASA 查看 ACL 拒绝日志(推荐使用 ACL 名称或关键字过滤,无需记忆 Syslog ID)
ASA1# show logging | include OUTSIDE_IN
# 或者使用更通用的 "denied" 关键字:
ASA1# show logging | include denied
# 预期输出示例(不同 ASA 版本的 Syslog ID 可能不同,但关键字一致):
# %ASA-6-106100: access-list OUTSIDE_IN denied icmp outside/203.0.113.253(8)
# -> inside/10.1.10.1(0) hit-cnt 1 first hit [0x2dc51227, 0x00000000]
#
# 日志解读:
# - access-list OUTSIDE_IN denied icmp → 被 OUTSIDE_IN 规则拒绝的 ICMP 流量
# - outside/203.0.113.253(8) → 源地址(ICMP type 8 = Echo Request)
# - inside/10.1.10.1(0) → 目标地址
# - hit-cnt 1 → 本次会话中该规则的命中次数
# 5.(可选)清除日志缓冲区以便下次观察
ASA1# clear logging buffer
# 6. 验证完成后恢复默认日志间隔
ASA1(config)# access-list OUTSIDE_IN extended deny ip any any log informational interval 300
验证 3:NAT 功能验证
源 NAT(PAT)验证
bash
# --- 验证:内部网络 (Inside) 访问外部网络 (Outside) ---
# 目标:验证内部主机能否正常访问互联网,且 NAT (PAT) 转换是否生效。
# 1. 从内部主机发起 Ping 测试
VPC1> ping 203.0.113.253
# 预期结果:Ping 成功 (Success rate is 100 percent)
# 2. 在 ASA 上查看实时的 NAT 转换表 (数据面)
ASA1# show xlate
# 预期输出示例:
# ICMP PAT from inside:10.1.10.1/24777 to outside:203.0.113.1/24777 flags ri idle 0:00:02 timeout 0:00:30
#
# 日志解读:
# - 内部主机的 ICMP 流量被成功转换为外部接口 IP (203.0.113.1)。
# - flags ri 表示这是一个动态的端口地址转换 (PAT)。
# 3. 在 ASA 上查看 NAT 策略的命中计数 (控制面)
ASA1# show nat
# 预期输出示例:
# (inside) to (outside) source dynamic INSIDE_NET_10 interface
# translate_hits = 10, untranslate_hits = 0
#
# 日志解读:
# - 证明流量正确匹配了内部到外部的 Dynamic NAT/PAT 规则。
# - translate_hits 命中次数增加(例如 ping 5个包,一来一回计为 10 次命中)。
目的 NAT(端口映射)验证
bash
# 从公网访问 203.0.113.10:80
# 在 ASA1 上查看 NAT 转换
ASA1# show xlate | include 203.0.113.10
# 预期:看到 203.0.113.10:80 → 10.1.99.10:80 的静态映射
# 查看详细的 NAT 规则命中计数
ASA1# show nat detail
一对一 NAT 验证
bash
# 在 ASA1 上查看 ERP 的 NAT 映射状态
ASA1# show xlate | include 203.0.113.11
# 预期:看到 10.1.99.30 ↔ 203.0.113.11 的全端口映射
NAT from dmz:10.1.99.30 to outside:203.0.113.11
# 从公网模拟访问 ERP (验证安全策略拦截)
# 从外网 ISP-Router 尝试访问 ERP 的 8080 端口
ISP-Router# telnet 203.0.113.11 8080
Trying 203.0.113.11, 8080 ...
% Connection timed out; remote host not responding
# 在 ASA1 上模拟外网 (203.0.113.254) 访问 ERP (203.0.113.11:8080)
ASA1# packet-tracer input outside tcp 203.0.113.254 12345 203.0.113.11 8080
验证 4:防火墙主备切换测试(核心测试!)
bash
# ===== 1.开启持续 Ping =====
VPC1> ping 203.0.113.253 -t # 内网 PC 持续 ping 公网
# ===== 2.模拟 ASA1 故障 =====
# 在拓补图中 Delete 掉 ASA1 的 g0/0 和 Core1 的 g1/2 的连接
# ===== 3.在 ASA2 上观察切换 =====
ASA2# show failover
# 预期:
# This host: Secondary - Active ← ASA2 接管为 Active
# Other host: Primary - Failed ← ASA1 标记为故障
# ===== 4.观察 Ping 结果 =====
# PC1 的 ping 仅丢 1~3 个包后自动恢复(ASA2 接管,IP 迁移)
# ===== 5.恢复 ASA1 =====
# 在拓补图中重新恢复 ASA1 的 g0/0 和 Core1 的 g1/2 的连接
# ===== 6.等待 30 秒,观察自动回切 =====
ASA1# show failover
# ASA1 恢复为 Active(Primary 默认不抢占)
ASA1# failover active
# ===== 7.再次观察 Ping =====
# PC1 的 ping 再次短暂丢包后恢复(ASA1 重新接管)
验证 5:端到端业务验证
bash
# 1. 内网所有 VLAN 上网
VPC1> ping 203.0.113.253 # VLAN10 ✅
VPC2> ping 203.0.113.253 # VLAN20 ✅
VPC3> ping 203.0.113.253 # VLAN30 ✅
# 2. 内网访问 DMZ
VPC1> ping 10.1.99.10 # 访问 WEB 服务器 ✅
VPC1> ping 10.1.99.20 # 访问 DNS 服务器 ✅
VPC1> ping 10.1.99.30 # 访问 ERP 服务器 ✅
# 3. 外网访问 DMZ(仅允许端口)
# DMZ-WEB上监控 80 端口
root@slax:~# nc -l -p 80
# 访问DMZ-WEB服务器 80 端口
ISP-Router> telnet 203.0.113.10 80 # HTTP ✅
# 结束后按 ctrl + shift + ^,然后松手按 x 键
# 同上
ISP-Router> telnet 203.0.113.10 443 # HTTPS ✅
ISP-Router> telnet 203.0.113.10 22 # SSH ❌(未放行)
# 未放行 SSH 端口,尝试连接会超时失败
# Trying 203.0.113.10, 22 ...
# % Connection timed out; remote host not responding
# 4. 外网无法访问内网
ISP-Router> ping 10.1.10.1 # ❌ 拒绝
# 5. 老旧厂区可达(模块03功能保持)
VPC1> ping 10.2.0.254 # 访问 AR-Old ✅
八、常见排错命令
bash
# 查看接口状态与 IP
ASA1# show interface ip brief
# 查看 NAT 转换表
ASA1# show xlate
ASA1# show xlate detail
# 查看连接表(实时流量)
ASA1# show conn
ASA1# show conn detail
# 查看 ACL 命中计数
ASA1# show access-list
# 查看路由表
ASA1# show route
# 查看 Failover 详细日志
ASA1# show failover history
# 清除 NAT 转换表(排错时重置)
ASA1# clear xlate all
# 实时抓包(调试用)
ASA1# capture OUTSIDE_CAP interface outside match ip any any
ASA1# show capture OUTSIDE_CAP
整体架构图

相关知识
HA 集群
HA 集群 = High Availability Cluster 高可用集群
是由两台或多台设备通过心跳和状态同步组成的冗余系统,目标是「当任何一台设备故障时,其余设备自动接管业务,实现接近零停机的业务连续性」。
核心目标 :当任一节点发生硬件 / 软件 / 网络故障时,其余节点自动接管业务,实现接近零停机的业务连续性 。
关键衡量指标
| 指标 | 含义 | 典型值 |
|---|---|---|
| 可用性 | 系统正常服务时间占比 | 99.9% / 99.99% / 99.999% |
| RTO | 恢复时间目标(故障到恢复的时长) | 秒级~分钟级 |
| RPO | 恢复点目标(数据丢失容忍度) | 0(双活)~ 秒级 |
| MTBF | 平均无故障时间 | 越长越好 |
| MTTR | 平均修复时间 | 越短越好 |
5 个 9(99.999%) = 年停机时间 ≤ 5.26 分钟
核心工作机制
三大基础能力:心跳检测 Heartbeat 、状态同步 Sync 、故障自动转移 Failover
心跳检测 Heartbeat
节点间周期性发送"存活信号",用于感知对方状态:
- 发送方式:专用串口线/以太网/共享磁盘
- 超时判定:连续丢失 N 次心跳信号,判定对端故障
- 脑裂风险 :心跳链路中断但节点都存活➡️双主冲突➡️需要仲裁机制
状态同步 Sync
保证主备节点数据/配置一致
故障转移 Failover
故障发生时的自动接管流程:
#mermaid-svg-5uYbnLfGQ5JVmrsp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5uYbnLfGQ5JVmrsp .error-icon{fill:#552222;}#mermaid-svg-5uYbnLfGQ5JVmrsp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5uYbnLfGQ5JVmrsp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .marker.cross{stroke:#333333;}#mermaid-svg-5uYbnLfGQ5JVmrsp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5uYbnLfGQ5JVmrsp p{margin:0;}#mermaid-svg-5uYbnLfGQ5JVmrsp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .cluster-label text{fill:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .cluster-label span{color:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .cluster-label span p{background-color:transparent;}#mermaid-svg-5uYbnLfGQ5JVmrsp .label text,#mermaid-svg-5uYbnLfGQ5JVmrsp span{fill:#333;color:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .node rect,#mermaid-svg-5uYbnLfGQ5JVmrsp .node circle,#mermaid-svg-5uYbnLfGQ5JVmrsp .node ellipse,#mermaid-svg-5uYbnLfGQ5JVmrsp .node polygon,#mermaid-svg-5uYbnLfGQ5JVmrsp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .rough-node .label text,#mermaid-svg-5uYbnLfGQ5JVmrsp .node .label text,#mermaid-svg-5uYbnLfGQ5JVmrsp .image-shape .label,#mermaid-svg-5uYbnLfGQ5JVmrsp .icon-shape .label{text-anchor:middle;}#mermaid-svg-5uYbnLfGQ5JVmrsp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .rough-node .label,#mermaid-svg-5uYbnLfGQ5JVmrsp .node .label,#mermaid-svg-5uYbnLfGQ5JVmrsp .image-shape .label,#mermaid-svg-5uYbnLfGQ5JVmrsp .icon-shape .label{text-align:center;}#mermaid-svg-5uYbnLfGQ5JVmrsp .node.clickable{cursor:pointer;}#mermaid-svg-5uYbnLfGQ5JVmrsp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .arrowheadPath{fill:#333333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uYbnLfGQ5JVmrsp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5uYbnLfGQ5JVmrsp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uYbnLfGQ5JVmrsp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5uYbnLfGQ5JVmrsp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .cluster text{fill:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp .cluster span{color:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5uYbnLfGQ5JVmrsp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5uYbnLfGQ5JVmrsp rect.text{fill:none;stroke-width:0;}#mermaid-svg-5uYbnLfGQ5JVmrsp .icon-shape,#mermaid-svg-5uYbnLfGQ5JVmrsp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uYbnLfGQ5JVmrsp .icon-shape p,#mermaid-svg-5uYbnLfGQ5JVmrsp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5uYbnLfGQ5JVmrsp .icon-shape .label rect,#mermaid-svg-5uYbnLfGQ5JVmrsp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uYbnLfGQ5JVmrsp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5uYbnLfGQ5JVmrsp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5uYbnLfGQ5JVmrsp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
正常运行
主节点对外服务
心跳超时?
故障判定
仲裁确认
资源释放
VIP/磁盘漂移
备节点接管
启动服务
业务恢复
流量切回新主
典型架构模式
主备模式 (Active-Standby)
最常见的双机热备模式:
#mermaid-svg-GP25k1zwyWx0eDLr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GP25k1zwyWx0eDLr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GP25k1zwyWx0eDLr .error-icon{fill:#552222;}#mermaid-svg-GP25k1zwyWx0eDLr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GP25k1zwyWx0eDLr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GP25k1zwyWx0eDLr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GP25k1zwyWx0eDLr .marker.cross{stroke:#333333;}#mermaid-svg-GP25k1zwyWx0eDLr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GP25k1zwyWx0eDLr p{margin:0;}#mermaid-svg-GP25k1zwyWx0eDLr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GP25k1zwyWx0eDLr .cluster-label text{fill:#333;}#mermaid-svg-GP25k1zwyWx0eDLr .cluster-label span{color:#333;}#mermaid-svg-GP25k1zwyWx0eDLr .cluster-label span p{background-color:transparent;}#mermaid-svg-GP25k1zwyWx0eDLr .label text,#mermaid-svg-GP25k1zwyWx0eDLr span{fill:#333;color:#333;}#mermaid-svg-GP25k1zwyWx0eDLr .node rect,#mermaid-svg-GP25k1zwyWx0eDLr .node circle,#mermaid-svg-GP25k1zwyWx0eDLr .node ellipse,#mermaid-svg-GP25k1zwyWx0eDLr .node polygon,#mermaid-svg-GP25k1zwyWx0eDLr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GP25k1zwyWx0eDLr .rough-node .label text,#mermaid-svg-GP25k1zwyWx0eDLr .node .label text,#mermaid-svg-GP25k1zwyWx0eDLr .image-shape .label,#mermaid-svg-GP25k1zwyWx0eDLr .icon-shape .label{text-anchor:middle;}#mermaid-svg-GP25k1zwyWx0eDLr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GP25k1zwyWx0eDLr .rough-node .label,#mermaid-svg-GP25k1zwyWx0eDLr .node .label,#mermaid-svg-GP25k1zwyWx0eDLr .image-shape .label,#mermaid-svg-GP25k1zwyWx0eDLr .icon-shape .label{text-align:center;}#mermaid-svg-GP25k1zwyWx0eDLr .node.clickable{cursor:pointer;}#mermaid-svg-GP25k1zwyWx0eDLr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GP25k1zwyWx0eDLr .arrowheadPath{fill:#333333;}#mermaid-svg-GP25k1zwyWx0eDLr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GP25k1zwyWx0eDLr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GP25k1zwyWx0eDLr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GP25k1zwyWx0eDLr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GP25k1zwyWx0eDLr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GP25k1zwyWx0eDLr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GP25k1zwyWx0eDLr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GP25k1zwyWx0eDLr .cluster text{fill:#333;}#mermaid-svg-GP25k1zwyWx0eDLr .cluster span{color:#333;}#mermaid-svg-GP25k1zwyWx0eDLr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GP25k1zwyWx0eDLr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GP25k1zwyWx0eDLr rect.text{fill:none;stroke-width:0;}#mermaid-svg-GP25k1zwyWx0eDLr .icon-shape,#mermaid-svg-GP25k1zwyWx0eDLr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GP25k1zwyWx0eDLr .icon-shape p,#mermaid-svg-GP25k1zwyWx0eDLr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GP25k1zwyWx0eDLr .icon-shape .label rect,#mermaid-svg-GP25k1zwyWx0eDLr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GP25k1zwyWx0eDLr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GP25k1zwyWx0eDLr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GP25k1zwyWx0eDLr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HA集群
客户端
数据同步
心跳
心跳
业务流量
虚拟IP / 浮动IP
主节点
Active
处理业务
备节点
Standby
待机同步
心跳链路
特点:
- 一台干活,一台待命
- 资源利用率 ~ 50%
- 切换简单,无冲突风险
双主模式 (Active-Active)
两台节点同时对外服务,互为备份:
#mermaid-svg-WCQBD2VBeGl2cxGK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WCQBD2VBeGl2cxGK .error-icon{fill:#552222;}#mermaid-svg-WCQBD2VBeGl2cxGK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WCQBD2VBeGl2cxGK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WCQBD2VBeGl2cxGK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WCQBD2VBeGl2cxGK .marker.cross{stroke:#333333;}#mermaid-svg-WCQBD2VBeGl2cxGK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WCQBD2VBeGl2cxGK p{margin:0;}#mermaid-svg-WCQBD2VBeGl2cxGK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK .cluster-label text{fill:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK .cluster-label span{color:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK .cluster-label span p{background-color:transparent;}#mermaid-svg-WCQBD2VBeGl2cxGK .label text,#mermaid-svg-WCQBD2VBeGl2cxGK span{fill:#333;color:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK .node rect,#mermaid-svg-WCQBD2VBeGl2cxGK .node circle,#mermaid-svg-WCQBD2VBeGl2cxGK .node ellipse,#mermaid-svg-WCQBD2VBeGl2cxGK .node polygon,#mermaid-svg-WCQBD2VBeGl2cxGK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WCQBD2VBeGl2cxGK .rough-node .label text,#mermaid-svg-WCQBD2VBeGl2cxGK .node .label text,#mermaid-svg-WCQBD2VBeGl2cxGK .image-shape .label,#mermaid-svg-WCQBD2VBeGl2cxGK .icon-shape .label{text-anchor:middle;}#mermaid-svg-WCQBD2VBeGl2cxGK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WCQBD2VBeGl2cxGK .rough-node .label,#mermaid-svg-WCQBD2VBeGl2cxGK .node .label,#mermaid-svg-WCQBD2VBeGl2cxGK .image-shape .label,#mermaid-svg-WCQBD2VBeGl2cxGK .icon-shape .label{text-align:center;}#mermaid-svg-WCQBD2VBeGl2cxGK .node.clickable{cursor:pointer;}#mermaid-svg-WCQBD2VBeGl2cxGK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WCQBD2VBeGl2cxGK .arrowheadPath{fill:#333333;}#mermaid-svg-WCQBD2VBeGl2cxGK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WCQBD2VBeGl2cxGK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WCQBD2VBeGl2cxGK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WCQBD2VBeGl2cxGK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WCQBD2VBeGl2cxGK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WCQBD2VBeGl2cxGK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WCQBD2VBeGl2cxGK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WCQBD2VBeGl2cxGK .cluster text{fill:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK .cluster span{color:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WCQBD2VBeGl2cxGK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WCQBD2VBeGl2cxGK rect.text{fill:none;stroke-width:0;}#mermaid-svg-WCQBD2VBeGl2cxGK .icon-shape,#mermaid-svg-WCQBD2VBeGl2cxGK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WCQBD2VBeGl2cxGK .icon-shape p,#mermaid-svg-WCQBD2VBeGl2cxGK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WCQBD2VBeGl2cxGK .icon-shape .label rect,#mermaid-svg-WCQBD2VBeGl2cxGK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WCQBD2VBeGl2cxGK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WCQBD2VBeGl2cxGK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WCQBD2VBeGl2cxGK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HA集群
心跳+互备
负载均衡器
节点A
Active
运行业务A
节点B
Active
运行业务B
特点:
- 资源利用率 ~ 100%
- 单节点故障时另一节点接管全部业务➡️性能降低
- 需要严格的资源隔离与脑裂防护
N+1 多节点模式
多台工作节点 + 1台专用备节点:
#mermaid-svg-rco9yA4jZRa3ytvL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rco9yA4jZRa3ytvL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rco9yA4jZRa3ytvL .error-icon{fill:#552222;}#mermaid-svg-rco9yA4jZRa3ytvL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rco9yA4jZRa3ytvL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rco9yA4jZRa3ytvL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rco9yA4jZRa3ytvL .marker.cross{stroke:#333333;}#mermaid-svg-rco9yA4jZRa3ytvL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rco9yA4jZRa3ytvL p{margin:0;}#mermaid-svg-rco9yA4jZRa3ytvL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rco9yA4jZRa3ytvL .cluster-label text{fill:#333;}#mermaid-svg-rco9yA4jZRa3ytvL .cluster-label span{color:#333;}#mermaid-svg-rco9yA4jZRa3ytvL .cluster-label span p{background-color:transparent;}#mermaid-svg-rco9yA4jZRa3ytvL .label text,#mermaid-svg-rco9yA4jZRa3ytvL span{fill:#333;color:#333;}#mermaid-svg-rco9yA4jZRa3ytvL .node rect,#mermaid-svg-rco9yA4jZRa3ytvL .node circle,#mermaid-svg-rco9yA4jZRa3ytvL .node ellipse,#mermaid-svg-rco9yA4jZRa3ytvL .node polygon,#mermaid-svg-rco9yA4jZRa3ytvL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rco9yA4jZRa3ytvL .rough-node .label text,#mermaid-svg-rco9yA4jZRa3ytvL .node .label text,#mermaid-svg-rco9yA4jZRa3ytvL .image-shape .label,#mermaid-svg-rco9yA4jZRa3ytvL .icon-shape .label{text-anchor:middle;}#mermaid-svg-rco9yA4jZRa3ytvL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rco9yA4jZRa3ytvL .rough-node .label,#mermaid-svg-rco9yA4jZRa3ytvL .node .label,#mermaid-svg-rco9yA4jZRa3ytvL .image-shape .label,#mermaid-svg-rco9yA4jZRa3ytvL .icon-shape .label{text-align:center;}#mermaid-svg-rco9yA4jZRa3ytvL .node.clickable{cursor:pointer;}#mermaid-svg-rco9yA4jZRa3ytvL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rco9yA4jZRa3ytvL .arrowheadPath{fill:#333333;}#mermaid-svg-rco9yA4jZRa3ytvL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rco9yA4jZRa3ytvL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rco9yA4jZRa3ytvL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rco9yA4jZRa3ytvL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rco9yA4jZRa3ytvL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rco9yA4jZRa3ytvL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rco9yA4jZRa3ytvL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rco9yA4jZRa3ytvL .cluster text{fill:#333;}#mermaid-svg-rco9yA4jZRa3ytvL .cluster span{color:#333;}#mermaid-svg-rco9yA4jZRa3ytvL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rco9yA4jZRa3ytvL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rco9yA4jZRa3ytvL rect.text{fill:none;stroke-width:0;}#mermaid-svg-rco9yA4jZRa3ytvL .icon-shape,#mermaid-svg-rco9yA4jZRa3ytvL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rco9yA4jZRa3ytvL .icon-shape p,#mermaid-svg-rco9yA4jZRa3ytvL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rco9yA4jZRa3ytvL .icon-shape .label rect,#mermaid-svg-rco9yA4jZRa3ytvL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rco9yA4jZRa3ytvL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rco9yA4jZRa3ytvL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rco9yA4jZRa3ytvL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 负载均衡
节点1 Active
节点2 Active
节点3 Active
备用节点 Standby
特点:
- 节省备机成本
- 只能容忍单节点故障
- 适合大规模集群
脑裂
脑裂(Split-Brain) 是高可用(HA)双击/集群架构中的一种故障状态:原本应该是一主一备的两台设备,因为心跳/状态同步链路中断,双方都认为对方已经宕机,于是同时切换为 Active(主)状态,形成"两个大脑同时发号施令"的局面,所以叫脑裂。
⚠️ 脑裂需要同时满足两个条件才会发生:
- ① 心跳链路完全中断 → 双方无法协商角色
- ② 两台设备各自都还能正常工作 → 双方都有能力"抢当主"
(如果心跳一断,其中一台设备本身也挂了,那不是脑裂)
为什么会产生脑裂?
1. 心跳链路故障(最常见原因)
- 心跳线物理断开、端口故障、中间交换机宕机
- 心跳链路被流量拥塞打满,心跳报文丢包超时
- 拓扑里 Gi0/3 是专用心跳口,如果这条线断了,就失去了"对方是否存活"的判断依据
2. 设备负载过高/性能瓶颈
- 主设备 CPU 打满,无法及时发送心跳报文
- 备设备处理不过来,心跳超时误判对端宕机
3. 软件 Bug / HA 状态机异常(较低概率)
- HA 状态机本身的逻辑缺陷,导致角色协商失败
- 注意:单纯 Gi0/4 状态同步链路断开,不会脑裂
(脑裂的前提是"心跳链路失联",状态链路断只影响"切换时会话是否保持")
脑裂的危害
| 危害 | 具体表现 |
|---|---|
| IP 地址冲突 | 两台设备同时持有同一个 standby VIP,内网出现 ARP 冲突,网络震荡 |
| 流量双份转发 / 环路 | 同一条流被两台防火墙各处理一次,导致会话混乱、丢包、重传 |
| 状态不一致 | 会话表、NAT 表、连接状态各自独立维护,恢复后数据冲突 |
| DMZ 服务器访问异常 | 拓扑里的 NAT 映射(203.0.113.10/.11)可能同时出现在两台 ASA 上,外网访问混乱 |
PAT
PAT = Port Address Translation 端口地址转换
是 NAT 的一种具体形式,也常称为 NAPT(Network Address Port Translation) 或 "多对一 NAT"。
工作原理
- 传统 NAT(一对一):一个内网 IP ↔ 一个公网 IP,需要多少公网 IP 才能满足多少内网主机
- PAT(多对一):多个内网 IP 共享同一个公网 IP,通过不同的源端口来区分不同的会话
example.com :80 ASA防火墙 PAT转换 公网IP: 203.0.113.1 主机B 10.1.10.6:49152 主机A 10.1.10.5:49152 example.com :80 ASA防火墙 PAT转换 公网IP: 203.0.113.1 主机B 10.1.10.6:49152 主机A 10.1.10.5:49152 #mermaid-svg-kRB97bEF3wlAftik{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kRB97bEF3wlAftik .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kRB97bEF3wlAftik .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kRB97bEF3wlAftik .error-icon{fill:#552222;}#mermaid-svg-kRB97bEF3wlAftik .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kRB97bEF3wlAftik .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kRB97bEF3wlAftik .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kRB97bEF3wlAftik .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kRB97bEF3wlAftik .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kRB97bEF3wlAftik .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kRB97bEF3wlAftik .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kRB97bEF3wlAftik .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kRB97bEF3wlAftik .marker.cross{stroke:#333333;}#mermaid-svg-kRB97bEF3wlAftik svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kRB97bEF3wlAftik p{margin:0;}#mermaid-svg-kRB97bEF3wlAftik .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kRB97bEF3wlAftik text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-kRB97bEF3wlAftik .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kRB97bEF3wlAftik .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-kRB97bEF3wlAftik .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-kRB97bEF3wlAftik .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-kRB97bEF3wlAftik #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-kRB97bEF3wlAftik .sequenceNumber{fill:white;}#mermaid-svg-kRB97bEF3wlAftik #sequencenumber{fill:#333;}#mermaid-svg-kRB97bEF3wlAftik #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-kRB97bEF3wlAftik .messageText{fill:#333;stroke:none;}#mermaid-svg-kRB97bEF3wlAftik .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kRB97bEF3wlAftik .labelText,#mermaid-svg-kRB97bEF3wlAftik .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-kRB97bEF3wlAftik .loopText,#mermaid-svg-kRB97bEF3wlAftik .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-kRB97bEF3wlAftik .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kRB97bEF3wlAftik .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-kRB97bEF3wlAftik .noteText,#mermaid-svg-kRB97bEF3wlAftik .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-kRB97bEF3wlAftik .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kRB97bEF3wlAftik .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kRB97bEF3wlAftik .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kRB97bEF3wlAftik .actorPopupMenu{position:absolute;}#mermaid-svg-kRB97bEF3wlAftik .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-kRB97bEF3wlAftik .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kRB97bEF3wlAftik .actor-man circle,#mermaid-svg-kRB97bEF3wlAftik line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-kRB97bEF3wlAftik :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 📤 出站请求阶段 PAT转换表 10.1.10.5:49152 → 203.0.113.1:50001 10.1.10.6:49152 → 203.0.113.1:50002 📥 回程响应阶段 查询PAT表 50001 → 10.1.10.5:49152 查询PAT表 50002 → 10.1.10.6:49152 10.1.10.5:49152 → example.com:80 10.1.10.6:49152 → example.com:80 203.0.113.1:50001 → example.com:80 203.0.113.1:50002 → example.com:80 example.com:80 → 203.0.113.1:50001 example.com:80 → 10.1.10.5:49152 ✅ example.com:80 → 203.0.113.1:50002 example.com:80 → 10.1.10.6:49152 ✅
为什么出现 PAT?
| 驱动力 | 说明 |
|---|---|
| IPv4 不够用 | 43 亿地址早已枯竭,不可能每台设备分一个公网 IP |
| 省钱 | 一个公网 IP 供全网设备使用,成本极低 |
| 私有地址普及 | 192.168.x.x 等内网地址无法直接上网,必须靠 PAT 转换 |
| 安全副产物 | 天然隐藏内网拓扑,阻止外部主动入侵 |
实际存在形式
| 形式 | 说明 |
|---|---|
| 家庭路由器 | 最常见,WAN口一个IP,全家设备共享上网 |
| 企业防火墙 | 企业级,配NAT地址池支撑高并发 |
| 运营商CGNAT | 双层NAT:你家路由器WAN口拿到的也是运营商内网IP |
| 云NAT网关 | 阿里云/AWS的VPC内,云服务器借此访问外网 |
| Linux软件 | iptables一条命令就能实现PAT:iptables -t nat -A POSTROUTING -j MASQUERADE |