一、NAT产生的背景

IPv4地址分类
| 类别 | 范围 | 首字节 | 默认掩码 | 网络/主机位 |
|---|---|---|---|---|
| A类 | 1.0.0.0 - 126.255.255.255 | 1-126 | 255.0.0.0 (/8) | 网络.主机.主机.主机 |
| B类 | 128.0.0.0 - 191.255.255.255 | 128-191 | 255.255.0.0 (/16) | 网络.网络.主机.主机 |
| C类 | 192.0.0.0 - 223.255.255.255 | 192-223 | 255.255.255.0 (/24) | 网络.网络.网络.主机 |
| D类 | 224.0.0.0 - 239.255.255.255 | 224-239 | 无(组播专用) | 组播地址 |
| E类 | 240.0.0.0 - 255.255.255.255 | 240-255 | 无(保留实验) | 实验地址 |
私有地址(必须记住)
| 类别 | 私有地址范围 | CIDR表示 |
|---|---|---|
| A类私有 | 10.0.0.0 - 10.255.255.255 | 10.0.0.0/8 |
| B类私有 | 172.16.0.0 - 172.31.255.255 | 172.16.0.0/12 |
| C类私有 | 192.168.0.0 - 192.168.255.255 | 192.168.0.0/16 |
二、定义

三、工作流程

四、NAT的种类
源NAT
1、NO-PAT

