IPSec协商阶段使用UDP封装IKE报文,当我们使用较大的证书时,UDP封装的IKE报文(主模式第5、6个包,野蛮模式第1、2个包,IKEv2)可能会出现UDP分片,某些ISP或中间的安全设备可能将IKE分片丢弃,导致IPSec无法协商成功。
对于大多数配置,当中间设备丢弃包含较大证书的IKE分片而导致IPSec协商失败时,开启IKE Fragmentation可以解决此问题。
FortiGate只会在以下条件同时满足的情况下,对IKE报文进行预分片(先分片后封装ISAKMP,保证封装ISAKMP后的IKE报文小于576):
默认情况下,IKE fragmentation功能是开启的。如果关闭该功能,则IPSec不对IKE报文进行分片,IKE报文从物理口发出时,根据物理口MTU进行分片。
config vpn ipsec phase1-interface
edit "ToR2"
**set fragmentation [enable | disable]**
next
end
在IKEv2协商中,RFC7382要求IKEv2每一个分片都必须单独进行加密和验证。
我们需要为每一个发出的IKEv2报文保留一份加密前的IKEv2 Payload。FortiGate只会在以下条件同时满足的情况下,对IKEv2报文进行分片:
config vpn ipsec phase1-interface
edit "ToR2"
set ike-version 2
**set fragmentation enable**
**set fragmentation-mtu [500-16000]**
next
end

R1-FG1101E # show vpn ipsec phase1-interface ToR2
config vpn ipsec phase1-interface
edit "ToR2"
set interface "port16"
s**et authmethod signature**
set peertype any
set passive-mode enable
set proposal aes128-sha256
**set fragmentation enable**
set remote-gw 100.0.3.2
**set certificate "R1-FG1101E_FW1"**
next
end
R2-FG1101E # show vpn ipsec phase1-interface ToR1
config vpn ipsec phase1-interface
edit "ToR1"
set interface "port16"
**set authmethod signature**
set peertype any
set proposal aes128-sha256
**set fragmentation enable**
set remote-gw 100.0.0.2
**set certificate "R2-F1101E_FW2"**
next
end
使用OpenSSL证书服务器为FW1和FW2分别颁发IPSec证书(密钥长度4096 Bits)并导入FW1和FW2(同时导入CA证书),FW1和FW2的IPSec认证使用证书认证(主模式),并引用各自被颁发的证书。
查看FW1和FW2的一阶段状态:
FW1
R1-FG1101E # diagnose vpn ike gateway list
vd: root/0
name: ToR2
version: 1
interface: port16 39
addr: 100.0.0.2:500 -> 100.0.3.2:500
created: 355s ago
peer-id: C = CN, ST = Haidian, L = Beijing, O = TAC, OU = Fortinet, CN = fw2.summerice2019.com, emailAddress = [email protected]
peer-id-auth: yes
IKE SA: created 1/1 established 1/1 time 10/10/10 ms
IPsec SA: created 0/0
id/spi: 269 efdc3e0b977466ff/bd316a8dff131e02
direction: initiator
status: established 355-355s ago = 10ms
proposal: aes128-sha256
key: 6fb1d2a827b06bfe-61e30fcf2684a052
lifetime/rekey: 86400/85744
DPD sent/recv: 00000000/00000000
peer-id: C = CN, ST = Haidian, L = Beijing, O = TAC, OU = Fortinet, CN = fw2.summerice2019.com, emailAddress = [email protected]
FW2
R2-FG1101E # diagnose vpn ike gateway list
vd: root/0
name: ToR1
version: 1
interface: port16 39
addr: 100.0.3.2:500 -> 100.0.0.2:500
created: 3556s ago
peer-id: C = CN, ST = Haidian, L = Beijing, O = TAC, OU = Fortinet, CN = R1-FG1101E.summerice2019.com, emailAddress = [email protected]
peer-id-auth: yes
IKE SA: created 1/1 established 1/1 time 10/10/10 ms
IPsec SA: created 1/1 established 1/1 time 0/0/0 ms
id/spi: 69 efdc3e0b977466ff/bd316a8dff131e02
direction: responder
status: established 3556-3556s ago = 10ms
proposal: aes128-sha256
key: 6fb1d2a827b06bfe-61e30fcf2684a052
lifetime/rekey: 86400/82573
DPD sent/recv: 00000000/00000000
peer-id: C = CN, ST = Haidian, L = Beijing, O = TAC, OU = Fortinet, CN = R1-FG1101E.summerice2019.com, emailAddress = [email protected]
在中间设备Router上抓取FW1和FW2的ISAKMP协商报文。
格式4抓包,可以看到主模式的第5、6个包(包含证书)根据FW1、FW2出接口的MTU=1500被分别分成了3片,总大小(不含IP头长度)1480 + 1480 + 436 = 3396 Bytes、1480 + 1480 + 388 = 3348 Bytes:
RACK1-FG601E # diagnose sniffer packet any 'host 100.0.3.2' 4
interfaces=[any]
filters=[host 100.0.3.2]
49.437037 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 332
49.437042 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 332
49.437145 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 192
49.437148 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 192
49.437241 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 508
49.437243 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 508
49.437327 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 513
49.437329 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 513
49.444845 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 3388 (frag 24504:**1480**@0+)
49.444858 port7 in 100.0.0.2 -> 100.0.3.2: ip-proto-17 (frag 24504:**1480**@1480+)
49.444860 port7 in 100.0.0.2 -> 100.0.3.2: ip-proto-17 (frag 24504:**436**@2960)
49.444867 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 3388 (frag 24504:1480@0+)
49.444869 port8 out 100.0.0.2 -> 100.0.3.2: ip-proto-17 (frag 24504:1480@1480+)
49.444872 port8 out 100.0.0.2 -> 100.0.3.2: ip-proto-17 (frag 24504:436@2960)
49.451532 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 3340 (frag 42137:**1480**@0+)
49.451545 port8 in 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42137:**1480**@1480+)
49.451546 port8 in 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42137:**388**@2960)
49.451551 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 3340 (frag 42137:1480@0+)
49.451553 port7 out 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42137:1480@1480+)
49.451555 port7 out 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42137:388@2960)
格式6抓包,可以看到FW1先执行了IKE封装,再根据出接口的MTU=1500执行了IP分片:

