# VPP IPsec NAT-T 配置手册 ## IPSec NAT-T 原理 ### IPSec 与 N/PAT 的矛盾 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422171836482.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) - AH 传输模式和隧道模式都不支持 N/PAT。 - ESP 传输模式都不支持 N/PAT。 - ESP 隧道模式只支持一对一的 NAT,不支持 PAT。 #### Transport 模式 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422163419321.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) - AH 封装协议的数据完整性校验(Authenticate)范围为整个 IP 报文,NAT 会修改 IP Header 的 Address,所以就会导致接收方 Authenticate 失败。而 PAT 会修改 TCP Header 的 Port,也会导致 Authenticate 失败。 - ESP 封装协议的 Authenticate 范围为 ESP Header 和 ESP Tail(尾部)之间。因为 ESP 不校验 IP Header 所以 NAT 行为并不会导致接收方的 Authenticate 失败,但由于 NAT 修改了 IP Header 中的 Address,理论上后面的 TCP checksum 也会随之修改,而 TCP checksum 已经属于 ESP 校验范围之内了,NAT 设备无法进行修改,所以接收端在 TCP 层接收时会导致 checksum 校验失败。 #### Tunnel 模式 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422164447186.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) - AH 协议的 Tunnel 模式的 Authenticate 范围会包含外层的 New IP Header,因此 NAT 同样会造成接收方 Authenticate 失败。 - ESP 协议的 Tunnel 模式经过 NAT 设备后,内层 IP Header 并不会被改变,所以 TCP checksum 也不会改变,接收方也就不会再出现 checksum 失败了。但也存在着缺点:它只能支持一对一的 NAT,即:NAT 设备后面只有一台内网主机。如果考虑 PAT 来补充的话,又回因为 TCP Header 已经被加密而无法实现。 ### NAT-Tranversal 为了解决上述问题的技术就是 NAT-T,IPSec 的 NAT-T 解决方案是 ESP-UDP-Encapsulate(封装),即:在 ESP Header 前加上一个 New UDP Header,源和目的端口号均是 4500,使得 NAT 设备按照处理一个普通的 UDP 数据包的方式对它处理。这个方法同时适用于 ESP-Transport 和 ESP-Tunnel 模式,以及同时支持 PAT 和 NAT。 - **UDP-Encapsulated-Transport 模式** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422165136646.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) - **UDP-Encapsulated-Tunnel 模式** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422172118847.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) 示例:NAT 设备后有两台内网主机,它们都与 Server 建立 IPSec 连接。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422165429775.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) ### NAT-T 协商过程 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422172234943.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ptaWxr,size_16,color_FFFFFF,t_70) IPSec 两端需要在 IKE 完成协商后才能使用 NAT-T。 **阶段一**: 1. 探测出双方都支持 NAT-T。 2. 探测出双方报文传输路径上存在 NAT 设备。 3. 前 4 个 Msg 都是使用 Sport=Dport=500 进行通信。但当探测到 NAT 设备后,作为 Initiator 再发出第 5 个 Msg 就会将端口切换到 Sport=Dport=4500,Responder 收到该消息后,如果解密成功,后续也会使用新的 4500 端口。注意,RFC3948 规定了 New UDP Header 中的端口要使用和 IKE 协商时相同的端口号,这个端口号在 RFC3947 中规定为 4500。 **阶段二**: 1. 双方协商 NAT-T 的封装模式,UDP-Encapsulated-Tunnel 还是 UDP-Encapsulated-Transport。 2. 其中,UDP-Encapsulated-Transport 模式还会向对方发送自己的原始 IP 地址,让对方可以据此修正后续 TCP 报文的 checksum。要知道,经过 NAT 设备之后,报文的 IP 地址发生了变化,就会导致接收端校验失败。IPsec 采用的方法是在 IKE 协商时,就将自己原始 IP 地址信息发给对端,这样 Server 在解密出 TCP 报文后,可以根据这个信息修正 checksum。 ## VPP IPsec NAT-T 配置示例 目前 VPP 20.09 支持两种 IPSec NAT-T(udp-encap)设置方式: 1. 支持静态配置方式(create ipsec tunnel)的 NAT-T。 2. 支持 IKEv2 自动协商的 NAT-T。 ```bash create ipsec tunnel local-ip local-spi remote-ip remote-spi [instance ] [udp-encap] [tx-table ]. ikev2 profile set udp-encap ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422181848251.png) ```bash # 配置左边 VPP set int ip address GigabitEthernet4/0/2 90.10.30.1/24 set int promiscuous on GigabitEthernet4/0/2 set int ip address GigabitEthernet4/0/3 10.10.10.1/24 set int promiscuous on GigabitEthernet4/0/3 create ipsec tunnel local-ip 10.10.10.1 local-spi 1031 remote-ip 10.10.10.2 remote-spi 1030 udp-encap set interface ipsec key ipsec0 local crypto aes-cbc-128 4339314b55523947594d6d3547666b45 set interface ipsec key ipsec0 remote crypto aes-cbc-128 4339314b55523947594d6d3547666b45 set interface ipsec key ipsec0 local integ sha1-96 4339314b55523947594d6d3547666b45 set interface ipsec key ipsec0 remote integ sha1-96 4339314b55523947594d6d3547666b45 ip route add 90.10.40.0/24 via 10.10.10.2 ipsec0 set interface unnumbered ipsec0 use GigabitEthernet4/0/3 set ip arp GigabitEthernet4/0/3 10.10.10.2 00:0b:ab:f6:b3:66 set ip arp GigabitEthernet4/0/2 90.10.10.100 00:0b:ab:f5:a9:70 ip route add 90.10.10.0/24 via GigabitEthernet4/0/2 set int state GigabitEthernet4/0/2 up set int state GigabitEthernet4/0/3 up set int state ipsec0 up # 配置右边 VPP set int ip address GigabitEthernet4/0/2 90.10.30.2/24 set int promiscuous on GigabitEthernet4/0/2 set int ip address GigabitEthernet4/0/3 10.10.10.2/24 set int promiscuous on GigabitEthernet4/0/3 create ipsec tunnel local-ip 10.10.10.2 local-spi 1030 remote-ip 10.10.10.1 remote-spi 1031 udp-encap set interface ipsec key ipsec0 local crypto aes-cbc-128 4339314b55523947594d6d3547666b45 set interface ipsec key ipsec0 remote crypto aes-cbc-128 4339314b55523947594d6d3547666b45 set interface ipsec key ipsec0 local integ sha1-96 4339314b55523947594d6d3547666b45 set interface ipsec key ipsec0 remote integ sha1-96 4339314b55523947594d6d3547666b45 ip route add 90.10.10.0/24 via 10.10.10.1 ipsec0 set interface unnumbered ipsec0 use GigabitEthernet4/0/3 set ip arp GigabitEthernet4/0/3 10.10.10.1 74:fe:48:09:3c:cb set ip arp GigabitEthernet4/0/2 90.10.40.100 00:0b:ab:f5:a9:71 ip route add 90.10.40.0/24 via ipsec0 GigabitEthernet4/0/2 set int state GigabitEthernet4/0/2 up set int state GigabitEthernet4/0/3 up set int state ipsec0 up ```