bash
# NO-PAT配置示例(华为)
nat address-group 1 202.100.1.100 202.100.1.100 # 单个IP
nat-policy
rule name "no_pat_rule"
source-zone trust
destination-zone untrust
source-address 192.168.1.100 32 # 只转换这个IP
action source-nat address-group 1 no-pat # 关键:no-pat参数
为什么NO-PAT模式下安全策略优先?
原因:需要基于真实身份做安全检查
bash
情景:内网服务器通过NO-PAT对外提供服务
服务器:192.168.1.100 → 映射为公网IP:202.100.1.100
访问流程:
外部用户(8.8.8.8) → 请求202.100.1.100:80 → [防火墙] → 服务器192.168.1.100:80
安全策略必须基于【真实身份】做控制,而NAT会【隐藏真实身份】'
第一层:数据层面(最直观)
bash
# 内网有两个用户:
员工A:192.168.1.10
员工B:192.168.1.20
# 出访互联网时,PAT转换:
192.168.1.10:1000 → 202.100.1.1:2000
192.168.1.20:1000 → 202.100.1.1:2001
# 到达安全策略时:
看到的都是:202.100.1.1 在访问
问:哪个是员工A?哪个是员工B?
答:分不出来!
第二层:策略配置层面
bash
# 企业需求:研发部可以上网,财务部不能上网
研发部:192.168.1.0/24
财务部:192.168.2.0/24
# 如果先NAT后安全:
所有人 → 都变成202.100.1.1 → 安全策略怎么写?
只能写:允许202.100.1.1上网
结果:财务部也能上网了!
# 如果先安全后NAT:
安全策略:
1. 允许192.168.1.0/24上网
2. 拒绝192.168.2.0/24上网
NAT策略:
1. 将允许上网的流量做NAT转换
结果:财务部根本上不了网
第三层:实际报文流程
错误顺序(先NAT后安全)
bash
# 财务部员工访问百度
原始包:src=192.168.2.10 → NAT → src=202.100.1.1
安全策略:检查202.100.1.1→百度 → 允许!❌
# 研发部员工访问百度
原始包:src=192.168.1.10 → NAT → src=202.100.1.1
安全策略:检查202.100.1.1→百度 → 允许 ✓
# 问题:安全策略看不到192.168.2.10这个关键信息!
正确顺序(先安全后NAT)
bash
# 财务部员工访问百度
原始包:src=192.168.2.10 → 安全策略 → 拒绝!不允许上网 → 丢弃 ❌
# 研发部员工访问百度
原始包:src=192.168.1.10 → 安全策略 → 允许 ✓ → NAT → src=202.100.1.1 → 转发
# 安全策略基于真实地址做决策,NAT只是匿名化工具
对于外部进来的流量,通常是【先NAT后安全】,而不是【先安全后NAT】!
外部访问内部的完整流程
情况1:先安全后NAT(有问题)
bash
# 外部访问内部Web服务器
公网IP:202.100.1.100 → NAT映射到 → 内网IP:192.168.1.100
# 防火墙处理流程(先安全后NAT):
1. 收到包:src=8.8.8.8, dst=202.100.1.100:80
2. 执行安全策略:检查"8.8.8.8→202.100.1.100:80"是否允许 ✓
3. 执行NAT:dst转换为192.168.1.100:80
4. 转发到服务器
# 看起来没问题,但实际配置时:
安全策略应该怎么写?
- 写目的IP=202.100.1.100(公网IP)?
- 还是写目的IP=192.168.1.100(内网IP)?
问题所在:
-
配置混乱:管理员要在安全策略里记住公网IP,但在内网看到的却是内网IP
-
多个服务器时更乱:
bash
服务器A:内网192.168.1.100 → 公网202.100.1.100
服务器B:内网192.168.1.200 → 公网202.100.1.200
安全策略配置:
- 允许访问202.100.1.100
- 拒绝访问202.100.1.200
但内部管理时用的是192.168.1.x,需要大脑转换!
情况2:先NAT后安全(更合理)
bash
# 同样场景,采用先NAT后安全:
1. 收到包:src=8.8.8.8, dst=202.100.1.100:80
2. 执行NAT:dst转换为192.168.1.100:80
3. 执行安全策略:检查"8.8.8.8→192.168.1.100:80"是否允许 ✓
4. 转发到服务器
# 安全策略配置:
rule name "allow_web_server"
source-zone untrust
destination-zone dmz
source-address 8.8.8.8 32
destination-address 192.168.1.100 32 # 直接写内网IP!
service http
action permit
优势:
-
配置直观:安全策略直接管控内网服务器IP
-
管理简单:不用在公网IP和内网IP之间来回转换
-
逻辑清晰:内部网络的所有策略都基于内部地址
bash
┌─────────────┐ 出站流量(内→外) ┌─────────────┐
│ 内网用户 │ ────────────────────▶ │ 互联网 │
│ 192.168.x.x │ │ │
└─────────────┘ └─────────────┘
│ ▲
│ │
▼ │
┌────────────────────────────────────────────┐
│ 防火墙策略处理顺序 │
├────────────────────────────────────────────┤
│ 出站方向: │
│ 1. 收到包:src=192.168.1.10 → 安全策略检查 │
│ 2. 允许? → 执行NAT:src=202.100.1.1 │
│ 3. 转发到外网 │
│ │
│ 入站方向: │
│ 1. 收到包:dst=202.100.1.100 → 执行NAT │
│ 2. NAT转换:dst=192.168.1.100 │
│ 3. 安全策略检查:访问192.168.1.100允许吗? │
│ 4. 允许? → 转发到内网 │
└────────────────────────────────────────────┘
Server Map表
会话表老化时间是很快的,但是生成的server map表,老化时间比较慢