原始报文文件:
在中间设备Router的port7(针对FW1到FW2的方向)下开启丢弃分片包功能,这样可以导致FW1发送主模式的第5个包被丢弃,进入重传状态,进而触发FW1的IKE Fragmentation:
config system interface
edit "port7"
**set drop-fragment enable**
next
end
在中间设备Router上抓取FW1和FW2的ISAKMP协商报文:
格式4抓包,可以看到FW1发出的主模式的第5个包(包含证书)根据FW1出接口的MTU=1500被分别分成了3片,总大小(不含IP Header)1480 + 1480 + 436 = 3396 Bytes,由于Router的port7开启了分片丢包,这三个片未被转发到port8。FW1的IKE协商进入重传状态,触发IKE Fragmentation,按照Internet MTU=576对第5个包进行预分片(先分片,再封装ISAKMP Header,抓包这里显示的UDP长度544和376不包含IP Header和UDP Header),总长度(不含IP Header)544 * 6 + 376 + 8(UDP Header) * 7 = 3696。
RACK1-FG601E # diagnose sniffer packet any 'host 100.0.3.2' 4
interfaces=[any]
filters=[host 100.0.3.2]
19.622150 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 332
19.622157 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 332
19.622252 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 192
19.623133 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 192
19.623227 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 508
19.623230 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 508
19.623306 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 513
19.623308 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 513
19.630961 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 3388 (frag 24507:**1480**@0+)
19.630973 port7 in 100.0.0.2 -> 100.0.3.2: ip-proto-17 (frag 24507:**1480**@1480+)
19.630975 port7 in 100.0.0.2 -> 100.0.3.2: ip-proto-17 (frag 24507:**436**@2960)
22.617820 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 513
22.617824 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 513
**22.617908 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617911 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617913 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617915 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617918 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617920 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617922 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617924 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617929 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617931 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617933 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617935 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 544
22.617936 port7 in 100.0.0.2.500 -> 100.0.3.2.500: udp 376
22.617938 port8 out 100.0.0.2.500 -> 100.0.3.2.500: udp 376**
22.624409 port8 in 100.0.3.2.500 -> 100.0.0.2.500: udp 3340 (frag 42163:1480@0+)
22.624420 port8 in 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42163:1480@1480+)
22.624422 port8 in 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42163:388@2960)
22.624428 port7 out 100.0.3.2.500 -> 100.0.0.2.500: udp 3340 (frag 42163:1480@0+)
22.624430 port7 out 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42163:1480@1480+)
22.624433 port7 out 100.0.3.2 -> 100.0.0.2: ip-proto-17 (frag 42163:388@2960)
<aside> 💡 FW2到FW1的方向没有丢弃分片包的动作,所以FW2发给FW1的IKE报文仍然按照原始分片方式,先封装IKE,再根据出接口MTU进行IP分片。证明此功能不需要协商,单方向生效。
</aside>
格式6抓包,可以看到IKE Fragmentation执行的是先分片后封装IKE,每个包都是有ISAKMP封装的,且包含Fragmentation的Payload,标识此IKE报文的序列,以便接收方重组:

