IPSec的封装——TK

封装模式
IPsec封装模式:传输模式 vs 隧道模式
一句话本质
IPsec封装模式的本质是“保护范围”的区别:
-
传输模式:只保护IP载荷(TCP/UDP等),保留原IP头不变。
-
隧道模式:保护整个原始IP包,再添加一个新IP头。
一、设计初衷:为什么要分两种模式?
IPsec设计于90年代,面临两种主要需求:
-
端到端的主机安全:两台主机之间直接通信,中间网络是可信的(如企业内部网络),但担心链路被窃听。此时不需要隐藏源目IP,只需要加密内容。→ 传输模式
-
网关到网关的VPN:两个安全网关之间建立隧道,保护各自后面的私网主机。此时需要隐藏私网拓扑,让公网只看到网关的IP地址。→ 隧道模式
这两种需求对IP头的处理完全不同,所以协议设计了两种模式。
二、传输模式(Transport Mode)
报文结构(以ESP为例)
原始IP包:
[ IP头(源=A,目的=B) ] [ TCP头 ] [ 数据 ]
传输模式ESP封装后:
[ IP头(源=A,目的=B) ] [ ESP头 ] [ TCP头 ] [ 数据 ] [ ESP尾 ] [ ESP认证 ]
↑——————— 加密部分 ———————↑
本质与精髓
-
原IP头不动:源IP和目的IP保持不变,仍然是通信双方的真实地址。
-
只加密上层协议:TCP/UDP/ICMP等载荷被保护,但IP头明文暴露。
-
为什么这样设计? 因为端到端通信时,中间路由器需要看到真实IP地址来转发报文。加密IP头会导致路由器无法路由。传输模式在“保证内容机密”的同时,不破坏原有的路由结构。
场景
-
两台服务器在同一个安全域内(如数据中心内部),但需要加密通信内容防止同一交换机上的其他设备嗅探。
-
或者作为更复杂隧道的一部分(如GRE over IPsec中,IPsec使用传输模式保护GRE包,因为GRE已经提供了外层IP头)。
三、隧道模式(Tunnel Mode)
报文结构(以ESP为例)
原始IP包:
[ 原IP头(源=私网A,目的=私网B) ] [ TCP头 ] [ 数据 ]
隧道模式ESP封装后:
[ 新IP头(源=网关1公网,目的=网关2公网) ] [ ESP头 ] [ 原IP头 ] [ TCP头 ] [ 数据 ] [ ESP尾 ] [ ESP认证 ]
↑—————————— 整个原IP包被加密 ———————————↑
本质与精髓
-
增加新IP头:新IP头的源目地址是VPN网关的公网地址,用于在公网上路由。
-
加密整个原始IP包:包括原始IP头。所以私网地址(如192.168.x.x)完全不可见。
-
为什么这样设计? 因为私网地址在公网上不可路由。隧道模式把私网IP包“装进”一个公网IP包中,由网关负责封装/解封装。同时隐藏了内部网络拓扑,提高了安全性。
场景
-
站点到站点VPN:企业总部与分支之间,各自内网使用私有地址,通过公网加密通信。
-
远程访问VPN:员工从家里访问公司内网,客户端虚拟一个IP地址,与VPN网关建立隧道。
**************************************************************************************************************
安全协议
AH vs ESP:本质区别与设计精髓
-
AH(认证头):提供数据完整性和身份认证,但不加密。它保护IP包的整个载荷和IP头中的部分字段(防篡改)。
-
ESP(封装安全载荷):提供加密(机密性) + 可选认证。它保护IP包载荷(传输模式)或整个IP包(隧道模式)
核心区别:AH保护数据不被篡改(防改写),ESP保护数据不被偷看(防偷看) + 可选防篡改。
为什么这样设计?—— 两个独立的安全需求
90年代设计IPsec时,安全专家意识到:
-
有时只需要防篡改,不需要加密。例如:路由器之间交换的路由协议报文(如OSPF),你希望确保它没有被中间人修改,但内容本身不必保密(因为路由信息本来就是要公开的)。加密会浪费CPU,且可能触发出口管制(当年密码技术受限制)。
-
但大多数场景需要同时保证机密性和完整性(如VPN传输业务数据),所以需要ESP。
于是协议分成了两个独立协议:AH专门做认证,ESP专门做加密+可选认证。后来ESP也加入了认证功能,导致AH逐渐边缘化,但AH仍有独特价值。
-
AH(Authentication Header):提供数据完整性和源认证,但不加密。
-
ESP(Encapsulation Security Payload):提供数据加密(机密性),并可选提供完整性和认证。
两者都工作在IP层,都需要IKE来协商密钥和参数。
AH:具体怎么干活?
1. 发送方处理(以传输模式为例)
假设原始IP包:
[ IP头 ] [ TCP头 ] [ 数据 ]
步骤:
-
计算完整性校验值(ICV),计算范围包括:
- IP头中的不可变字段(源IP、目的IP、协议号等,但不包括TTL、校验和等每跳会变的字段)
- 整个TCP头+数据(即整个上层协议数据)
-
在IP头和TCP头之间插入AH头。AH头包含:
- 下一个头(Next Header,标识TCP)
- 载荷长度
- SPI(安全参数索引)
- 序列号(防重放)
- ICV(前面算出的完整性校验值)
-
修改IP头中的“协议号”字段为51(表示后面跟着AH)。
-
发出报文。
最终报文结构:
[ IP头(协议=51) ] [ AH头 ] [ TCP头+数据 ]
2. 接收方处理
-
看到IP头协议=51,知道后面是AH。
-
根据SPI找到对应的SA(包含密钥、算法等)。
-
用相同的算法,对同样的字段范围(IP头不可变部分 + TCP头+数据)重新计算ICV。
-
对比收到的ICV和自己算的是否一致:
-
一致 → 数据没有被篡改,源IP真实。
-
不一致 → 丢弃报文,并记录异常。
-
关键:AH不修改IP头中的源/目IP,也不加密任何数据。所以中间的转发设备能看到原始IP地址和TCP/UDP端口等所有信息,只是不能篡改。
三、ESP:具体怎么干活?
ESP可以做两件事:加密(必须) 和 认证(可选)。我们按完整功能(加密+认证)讲。
1. 发送方处理(传输模式)
原始IP包:
[ IP头 ] [ TCP头 ] [ 数据 ]
步骤:
-
在TCP头+数据后面添加ESP尾(ESP Trailer),用于补齐加密块长度。
-
将 TCP头+数据+ESP尾 一起加密(使用协商好的加密算法,如AES)。
-
在加密数据前加上ESP头(包含SPI、序列号)。
-
可选:对整个ESP头+加密数据计算ICV,附加到末尾。
-
修改IP头中的“协议号”字段为50(表示后面是ESP)。
-
发出报文。
最终报文结构:
[ IP头(协议=50) ] [ ESP头 ] [ 加密的TCP头+数据+ESP尾 ] [ ESP认证(可选)]
2. 接收方处理
-
看到IP头协议=50,知道后面是ESP。
-
根据SPI找到SA。
-
如果开启了认证,先验证ICV,确保报文未被篡改。
-
解密ESP头后面的数据,还原出TCP头+数据+ESP尾。
-
去掉ESP尾,得到原始TCP头+数据,交给上层。
**************************************************************************************************************
ESP的“完整性”认证范围不包括外层IP头
ESP明明能提供完整性校验,为什么中间人修改IP头时,ESP检测不到?
根本原因:ESP的完整性校验(ICV)计算范围只覆盖ESP头 + 加密后的数据,不包括外层IP头。
而AH的完整性校验包括IP头中的不可变字段(如源IP、目的IP)。
一、举例说明:传输模式下,ESP为什么保护不了IP头?
原始报文(A → B,传输模式ESP)
[ IP头(源=1.1.1.1,目的=2.2.2.2,协议=50) ] [ ESP头 ] [ 加密的TCP数据 ] [ ESP尾 ] [ ESP认证 ]
-
ESP认证计算的范围:ESP头 + 加密的TCP数据 + ESP尾。
-
IP头不在这个计算范围内。
中间人攻击:修改IP头(目的IP 2.2.2.2 → 3.3.3.3)
中间人直接改掉IP头中的目的IP,然后转发。
报文到达3.3.3.3(一个错误的设备),它可能丢弃或错误处理。
真正的B(2.2.2.2)根本收不到。
但是,ESP的ICV验证是在接收方B进行的,既然B没收到,就没人去验证。即使有人验证,验证对象是ESP头+加密数据,IP头被改不影响ICV计算结果——因为IP头不在计算范围里。
结果:ESP完全无法阻止IP头篡改。
二、为什么ESP这样设计?
-
性能与通用性:IP头中的TTL、校验和等字段每经过一跳都会变化,如果ESP把IP头纳入认证范围,这些合法变化也会导致认证失败。所以ESP选择只保护稳定部分(载荷)。
-
NAT穿透:NAT设备需要修改IP头(源IP、端口),如果ESP认证了IP头,NAT后认证必失败。因此ESP故意不保护外层IP头,以便配合NAT-T。
| 协议 | 设计目标 | 是否兼容NAT | 当前状态 |
|---|---|---|---|
| ESP | 加密+可选认证,牺牲IP头保护 | ✅ 是(配合NAT-T) | 主流 |
| AH | 保护IP头+载荷,不加密 | ❌ 否 | 边缘化 |
**************************************************************************************************************
传输模式和隧道模式的使用区分
如果隧道是加密点(防火墙)自己使用,那么使用传输模式,如果是给加密点(防火墙)后面的网络使用,那么使用隧道模式。
-
传输模式:加密点就是通信的源和目的本身。数据包从防火墙发出,目的也是防火墙(或者防火墙是端到端的一环)。此时不需要隐藏IP,因为IP就是防火墙自己的公网地址。
-
隧道模式:加密点只是一个网关,保护的是它后面的网络。源和目的不是防火墙本身,而是内网的主机。此时需要把原始IP包整个加密,再套上新IP头(防火墙的公网地址),从而隐藏内网结构。
一、场景举例:加密点(防火墙)自己使用
例子:两台防火墙之间直接建立IPsec VPN,用于传输防火墙自己的管理流量(比如SNMP、Syslog、BGP邻居等)。
源IP = 防火墙A的公网IP(1.1.1.1)
目的IP = 防火墙B的公网IP(2.2.2.2)
通信双方就是防火墙本身,没有“后面的网络”。
此时用传输模式:
[ IP头(1.1.1.1→2.2.2.2) ] [ ESP头 ] [ 管理数据 ]
不需要加新IP头,因为原IP头已经是公网可路由的,且不需要隐藏。
效率高(少20字节开销)。
二、场景举例:加密点给后面的网络使用
例子:总部防火墙(公网IP 1.1.1.1)与分支防火墙(公网IP 2.2.2.2)建立IPsec VPN,保护总部内网(192.168.1.0/24)和分支内网(192.168.2.0/24)之间的流量。
源IP = 192.168.1.10(总部主机)
目的IP = 192.168.2.10(分支主机)
通信双方是内网主机,防火墙只是加密网关。
此时必须用隧道模式:[ 新IP头(1.1.1.1→2.2.2.2) ] [ ESP头 ] [ 原IP包(192.168.1.10→192.168.2.10) ]
原IP包中的私网地址在公网上不可路由,必须封装进新IP头。
隐藏内网拓扑,私网IP不暴露在公网。
-
“加密点自己使用” → 防火墙是通信的端点 → 传输模式(因为IP头就是真实的通信地址,不需要额外封装)。
-
“加密点给后面的网络使用” → 防火墙是中间网关 → 隧道模式(因为真实通信地址是内网主机,需要被封装保护)。
三、一个容易混淆的补充:GRE over IPsec 中的传输模式
在GRE over IPsec中,GRE隧道已经添加了外层IP头(公网IP到公网IP),此时IPsec用来保护这个GRE包。对于IPsec来说,它保护的源和目的就是GRE包的外层IP头,而这正是两个防火墙的公网IP —— 相当于IPsec是在“防火墙之间”保护,所以可以用传输模式。这也符合老师的规则:加密点(防火墙)自己使用(GRE封装后的包,源目是防火墙自身),所以传输模式。
AH头明明在新IP头后面(内层),为什么能验证新IP头?
报文格式是 [新IP头] [AH头] [原始IP包],AH头明明被夹在中间,怎么去校验它前面的新IP头?这听起来确实违反直觉。
详细步骤(发送方)
构建原始IP包(私网A→私网B)。
在原始IP包前添加AH头(此时AH头的ICV字段暂时填0)。
在AH头前添加新IP头(源=网关1公网,目的=网关2公网,协议=51)。
此时内存中已有完整报文:
[新IP头] [AH头] [原始IP包]。计算ICV:按照RFC定义,将以下数据拼接成一个缓冲区,计算哈希:
新IP头中的不可变字段(源IP、目的IP、协议号等,跳过TTL、校验和等可变字段)
AH头本身(包括下一个头、载荷长度、SPI、序列号等,但ICV字段置0)
整个原始IP包
将计算出的哈希值填入AH头的ICV字段。
发送报文。
详细步骤(接收方)
收到完整报文:
[新IP头] [AH头] [原始IP包]。解析新IP头,知道后面是AH(协议=51)。
根据AH头中的SPI找到SA,获得算法和密钥。
同样拼接以下数据:
新IP头中的不可变字段(按相同规则提取)
AH头(包括SPI、序列号等,但使用报文中的ICV字段?注意:计算哈希时,ICV字段应作为0处理,因为原始ICV不参与计算)
整个原始IP包
计算哈希,与AH头中的ICV对比。
一致则通过,否则丢弃。
为什么AH在NEW IP跟RAW IP之间呢?
无论是传输模式还是隧道模式,也无论是AH还是ESP,第一个字节必须是IP头。这是IP协议的铁律,没有例外。
正确的“最外面”:对于隧道模式,新IP头就是最外面(第一个)。AH头在新IP头后面,但它通过ICV计算可以保护新IP头。这就是设计上看似反直觉但实际可行的原因。