这还会产生 No-pat Reverse 这个反向表
-
NAT Server-Map表 :是静态的、预制的"地图" ,告诉防火墙"当外面的人要找公网IP X的Y端口时,应该把它转到内网IP A的B端口"。它解决的是**"找谁"**的问题。
-
ASPF Server-Map表 :是动态的、智能的"通行证" ,告诉防火墙"里面这个客户端刚刚协商了一个新端口Z,等会儿外面会有数据从这个端口进来,你得提前放行"。它解决的是**"怎么进"**的问题。
联系 :它们都是防火墙在会话正式建立之前 就预先准备好的"映射关系"或"放行规则",目的是让后续流量能够被正确处理。
区别 :一个解决地址转换 的映射,一个解决协议通道的放行。
第一部分:NAT Server-Map 表(静态的地址转换地图)
1. 是什么?
这是配置静态NAT(包括NAT Server、目的NAT) 时自动生成的表项。它是一个"预转换规则",在第一个数据包到达之前就已经存在。
2. 为什么需要它?(逻辑核心)
想象一下,如果没有这个表,外部第一个访问服务器的数据包到达防火墙时,会发生什么?
-
这是一个新连接,会话表(Session Table)里查不到。
-
防火墙不知道这个目标是公网IP的数据包应该转给哪个内网服务器。
-
数据包会被丢弃。
NAT Server-Map表的作用,就是在首包触发创建会话之前,提前告诉防火墙NAT转换规则。 它是指路明灯。
3. 技术细节与工作流程
bash
# 配置示例(华为):将公网202.100.1.100的80端口映射到内网192.168.1.100的80端口
nat server protocol tcp global 202.100.1.100 80 inside 192.168.1.100 80
# 生成的Server-Map表项(概念展示):
类型:NAT Server
映射: (202.100.1.100:80, ANY) <--> (192.168.1.100:80, ANY)
生效域: Untrust -> DMZ
工作流程:
bash
外部客户端(8.8.8.8:5000) ──[SYN包]──> 防火墙外网口(202.100.1.100:80)
↓
防火墙收到包,查找会话表 → 未命中(新连接)
↓
查询 NAT Server-Map 表 → **命中!** "需转换目的地址"
↓
执行转换:目的IP:Port = 202.100.1.100:80 → 192.168.1.100:80
↓
查找路由,并执行安全策略检查(针对转换后的目标192.168.1.100)
↓
检查通过,**正式创建会话表项**,记录双向NAT关系
↓
数据包转发给内网服务器(192.168.1.100:80)
关键点 :NAT Server-Map表的存在,让首包就能完成NAT转换,进而触发后续的安全策略检查和会话建立。
第二部分:ASPF Server-Map 表(动态的协议通道守卫)
1. 是什么?
这是ASPF(Application Specific Packet Filter,应用层包过滤) 功能动态生成的表项。它是一个"临时放行规则",在一个已建立的会话进行应用层协商之后才动态产生。
2. 为什么需要它?(逻辑核心)
很多应用层协议(如FTP、SIP、H.323)的通信模式是"多通道"的:
-
客户端先与服务器的知名端口 建立控制连接(如FTP的21端口)。
-
在控制连接里,双方协商 出一个新的数据端口(如FTP客户端说:"我在端口6000等你")。
-
服务器随后主动向客户端的这个新端口 发起数据连接。
问题来了:如果没有ASPF,防火墙会怎么看待服务器发起的这个新连接?
-
这是一个从外到内(对客户端而言)的新SYN包。
-
防火墙的默认状态检测机制是"只允许内网主动发起的连接的返回报文"。
-
这个数据连接是服务器主动发起的,没有对应的出向会话,因此会被安全策略默认拒绝!
ASPF Server-Map表的作用,就是通过深度检测控制通道的协议报文,提前学习到即将建立的数据通道信息,并为其动态打开一个"洞"。
3. 技术细节与工作流程(以FTP Active模式为例)
bash
# 启用FTP协议的ASPF(华为)
firewall interzone trust untrust
detect ftp
工作流程:
bash
步骤1:控制连接建立
内网客户端(192.168.1.10:随机端口) ──[连接]──> 外网FTP服务器(8.8.8.8:21)
↓
防火墙创建会话:192.168.1.10:PortX <--> 8.8.8.8:21
步骤2:客户端协商数据端口(关键!)
客户端在控制信道发送:PORT 192,168,1,10,23,112 (即IP=192.168.1.10,端口=23*256+112=6000)
↓
**ASPF引擎深度检测(识别PORT命令)**
↓
**动态生成 ASPF Server-Map 表项**(概念展示):
类型:ASPF
映射: (8.8.8.8:ANY, 192.168.1.10:6000)
方向: 允许从Untrust到Trust访问该端口
协议: TCP
超时时间: 例如30秒(临时性)
↓
步骤3:服务器发起数据连接
外网FTP服务器(8.8.8.8:20) ──[SYN包]──> 防火墙(目标是192.168.1.10:6000)
↓
防火墙收到包,查找会话表 → 未命中(这是新连接)
↓
查询 **ASPF Server-Map 表** → **命中!** "允许此连接建立"
↓
放行该SYN包,并为其创建新的数据连接会话表项
↓
FTP数据得以传输
ASPF的server map表是可以绕过安全策略检查的,而No Pat产生的server map表是不能够绕过安全策略检查的
简单来说,这是因为:
-
ASPF Server-Map 的"免检特权",来自于防火墙自己亲眼所见、亲自审查过的会话,是一种"内生的信任延伸"。
-
NO-PAT Server-Map 只是一个静态的地址转换预告 ,它本身不具备任何可信度,安全策略必须对其进行独立审查。
具体分析 :https://chat.deepseek.com/share/9gbuur6ddjvh4kwein