<aside> 💡
未触发IKE Fragmentation前的原始Data长度为3396 - 8(UDP Header) - 16(SPI) - 1(Next Payload) - 1(Version) - 1(Exchange Type) - 1(Flags) - 4(Message ID) - 4(Length) = 3360 Bytes,IKE Fragmentation后的原始Data长度为3696 - 44(Fragmentation Payload 1~6) * 6 - 72(Fragmentation Payload 7) = 3360 Bytes,两者原始Data长度一致。
</aside>
原始报文文件:
IKE debug信息中可以看到进入了重传模式后触发了IKE Fragmentation:
ike 0:ToR2:275: **retransmission, re-send last message**
ike 0:ToR2:275: **fragment on 544 byte boundary**
ike 0:ToR2:275: send fragment len 544 id 1 index 1 last 0
ike 0:ToR2:275: sent IKE msg (retransmit): 100.0.0.2:500->100.0.3.2:500, len=544, id=4747dd36d159b27b/928cbb1951a80e00
ike 0:ToR2:275: send fragment len 544 id 1 index 2 last 0
ike 0:ToR2:275: sent IKE msg (retransmit): 100.0.0.2:500->100.0.3.2:500, len=544, id=4747dd36d159b27b/928cbb1951a80e00
ike 0:ToR2:275: send fragment len 544 id 1 index 3 last 0
ike 0:ToR2:275: sent IKE msg (retransmit): 100.0.0.2:500->100.0.3.2:500, len=544, id=4747dd36d159b27b/928cbb1951a80e00
ike 0:ToR2:275: send fragment len 544 id 1 index 4 last 0
ike 0:ToR2:275: sent IKE msg (retransmit): 100.0.0.2:500->100.0.3.2:500, len=544, id=4747dd36d159b27b/928cbb1951a80e00
ike 0:ToR2:275: send fragment len 544 id 1 index 5 last 0
ike 0:ToR2:275: sent IKE msg (retransmit): 100.0.0.2:500->100.0.3.2:500, len=544, id=4747dd36d159b27b/928cbb1951a80e00
ike 0:ToR2:275: send fragment len 544 id 1 index 6 last 0
ike 0:ToR2:275: sent IKE msg (retransmit): 100.0.0.2:500->100.0.3.2:500, len=544, id=4747dd36d159b27b/928cbb1951a80e00
ike 0:ToR2:275: send fragment len 376 id 1 index 7 last 1
查看连接一阶段建立状态,连接正常建立。
R1-FG1101E # diagnose vpn ike gateway list
vd: root/0
name: ToR2
version: 1
interface: port16 39
addr: 100.0.0.2:500 -> 100.0.3.2:500
created: 19s ago
peer-id: C = CN, ST = Haidian, L = Beijing, O = TAC, OU = Fortinet, CN = fw2.summerice2019.com, emailAddress = [email protected]
peer-id-auth: yes
IKE SA: created 1/1 established 1/1 time 3000/3000/3000 ms
IPsec SA: created 0/0
id/spi: 272 4747dd36d159b27b/928cbb1951a80e00
direction: initiator
status: established 19-16s ago = 3000ms
proposal: aes128-sha256
key: fbccacf66b8f53ff-45734e851fbe3742
lifetime/rekey: 86400/86083
DPD sent/recv: 00000000/00000000
peer-id: C = CN, ST = Haidian, L = Beijing, O = TAC, OU = Fortinet, CN = fw2.summerice2019.com, emailAddress = [email protected]
野蛮模式和IKEv2的测试略过,大家可以自行测试,看看是否符合这里的说明。