为什么传输模式下ESP也不能穿越NAT
ESP传输模式 vs 隧道模式:穿越NAT的本质区别
核心结论
-
传输模式ESP:无法直接穿越NAT(即使有NAT-T也困难,且不推荐)。
-
隧道模式ESP:配合NAT-T可以完美穿越NAT(实际生产标准做法)。

到底是什么导致传输模式ESP不能穿越NAT,而隧道模式ESP可以?
一、先明确三条不可动摇的“硬约束”
-
TCP校验和依赖IP地址
TCP校验和的计算包括“伪头部”,伪头部中含有源IP和目的IP。这是TCP协议的规定,目的是防止IP地址被篡改后上层协议不知道。 -
NAT修改IP地址后,必须同步更新TCP校验和
否则,接收方计算出的校验和与发送方的不一致,会认为数据损坏而丢弃。NAT必须做这个更新。 -
NAT要更新TCP校验和,必须能读取TCP头(包括校验和字段)
否则无法修改。
二、传输模式ESP的因果链
[1] 原始报文:IP头(源=192.168.1.1,目=8.8.8.8),TCP头(校验和=C1,依赖192.168.1.1和8.8.8.8)
[2] 经过传输模式ESP加密 → TCP头被加密(NAT看不见)
[3] 到达NAT设备:NAT看到IP头源=192.168.1.1 → 必须改为公网IP 1.1.1.1
[4] NAT知道:改了源IP → TCP校验和必须重新计算(因为伪头部变了)
[5] 但是:TCP头被加密 → NAT无法读取,更无法修改校验和
[6] NAT无奈:只改IP头,不改变校验和(因为改不了)→ 转发
[7] 接收方解密后 → 得到IP头(源=1.1.1.1,目=8.8.8.8),TCP校验和仍然是C1(基于旧IP)
[8] 接收方计算校验和(基于1.1.1.1和8.8.8.8)→ 得到C2 ≠ C1 → 丢弃
失败的根本原因:NAT有“更新校验和”的需求,但没有“访问TCP头”的能力(因为加密)。因果关系:需求存在,能力缺失 → 失败。
三、隧道模式ESP的因果链
[1] 原始报文(内层):IP头(源=192.168.1.1,目=192.168.2.1),TCP头(校验和=C3,依赖这两个私网IP)
[2] 经过隧道模式ESP加密 → 整个原始IP包被加密(包括内层IP头和TCP头)
[3] 外层加上新IP头(源=网关1公网1.1.1.1,目=网关2公网2.2.2.2)
[4] 到达NAT设备:NAT看到外层IP头源=1.1.1.1 → 可能改为另一个公网地址(例如1.1.1.100)
[5] NAT思考:我改了外层IP头,但TCP校验和在哪里?它在加密的内层里面。
[6] 关键:内层TCP校验和依赖的是内层IP地址(192.168.1.1和192.168.2.1),与外层IP头无关。
[7] 因此,NAT修改外层IP头,**完全不影响内层TCP校验和的正确性**。NAT不需要修改内层校验和。
[8] NAT只需要修改外层IP头(以及外层IP头校验和)→ 转发
[9] 接收方解密后 → 内层TCP校验和C3依然正确 → 正常处理
成功的根本原因:NAT没有“更新内层TCP校验和”的需求(因为外层IP修改与内层校验和无关)。因果关系:需求不存在 → 无需能力 → 成功。
| 因素 | 传输模式ESP | 隧道模式ESP |
|---|---|---|
| NAT修改了哪个IP? | 原IP头中的源IP(私网→公网) | 外层新IP头中的源IP(公网→公网) |
| TCP校验和依赖哪个IP? | 同一个IP(就是被改的那个) | 内层IP(私网,未被改) |
| NAT修改IP后,TCP校验和会错吗? | 会(因为依赖的被改了) | 不会(因为依赖的没被改) |
| NAT需要更新TCP校验和吗? | 必须 | 不需要 |
| NAT能更新TCP校验和吗? | 不能(TCP头被加密) | 不需要能力 |
| 最终结果 | ❌ 失败 | ✅ 成功(协议号问题另由NAT-T解决) |
更多推荐
所有评论(0)