2、NAPT


NAPT是不会生成Server Map表的
NO-PAT:静态一对一映射
bash
内网IP:192.168.1.100 ↔ 公网IP:202.100.1.100(固定)
特点:映射关系在配置时就确定了,是静态的、可预测的
NAPT(PAT):动态多对一映射
bash
内网IP1:192.168.1.100:1000 → 公网IP:202.100.1.1:5000(临时)
内网IP2:192.168.1.101:2000 → 公网IP:202.100.1.1:5001(临时)
特点:映射关系是临时的、动态分配的、不可预测的
Server-Map表的本质是"预置的转换规则",而NAPT是"按需的动态转换"。
为什么NAPT不需要Server-Map表?
1. NAPT的工作方式:会话驱动
bash
# NAPT的工作流程:
用户A访问百度:
1. 发起连接:192.168.1.10:1000 → 8.8.8.8:80
2. 到达防火墙:创建会话表项
3. 动态分配:192.168.1.10:1000 → 202.100.1.1:5000(随机端口)
4. 发送数据包:202.100.1.1:5000 → 8.8.8.8:80
用户B访问百度:
1. 发起连接:192.168.1.20:2000 → 8.8.8.8:80
2. 到达防火墙:创建会话表项
3. 动态分配:192.168.1.20:2000 → 202.100.1.1:5001(另一个随机端口)
关键点:
-
没有预定义的映射关系:不知道用户A会用哪个端口
-
按需动态分配:在数据包到达时实时分配
-
记录在会话表中,不需要预置的Server-Map
2. Server-Map表解决的问题NAPT不存在
Server-Map解决的核心问题:首包转换
bash
对于静态NAT(NO-PAT):
问题:外部第一个包到达时,没有会话,不知道转给谁
方案:预置Server-Map,告诉防火墙"把202.100.1.100转给192.168.1.100"
bash
对于NAPT:
情况:外部不会主动发起访问NAPT的公网IP(因为不知道映射关系)
所以:不存在"外部第一个包到达不知道转给谁"的问题
NAPT天生是单向的:内网主动发起,外部回应


修改地址,配置成和接口不同网段的地址


情况:运营商给你的地址可能并不一定是跟接口地址同一个网段的。

运营商会写一个回程路由发布在IS-IS中。
现在能通,查看会话表

没有server map表

天然穿越NAT的理解
https://chat.deepseek.com/share/jqa2kupavqn5nwzttg
环路问题

内网设备如果去访问6.6.6.6这个防火墙NAT地址池中的地址,这会命中防火墙的默认路由,会丢出去(NAT转换之后丢给外部路由器),但是外部的路由器AR1也指了一条静态路由,又到防火墙了
如果主机去访问地址池中的IP地址的话,而该地址并不是物理接口和逻辑接口上配置的IP地址。这个时候就会产生环路。

把防火墙TTL超时功能打开

如何解决环路

这会为地址池中的地址产生NULL 0 的路由(黑洞路由)


如果是相同网段,最多发几次ARP

3、Easy IP
以连接外网的物理接口的IP地址直接进行转化,不需要建立地址池。
Easy IP 是 NAT 的一种特殊形式,它是 PAT(端口地址转换)的简化版 ,直接使用路由器的出口接口IP地址 作为NAT转换的公网地址,实现多台内网主机共享同一个出口接口IP上网。
"无需配置NAT地址池,直接用路由器外网接口的IP做PAT转换"
传统PAT vs Easy IP对比
传统PAT配置:
bash
# 需要定义地址池
nat address-group PAT_POOL
section 0 202.100.1.100 202.100.1.100 # 需要知道具体公网IP
nat-policy
action source-nat address-group PAT_POOL
Easy IP配置:
bash
# 直接用接口IP,无需地址池
nat-policy
action source-nat easy-ip # 自动使用接口IP
目的NAT
数据到达NAT设备后,更换IP头部的目的地址
我们一般很少做目的NAT,目的NAT分为两种:一种是静态的,一种是动态(端口号会变)的。
目的NAT详解 (Nat server)
https://chat.deepseek.com/share/7apm6o235dleypykp3
目的NAT详解 (Nat 策略)
bash
nat-policy # 进入全局NAT策略视图
rule name dnat
source-zone untrust # 只指定源区域
destination-address 6.6.6.6 mask 255.255.255.255
service http
action destination-nat address 192.168.1.1
华为防火墙的NAT处理在路由之前
https://chat.deepseek.com/share/iueur7aznu9hf95rrp

NAT Server
目的NAT的一种
NAT Server:把内网服务"安全地展示"给全世界的技术
NAT Server 是目的NAT 的具体实现形式,专门用于将内网服务器发布到公网,让外部用户能够访问。它是防火墙的"迎宾员",负责把外部的访问请求引导到正确的内部服务器。
"告诉防火墙:当有人来找公网IP的某个端口时,请把他带到内网服务器的对应端口"
问题场景
bash
你的公司有:
- 内部Web服务器:192.168.1.100:80
- 公网IP地址:202.100.1.100
客户想访问公司网站,但:
❌ 客户不能直接访问192.168.1.100(私有地址,无法路由)
❌ 不能把服务器直接放到公网(不安全)
✅ 解决方案:NAT Server!
NAT Server的作用
-
地址转换:公网IP → 内网IP
-
端口映射:外部端口 → 内部端口
-
安全隔离:服务器在内网,防火墙保护
-
灵活控制:可以控制谁能访问、访问什么服务
完整配置详解(华为防火墙)
基础环境准备
bash
# 1. 创建安全区域
firewall zone trust
add interface GigabitEthernet0/0/1 # 内网口
firewall zone dmz
add interface GigabitEthernet0/0/2 # 服务器区口
firewall zone untrust
add interface GigabitEthernet0/0/0 # 外网口
# 2. 配置接口IP
interface GigabitEthernet0/0/0 # 外网口
ip address 202.100.1.1 24
interface GigabitEthernet0/0/2 # DMZ口
ip address 192.168.1.1 24
# 3. 配置服务器
# 假设Web服务器IP:192.168.1.100,网关指向192.168.1.1
案例1:基础Web服务器发布
bash
# 核心配置:一条命令完成映射
nat server protocol tcp global 202.100.1.100 80 inside 192.168.1.100 80
# 分解理解:
# nat server → 配置NAT Server
# protocol tcp → 协议类型是TCP
# global 202.100.1.100 80 → 公网IP和端口
# inside 192.168.1.100 80 → 内网IP和端口
必须的安全策略
bash
# NAT Server只负责转换,必须配合安全策略
security-policy
rule name "allow_web_in"
source-zone untrust # 来自外网
destination-zone dmz # 去往服务器区
destination-address 192.168.1.100 32 # 重要:用内网IP!
service http # 只允许HTTP
action permit
# 可选:记录日志,便于审计
rule name "web_log"
source-zone untrust
destination-zone dmz
destination-address 192.168.1.100 32
service http
action permit
logging
验证命令
bash
# 1. 查看配置
display nat server
# 2. 查看Server-Map表
display firewall server-map | include 202.100.1.100
# 3. 从外网测试访问
# 在另一台机器执行:
curl http://202.100.1.100
# 4. 查看会话表
display firewall session table verbose
# 应该看到转换过程:202.100.1.100:80 → 192.168.1.100:80
1、产生背景:因为服务器在内网中(私网IP地址),需要被外网的终端访问。需要在NAT设备(边界设备)上配置NAT Server,也就是访问目的的服务的时候,通过一个公网IP映射到内网服务器的IP对应的服务。
2、原理:

NAT Server产生的Server Map表也是不能够绕过安全策略检查的,
配置了NAT Server以后,会产生server map表,并产生反向的server map表项。
正向的表是用于外网进来的,反向的表是用于我的服务器出去的。
数据包处理流程
出站流量处理(内网→外网)
bash
内网用户发起访问:
┌─────────────────────────────────────────────────────────┐
│ 数据包流程 │
├─────────────────────────────────────────────────────────┤
│ 1. 入站: src=192.168.1.10:5000, dst=8.8.8.8:80 │
│ 2. 会话查找: 未命中(新建会话) │
│ 3. 目的NAT: 不匹配NAT Server │
│ 4. 路由查找: 出接口=GE0/0/0, 区域=untrust │
│ 5. 安全策略: 检查trust→untrust是否允许 │
│ 6. 源NAT: 匹配源NAT策略, 转换src=202.100.1.1:6000 │
│ 7. 创建会话表项 │
│ 8. 出站: src=202.100.1.1:6000, dst=8.8.8.8:80 │
└─────────────────────────────────────────────────────────┘
入站流量处理(外网→内网服务器)
bash
外网用户访问内网服务器:
┌─────────────────────────────────────────────────────────┐
│ 数据包流程 │
├─────────────────────────────────────────────────────────┤
│ 1. 入站: src=8.8.8.8:1234, dst=202.100.1.100:80 │
│ 2. 会话查找: 未命中(新建会话) │
│ 3. 目的NAT: 匹配NAT Server, 转换dst=192.168.1.100:80 │
│ 4. 路由查找: 出接口=GE0/0/2, 区域=dmz │
│ 5. 安全策略: 检查untrust→dmz是否允许 │
│ 6. 源NAT: 不匹配源NAT策略(通常入站不做源NAT) │
│ 7. 创建会话表项 │
│ 8. 出站: src=8.8.8.8:1234, dst=192.168.1.100:80 │
└─────────────────────────────────────────────────────────┘

如果是源NAT,那么转化地址前就需要安全策略的检查,如果是NAT Server就需要转换后做安全策略的检查。

查看server map表

这有一个反向的server map表:Nat Server Reverse
安全策略

查看是否命中安全策略

问题:为什么NAT Server需要Server-Map表?
根本原因:解决"先有鸡还是先有蛋"的问题
问题场景:
bash
外部用户第一次访问内部服务器:
1. 数据包到达防火墙:dst=202.100.1.100:80
2. 防火墙需要知道:这个包要转给谁?
3. 但防火墙还没建立会话(这是第一个包)
4. 如果没有预置规则,防火墙不知道如何处理
解决方案:
bash
# 管理员配置NAT Server
nat server protocol tcp global 202.100.1.100 80 inside 192.168.1.100 80
# 防火墙立即生成Server-Map表:
"告诉防火墙:以后看到目的地是202.100.1.100:80的包,直接转给192.168.1.100:80"
Server-Map表是"NAT规则的缓存"
bash
传统NAT处理:每个包都要重新匹配NAT规则(慢!)
Server-Map表:预先把NAT规则"编译"成快速查找表(快!)
类比:酒店预订系统
bash
没有Server-Map表:
- 每个客人到前台,前台都要翻厚厚的预订记录本找房间
- 速度慢,客人等待时间长
有Server-Map表:
- 前台有块白板,写着"张三 → 101房间"
- 客人一到,前台看一眼白板就知道去哪里
- 快速高效
为什么Server-Map表还有Reverse表?
这才是问题的关键!Reverse表解决了另一个根本问题
场景:内网服务器需要访问外网
内网Web服务器(192.168.1.100)需要:
下载系统更新
访问外部API
连接数据库等
问题:服务器用哪个IP访问外网?
选项A:用自己的私网IP 192.168.1.100 ❌
选项B:用公网IP 202.100.1.100 ✅
为什么必须是选项B?
原因1:地址一致性
bash
外部世界认为你的服务器是202.100.1.100
如果服务器用192.168.1.100访问外部:
1. 外部服务看到访问者是192.168.1.100
2. 但外部只知道202.100.1.100是你的服务器
3. 导致身份认证、回调等问题
原因2:会话关联性
bash
假设服务器访问外部API:
1. 服务器发起请求:src=192.168.1.100 → dst=api.com
2. API回应:dst=192.168.1.100(无法路由!)
如果服务器用202.100.1.100访问:
1. 服务器发起请求:src=202.100.1.100 → dst=api.com
2. API回应:dst=202.100.1.100(防火墙转换到192.168.1.100)
Reverse表的本质
bash
Reverse表是"源地址保证书":
"当内网服务器192.168.1.100访问外网时,请确保它使用公网IP 202.100.1.100"
完整数据流分析(包含Reverse表的作用)
场景:Web服务器需要下载更新
bash
服务器:192.168.1.100(内网IP)
公网映射:202.100.1.100
更新服务器:download.microsoft.com
步骤1:服务器发起下载请求
bash
# 原始数据包
src_ip = 192.168.1.100
src_port = 50000
dst_ip = 13.107.xxx.xxx(微软CDN)
dst_port = 443
# 经过防火墙时
1. 查Server-Map表
2. 匹配Reverse表项:192.168.1.100 → 202.100.1.100
3. 转换源地址:src_ip = 202.100.1.100
4. 发送出去
步骤2:微软CDN回应
bash
# 微软看到的请求来自:202.100.1.100:50000
# 所以回应给:202.100.1.100:50000
# 数据包到达防火墙
src_ip = 13.107.xxx.xxx
dst_ip = 202.100.1.100
dst_port = 50000
# 防火墙处理
1. 查会话表:找到对应会话
2. 转换目的地址:202.100.1.100 → 192.168.1.100
3. 转发给服务器
如果没有Reverse表会怎样?
bash
# 假设服务器用普通PAT转换
192.168.1.100:50000 → 202.100.1.1:60000(另一个公网IP)
# 微软CDN看到:
请求来自:202.100.1.1:60000(不是你的服务器公网IP!)
# 问题:
1. CDN无法识别这是你的服务器
2. 如果CDN有IP白名单,会拒绝请求
3. 如果CDN需要回调,会回调到202.100.1.1:60000
4. 会话不匹配,可能导致连接失败
Server-Map表的两种表项详解
1. 正向表项(Forward Entry)
bash
# 配置生成
nat server protocol tcp global 202.100.1.100 80 inside 192.168.1.100 80
# 生成的表项
Type: Nat Server
匹配条件:dst_ip=202.100.1.100 && dst_port=80
动作:转换dst_ip=192.168.1.100, dst_port=80
用途:外部访问内部服务器
2. 反向表项(Reverse Entry)
bash
# 自动生成(无需配置)
Type: Nat Server Reverse
匹配条件:src_ip=192.168.1.100 && src_port=80
动作:转换src_ip=202.100.1.100, src_port=80
用途:内部服务器访问外部
Q1:为什么NAT Server需要Server-Map表?
A:为了在第一个数据包到达时就能快速进行目的NAT转换,避免遍历所有NAT规则,提高处理效率。
Q2:为什么Server-Map表还有Reverse表?
A:为了确保内网服务器访问外部时,源地址与外部访问时的目的地址一致(即都使用公网IP),维持网络连接的身份一致性。
如果有时候为了安全上考虑,可以配置不产生反向server map表

NAT Server面临的环路问题
环路产生的具体技术场景
网络拓扑
bash
内网用户(192.168.1.50) → 防火墙(192.168.1.1) → 公网
↓
内网服务器(192.168.1.100) 挂了!
防火墙配置了NAT Server:
202.100.1.100:80 → 192.168.1.100:80
环路产生步骤(没有UNR-ROUTE)
步骤1:内部用户访问公网IP
bash
# 内网用户发起请求
src=192.168.1.50:50000, dst=202.100.1.100:80
用户 → 防火墙(默认网关是192.168.1.1)
步骤2:防火墙查路由表
bash
# 查看防火墙路由表
display ip routing-table 202.100.1.100
# 没有UNR-ROUTE时,可能匹配到:
# 1. 默认路由:0.0.0.0/0 → 外网接口(如果有)
# 2. 或者没有明确路由
# 假设有默认路由指向外网:
ip route-static 0.0.0.0 0.0.0.0 202.100.1.254
步骤3:匹配NAT Server失败
bash
# 数据包到达防火墙
# 目的IP=202.100.1.100 → 匹配NAT Server表
# 但是服务器挂了,没有响应
# 关键是:防火墙会把这个公网IP当作"可路由的地址"
# 因为它没有明确告诉防火墙"这个地址其实是我虚拟的"
步骤4:环路形成
bash
情况A:如果默认路由指向外网
192.168.1.50 → 202.100.1.100 → 防火墙 → 外网路由器 → 又回到防火墙 → ...
情况B:如果有其他路由指向内网
192.168.1.50 → 202.100.1.100 → 防火墙 → 内网交换机 → 又回到防火墙 → ...
情况C:最糟糕的是,服务器挂了但ARP缓存还在
192.168.1.50 → 202.100.1.100 → 防火墙 → ARP请求192.168.1.100 → 无响应 → 可能被其他设备错误响应
UNR-ROUTE如何防止环路
配置示例
bash
# 配置NAT Server时加上unr-route
nat server protocol tcp global 202.100.1.100 80 inside 192.168.1.100 80 unr-route
# 自动生成黑洞路由:
# 202.100.1.100/32 → NULL0(黑洞)
查看生成的路由
bash
display ip routing-table | include 202.100.1.100
# 输出:
Destination/Mask Proto Pre Cost NextHop Interface
202.100.1.100/32 UNR 255 0 0.0.0.0 NULL0
# UNR = User Network Route(用户网络路由)
# NULL0 = 黑洞接口,丢弃所有数据包
UNR-ROUTE的工作原理
原理1:告诉防火墙"这个地址是我的"
bash
没有UNR-ROUTE:
防火墙:"202.100.1.100是外网地址,我要查路由表找怎么走"
有UNR-ROUTE:
防火墙:"202.100.1.100是我管理的地址,我有它的路由"
原理2:建立精确的主机路由
bash
# 黑洞路由的特点:
1. 掩码/32:最精确的路由,优先级最高
2. 指向NULL0:数据包直接丢弃
3. 管理距离255:路由优先级最低(但因为是/32,还是很精确)
# 路由匹配顺序(精确匹配优先):
1. 202.100.1.100/32(最精确,UNR路由)
2. 202.100.1.0/24
3. 0.0.0.0/0(默认路由)
原理3:配合NAT Server的智能处理
bash
数据包到达防火墙的处理逻辑:
1. 先检查NAT Server表:匹配则转换
2. 如果不匹配(比如端口不对),才查路由表
3. 匹配到UNR路由(黑洞)→ 丢弃
这样保证了:
- 合法的访问(匹配NAT Server)正常转发
- 非法的访问(不匹配NAT Server)被丢弃
为什么Ping会产生环路,但是http服务不会产生环路?
https://chat.deepseek.com/share/3p11ra6yeh96y5spyc
Smart NAT:NAPT+NOPAT
假设有N个公网地址,那么N-1个地址做No PAT(这个的好处是会产生server map表,后续转发快),还有一个地址做NAPT
原理:Smart NAT就是NAPT和NO-PAT的组合使用,留一个IP地址做NAPT,其余的地址做NO-PAT。
想利用No-PAT的优点,但是又不希望里面的内网上不了外网。