一、组网需求
如图所示,某公司总部内部有一台OA服务器,其余分2个支机构都需要通过vpn拨入总部内网对OA服务器进行访问,为了方便配置,总部不想有太多的配置,总部只建立一条vpn隧道,实现所有分支机构和总部的通讯。
二、网络拓扑

HUB和SPOKE之间通过IPsec VPN通信:
SPOKE和SPOKE之间通过IPsec VPN通信:

三、配置要点
1、配置FortiGate1 (BJ)---HUB--- FortiGate1-HQ-BJ
1)基本上网配置
2)HUB端的IPsec VPN配置
3)HUB端的VPN策略和路由配置
2、配置FortiGate2 (SH)---SPOKE--- FortiGate2-Branch-SH
1)基本上网配置
2)SOPKE端(FortiGate2-Branch-SH)的IPsec VPN配置
3)SPOKE端(FortiGate2-Branch-SH)的VPN策略和路由配置
3、配置FortiGate3(GZ)---SPOKE--- FortiGate3-Branch-GZ
1)基本上网配置
2)SOPKE端(FortiGate3-Branch-GZ)的IPsec VPN配置
3)SPOKE端(FortiGate3-Branch-GZ)的VPN策略和路由配置
4、如果继续增加SPOKE,可以使用脚本完成新SPOKE的VPN部署
说明:如果要删除IPSEC VPN第一阶段、第二阶段时,需要先删除被调用的路由或防火墙安全策略。
四、配置步骤
1、配置FortiGate1 (BJ)---HUB--- FortiGate1-HQ-BJ
1) 基本上网配置
配置详细过程请参照 "路由模式典型功能--单线上网--静态地址线路上网配置"一节:
接口IP配置如下:
路由配置如下
2)HUB端的IPsec VPN配置
进入:虚拟专网--IPSEC隧道--"新建"
根据自定义模板进行相应的IPsec VPN配置:


总部(HUB)IPsec VPN配置说明:
1.HUB使用动态拨号的VPN方式。
因为分支可能来自任意地方的IP,另外分支可能使用PPPOE拨号,公网IP随时会变更,因此你没有办法确认对方的公网IP,只能动态拨号方式的IPsec VPN。
2.HUB使用主模式。
其实使用主模式或野蛮模式二者都是可以的,如果只有一条动态拨号的IPsec VPN,不存在多条动态IPsec VPN的情况下(因为动态VPN的目的IP为0.0.0.0,存在多条动态的IPsec VPN会导致冲突,必须使用Peer ID来区分彼此),可以简单的直接使用主模式,接收Peer ID为any即可,当然使用野蛮模式的接受任意的Peer ID 也是OK的,只要hub和spoke之间使用相同的模式即可,双方通过预共享密钥来认证对方的身份。综上,一条动态拨号VPN的场景下我们HUB选择最简单的主动模式+任意Peer ID+预共享密钥。这种选择优势是在SPOKE看来感觉就像是建立一个很普通的LAN-TO-LAN的IPsec VPN,因为不会涉及到任何的模式选择/ID选择和配置,对于SPOKE来说相对比较友好和好理解一些。
3.HUB第二阶段感兴趣流保持默认的0.0.0.0/0.0.0.0 <--> 0.0.0.0/0.0.0.0。
由于HUB是被动的接受SPOKE的协商,在没有协商之前你不可能知道SPOKE的具体网段/感兴趣流,其实HUB都不知道谁要来连接自己(目的IP为0.0.0.0),同理HUB也没有办法配置明细的感兴趣流,只能被动的接收SPOKE的感兴趣流,HUB保持默认0.0.0.0/0.0.0.0 <--> 0.0.0.0/0.0.0.0的感兴趣流,会产生这样这样一个效果:自动学习分支的感兴趣流,同时自动产生反向的去往感兴趣流的回程静态路由。当然如果HUB一定要填写明细的感兴趣流,可以吗?答案是可以的,只是这样很麻烦,每增加一个分支都要在HUB这端设置相应的第二阶段感兴趣流,这样非常的麻烦,需要频繁的修改HUB端的配置,而感兴趣流保持默认的0.0.0.0/0.0.0.0 <--> 0.0.0.0/0.0.0.0的好处就是:HUB只需要配置一次即可,SPOKE增加多少个HUB这端都不需要再修改IPsec VPN的配置了,动态拨号的IPsec VPN会自动学习分支的感兴趣流和自动生成去往分支感兴趣流的回程路由。此时我们反过来去思考,就可以得知SPOKE端是一定需要配置明细的感兴趣流的,SPOKE一定不能配置成0.0.0.0/0.0.0.0,否则HUB端就无法通过自动学习而得知SPOKE端的内网网段(感兴趣流),这样VPN业务就没有办法通信了。
3)HUB端的VPN策略和路由配置
VPN策略配置:
分支到总部之间的策略放通:
总部到分支之间的策略放通:
分支和分支之间的策略放通:

VPN路由配置:HUB 端路由自动学习并生成去往SPOKE感兴趣流的回程路由,因此无需再配置去往SPOKE的路由。
附:HUB端命令行
config vpn ipsec phase1-interface edit "hub-dia" set type dynamic set interface "port1" set peertype any set proposal des-md5 des-sha1 set dpd on-idle set psksecret Fortinet123# set dpd-retryinterval 60 nextendconfig vpn ipsec phase2-interface edit "hub-dia" set phase1name "hub-dia" set proposal des-md5 des-sha1 set keepalive enable nextendconfig firewall policy edit 2 set name "SPOKE-TO-HUB-Policy" set srcintf "hub-dia" set dstintf "port2" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable next edit 3 set name "HUB-TO-SPOKE-Policy" set srcintf "port2" set dstintf "hub-dia" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable next edit 4 set name "SPOKE-TO-SPOKE-Policy" set srcintf "hub-dia" set dstintf "hub-dia" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable next
end
----FortiGate1(BJ)的配置全部完成----
2、配置FortiGate2 (SH)---SPOKE--- FortiGate2-Branch-SH
1) 基本上网配置
接口IP配置如下:
路由通过DHCP自动获取到默认路由:

2)SPOKE端(FortiGate2-Branch-SH)的IPsec VPN配置
进入:虚拟专网--IPSEC隧道--"新建"
根据自定义模板进行相应的IPsec VPN配置:
分支(SPOKE)IPsec VPN配置说明:
1.第一阶段和第二阶段的参数和HUB保持一致。加密算法、预共享密钥、模式等一定要保持一致。
2.SPOKE的第二阶段感兴趣流一定要填写明细感兴趣流,将自己的业务网段告知HUB,以便HUB可以动态学习到SPOKE这端的业务网段感兴趣流和路由。
SPOKE的感兴趣流可以写成 192.168.1.0/24 <---> 192.168.0.0/16 的汇总感兴趣流(HUB和其他SPOKE的业务网段汇总为192.168.0.0/16),或者简单的使用192.168.1.0/24 <---> 0.0.0.0/0都可以。实际什么样的流量走IPsec VPN隧道是通过路由决定的,因此目的网段写成192.168.0.0/16和0.0.0.0/0.0.0.0在第二阶段中并不重要,都是可以的。
2)SPOKE端(FortiGate2-Branch-SH)的VPN策略和路由配置
VPN策略配置:


VPN路由配置:
附:SPOKE(SH)端命令行
config vpn ipsec phase1-interface edit "to-hub-a-sopke" set interface "port1" set peertype any set proposal des-md5 des-sha1 set dpd on-idle set remote-gw 100.1.1.1 set psksecret Fortinet123# nextendconfig vpn ipsec phase2-interface edit "to-hub-a-sopke" set phase1name "to-hub-a-sopke" set proposal des-md5 des-sha1 set auto-negotiate enable set src-subnet 192.168.1.0 255.255.255.0 nextendconfig firewall policy edit 2 set name "LOACL-TO-HUB-and-SPOKE" set srcintf "port2" set dstintf "to-hub-a-sopke" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable next edit 3 set name "HUB-and-SPOKE-TO-LOCAL" set srcintf "to-hub-a-sopke" set dstintf "port2" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable nextendconfig router static edit 1 set dst 192.168.0.0 255.255.0.0 set device "to-hub-a-sopke" next edit 2 set dst 192.168.0.0 255.255.0.0 set distance 254 set blackhole enable next
----FortiGate2(SH)的配置全部完成----
3、配置FortiGate3 (GZ)---SPOKE--- FortiGate3-Branch-GZ
1) 基本上网配置
接口IP配置如下:
路由通过PPPOE自动获取到默认路由:

2)SPOKE端(FortiGate3-Branch-GZ)的IPsec VPN配置
进入:虚拟专网--IPSEC隧道--"新建"
根据自定义模板进行相应的IPsec VPN配置:
分支(SPOKE)IPsec VPN配置说明:
1.第一阶段和第二阶段的参数和HUB保持一致。加密算法、预共享密钥、模式等一定要保持一致。
2.SPOKE的第二阶段感兴趣流一定要填写明细感兴趣流,将自己的业务网段告知HUB,以便HUB可以动态学习到SPOKE这端的业务网段感兴趣流和路由。
SPOKE的感兴趣流可以写成 192.168.2.0/24 <---> 192.168.0.0/16 的汇总感兴趣流(HUB和其他SPOKE的业务网段汇总为192.168.0.0/16),或者简单的使用192.168.2.0/24 <---> 0.0.0.0/0都可以。实际什么样的流量走IPsec VPN隧道是通过路由决定的,因此目的网段写成192.168.0.0/16和0.0.0.0/0.0.0.0在第二阶段中并不重要,都是可以的。
2)SPOKE端(FortiGate3-Branch-GZ)的VPN策略和路由配置
VPN策略配置:


VPN路由配置:
附:SPOKE(GZ)端命令行
config vpn ipsec phase1-interface edit "to-hub-a-sopke" set interface "port1" set peertype any set proposal des-md5 des-sha1 set dpd on-idle set remote-gw 100.1.1.1 set psksecret Fortinet123# nextendconfig vpn ipsec phase2-interface edit "to-hub-a-sopke" set phase1name "to-hub-a-sopke" set proposal des-md5 des-sha1 set auto-negotiate enable set src-subnet 192.168.2.0 255.255.255.0 nextendconfig firewall policy edit 2 set name "LOACL-TO-HUB-and-SPOKE" set srcintf "port2" set dstintf "to-hub-a-sopke" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable next edit 3 set name "HUB-and-SPOKE-TO-LOCAL" set srcintf "to-hub-a-sopke" set dstintf "port2" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable nextendconfig router static edit 1 set dst 192.168.0.0 255.255.0.0 set device "to-hub-a-sopke" next edit 2 set dst 192.168.0.0 255.255.0.0 set distance 254 set blackhole enable next
----FortiGate3(GZ)的配置全部完成----
4、如果继续增加SPOKE,可以使用脚本完成新SPOKE的VPN部署
通过上述的配置可以看出,HUB端的配置完全是固定的,新增SPOKE无需进行任何的配置添加和修改,而SPOKE侧的VPN非常的相似,唯一需要修改的地方就是第二阶段中感兴趣流的本地IP网段,修改成新增SPOKE的本地网段即可,如果SPOKE使用的设备型号和接线方式都一致的话,完全可以使用脚本的方式完成HUB-and-SPOKE的配置。
具体命令行配置脚本如下:
-------------------------------------------
config vpn ipsec phase1-interface edit "to-hub-a-sopke" set interface "port1" set peertype any set proposal des-md5 des-sha1 set dpd on-idle set remote-gw 100.1.1.1 set psksecret Fortinet123# nextendconfig vpn ipsec phase2-interface edit "to-hub-a-sopke" set phase1name "to-hub-a-sopke" set proposal des-md5 des-sha1 set auto-negotiate enable set src-subnet 192.168.X.0 255.255.255.0 ---- 脚本中唯一需要修改的地方,将此src-subnet修改成本地的网段即可。 nextendconfig firewall policy edit 0 set name "LOACL-TO-HUB-and-SPOKE" set srcintf "port2" set dstintf "to-hub-a-sopke" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable next edit 0 set name "HUB-and-SPOKE-TO-LOCAL" set srcintf "to-hub-a-sopke" set dstintf "port2" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set fsso disable nextendconfig router static edit 0 set dst 192.168.0.0 255.255.0.0 set device "to-hub-a-sopke" next edit 0 set dst 192.168.0.0 255.255.0.0 set distance 254 set blackhole enable nextend -------------------------------------------
五、检查配置结果
VPN状态以及业务测试:
查看VPN监视器,观察状态: 进入"监视器"--"IPsec监视器"
HUB 侧IPsec VPN状态监测
SPOKE侧IPsec VPN状态监测:
查看路由监视器,观察路由状态: 进入"监视器"--"路由监视器"
HUB 侧VPN路由状态监测
SPOKE 侧VPN路由状态监测
业务测试:
HUB(BJ)端业务测试:
FortiGate1-HQ-BJ # execute ping-options source 192.168.0.99
FortiGate1-HQ-BJ # execute ping 192.168.1.99 // BJ 去 SHPING 192.168.1.99 (192.168.1.99): 56 data bytes64 bytes from 192.168.1.99: icmp_seq=0 ttl=255 time=3.0 ms64 bytes from 192.168.1.99: icmp_seq=1 ttl=255 time=1.3 ms64 bytes from 192.168.1.99: icmp_seq=2 ttl=255 time=1.6 ms64 bytes from 192.168.1.99: icmp_seq=3 ttl=255 time=1.3 ms64 bytes from 192.168.1.99: icmp_seq=4 ttl=255 time=1.1 ms
--- 192.168.1.99 ping statistics ---5 packets transmitted, 5 packets received, 0% packet lossround-trip min/avg/max = 1.1/1.6/3.0 ms
FortiGate1-HQ-BJ # execute ping 192.168.2.99 // BJ 去 GZPING 192.168.2.99 (192.168.2.99): 56 data bytes64 bytes from 192.168.2.99: icmp_seq=0 ttl=255 time=2.2 ms64 bytes from 192.168.2.99: icmp_seq=1 ttl=255 time=1.3 ms64 bytes from 192.168.2.99: icmp_seq=2 ttl=255 time=0.9 ms64 bytes from 192.168.2.99: icmp_seq=3 ttl=255 time=1.2 ms64 bytes from 192.168.2.99: icmp_seq=4 ttl=255 time=1.1 ms
--- 192.168.2.99 ping statistics ---5 packets transmitted, 5 packets received, 0% packet lossround-trip min/avg/max = 0.9/1.3/2.2 ms
FortiGate1-HQ-BJ #
FortiGate2-Branch-SH # execute ping-options source 192.168.1.99
FortiGate2-Branch-SH # execute ping 192.168.0.99 //SH 去 BJ PING 192.168.0.99 (192.168.0.99): 56 data bytes64 bytes from 192.168.0.99: icmp_seq=0 ttl=255 time=1.1 ms64 bytes from 192.168.0.99: icmp_seq=1 ttl=255 time=1.1 ms64 bytes from 192.168.0.99: icmp_seq=2 ttl=255 time=1.1 ms64 bytes from 192.168.0.99: icmp_seq=3 ttl=255 time=1.0 ms64 bytes from 192.168.0.99: icmp_seq=4 ttl=255 time=1.1 ms
--- 192.168.0.99 ping statistics ---5 packets transmitted, 5 packets received, 0% packet lossround-trip min/avg/max = 1.0/1.0/1.1 ms
FortiGate2-Branch-SH # execute ping 192.168.2.99 // SH 去 GZPING 192.168.2.99 (192.168.2.99): 56 data bytes64 bytes from 192.168.2.99: icmp_seq=0 ttl=254 time=2.5 ms64 bytes from 192.168.2.99: icmp_seq=1 ttl=254 time=2.3 ms64 bytes from 192.168.2.99: icmp_seq=2 ttl=254 time=2.0 ms64 bytes from 192.168.2.99: icmp_seq=3 ttl=254 time=2.0 ms64 bytes from 192.168.2.99: icmp_seq=4 ttl=254 time=2.0 ms
--- 192.168.2.99 ping statistics ---5 packets transmitted, 5 packets received, 0% packet lossround-trip min/avg/max = 2.0/2.1/2.5 ms
FortiGate2-Branch-SH #
FortiGate3-Branch-GZ # execute ping-options source 192.168.2.99
FortiGate3-Branch-GZ # execute ping 192.168.0.99 // GZ 去 BJ PING 192.168.0.99 (192.168.0.99): 56 data bytes64 bytes from 192.168.0.99: icmp_seq=0 ttl=255 time=0.9 ms64 bytes from 192.168.0.99: icmp_seq=1 ttl=255 time=1.4 ms64 bytes from 192.168.0.99: icmp_seq=2 ttl=255 time=1.2 ms64 bytes from 192.168.0.99: icmp_seq=3 ttl=255 time=1.3 ms64 bytes from 192.168.0.99: icmp_seq=4 ttl=255 time=1.2 ms
--- 192.168.0.99 ping statistics ---5 packets transmitted, 5 packets received, 0% packet lossround-trip min/avg/max = 0.9/1.2/1.4 ms
FortiGate3-Branch-GZ # execute ping 192.168.1.99 // GZ 去 SHPING 192.168.1.99 (192.168.1.99): 56 data bytes64 bytes from 192.168.1.99: icmp_seq=0 ttl=254 time=2.4 ms64 bytes from 192.168.1.99: icmp_seq=1 ttl=254 time=3.0 ms64 bytes from 192.168.1.99: icmp_seq=2 ttl=254 time=2.1 ms64 bytes from 192.168.1.99: icmp_seq=3 ttl=254 time=2.0 ms64 bytes from 192.168.1.99: icmp_seq=4 ttl=254 time=2.1 ms
--- 192.168.1.99 ping statistics ---5 packets transmitted, 5 packets received, 0% packet lossround-trip min/avg/max = 2.0/2.3/3.0 ms
FortiGate3-Branch-GZ #
HUB 侧VPN状态和业务数据抓包:
FortiGate1-HQ-BJ # diagnose vpn ike gateway list
vd: root/0name: hub-dia_0version: 1interface: port1 3addr: 100.1.1.1:500 -> 101.1.1.1:500created: 58421s agoIKE SA: created 1/1 established 1/1 time 0/0/0 msIPsec SA: created 1/2 established 1/2 time 0/5/10 ms
id/spi: 2 2d99b672c529e745/ec81d8ac88f8dd4d direction: responder status: established 58421-58421s ago = 0ms proposal: des-md5 key: 3c62b457c5a04950 lifetime/rekey: 86400/27708 DPD sent/recv: 00000000/00000b5c
vd: root/0name: hub-dia_1version: 1interface: port1 3addr: 100.1.1.1:500 -> 102.1.1.1:500created: 57299s agoIKE SA: created 1/1 established 1/1 time 10/10/10 msIPsec SA: created 1/2 established 1/2 time 10/10/10 ms
id/spi: 3 0a16849bbd982817/52d3b2cd6acfca7b direction: responder status: established 57299-57299s ago = 10ms proposal: des-md5 key: 1298e6453e186a52 lifetime/rekey: 86400/28830 DPD sent/recv: 00000001/00000b27
FortiGate1-HQ-BJ # diagnose vpn tunnel listlist all ipsec tunnel in vd 0------------------------------------------------------name=hub-dia_0 ver=1 serial=5 100.1.1.1:0->101.1.1.1:0bound_if=3 lgwy=static/1 tun=intf/0 mode=dial_inst/3 encap=none/128 options[0080]=rgwy-chgparent=hub-dia index=0proxyid_num=1 child_num=0 refcnt=5 ilast=4 olast=4 ad=/0stat: rxp=79 txp=59 rxb=10744 txb=4956dpd: mode=on-idle on=1 idle=60000ms retry=3 count=0 seqno=0natt: mode=none draft=0 interval=0 remote_port=0proxyid=hub-dia proto=0 sa=1 ref=2 serial=1 add-route src: 0:0.0.0.0-255.255.255.255:0 dst: 0:192.168.1.0-192.168.1.255:0 SA: ref=3 options=2a7 type=00 soft=0 mtu=1446 expire=27662/0B replaywin=2048 seqno=23 esn=0 replaywin_lastseq=00000023 itn=0 life: type=01 bytes=0/0 timeout=43185/43200 dec: spi=6f614c07 esp=des key=8 095fd4d98f2c8950 ah=md5 key=16 7501ad23addbd1a761129ab6546f031e enc: spi=329a5865 esp=des key=8 b54ba456cc0c22d1 ah=md5 key=16 eea3a1d6b295a646b58d88f6b317d471 dec:pkts/bytes=34/2856, enc:pkts/bytes=34/4624------------------------------------------------------name=hub-dia_1 ver=1 serial=6 100.1.1.1:0->102.1.1.1:0bound_if=3 lgwy=static/1 tun=intf/0 mode=dial_inst/3 encap=none/128 options[0080]=rgwy-chgparent=hub-dia index=1proxyid_num=1 child_num=0 refcnt=5 ilast=4 olast=4 ad=/0stat: rxp=53 txp=73 rxb=7208 txb=6132dpd: mode=on-idle on=1 idle=60000ms retry=3 count=0 seqno=1natt: mode=none draft=0 interval=0 remote_port=0proxyid=hub-dia proto=0 sa=1 ref=2 serial=1 add-route src: 0:0.0.0.0-255.255.255.255:0 dst: 0:192.168.2.0-192.168.2.255:0 SA: ref=3 options=2a7 type=00 soft=0 mtu=1446 expire=28667/0B replaywin=2048 seqno=25 esn=0 replaywin_lastseq=00000025 itn=0 life: type=01 bytes=0/0 timeout=43185/43200 dec: spi=6f614c08 esp=des key=8 02c0cd8319ed772a ah=md5 key=16 eb8a38c38402e6a2c1454c73745c953c enc: spi=0fc6fa09 esp=des key=8 654fd6e3e1435257 ah=md5 key=16 2261040fab02e5c10557380dfdf30154 dec:pkts/bytes=36/3024, enc:pkts/bytes=36/4896------------------------------------------------------name=hub-dia ver=1 serial=2 100.1.1.1:0->0.0.0.0:0bound_if=3 lgwy=static/1 tun=intf/0 mode=dialup/2 encap=none/0proxyid_num=0 child_num=2 refcnt=18 ilast=59527 olast=59527 ad=/0stat: rxp=0 txp=0 rxb=0 txb=0dpd: mode=on-idle on=0 idle=60000ms retry=3 count=0 seqno=0natt: mode=none draft=0 interval=0 remote_port=0run_tally=2ipv4 route tree:192.168.1.0->192.168.1.255 0192.168.2.0->192.168.2.255 1
FortiGate1-HQ-BJ # get router info routing-table all
Routing table for VRF=0Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area * - candidate default
S* 0.0.0.0/0 [10/0] via 100.1.1.254, port1C 100.1.1.0/24 is directly connected, port1C 192.168.0.0/24 is directly connected, port2S 192.168.1.0/24 [15/0] via 101.1.1.1, hub-diaS 192.168.2.0/24 [15/0] via 102.1.1.1, hub-dia
FortiGate1-HQ-BJ # diagnose vpn ipsec statusAll ipsec crypto devices in use:SOFTWARE: Encryption (encrypted/decrypted) null : 0 0 des : 147 147 3des : 0 0 aes : 0 0 aes-gcm : 0 0 aria : 0 0 seed : 0 0 chacha20poly1305 : 0 0 Integrity (generated/validated) null : 0 0 md5 : 147 147 sha1 : 0 0 sha256 : 0 0 sha384 : 0 0 sha512 : 0 0
SPOKE(SH) 到 HUB(BJ) 的业务数据抓包:FortiGate1-HQ-BJ # diagnose sniffer packet any "icmp or esp" 4interfaces=[any]filters=[icmp or esp]5.878295 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x2e)5.878322 hub-dia in 192.168.1.100 -> 192.168.0.100: icmp: echo request5.878809 port2 out 192.168.1.100 -> 192.168.0.100: icmp: echo request
5.879292 port2 in 192.168.0.100 -> 192.168.1.100: icmp: echo reply5.879314 hub-dia out 192.168.0.100 -> 192.168.1.100: icmp: echo reply5.879332 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x2e)
6.881606 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x2f)6.881634 hub-dia in 192.168.1.100 -> 192.168.0.100: icmp: echo request6.881701 port2 out 192.168.1.100 -> 192.168.0.100: icmp: echo request
6.882236 port2 in 192.168.0.100 -> 192.168.1.100: icmp: echo reply6.882254 hub-dia out 192.168.0.100 -> 192.168.1.100: icmp: echo reply6.882273 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x2f)
7.883951 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x30)7.883980 hub-dia in 192.168.1.100 -> 192.168.0.100: icmp: echo request7.884032 port2 out 192.168.1.100 -> 192.168.0.100: icmp: echo request
7.884717 port2 in 192.168.0.100 -> 192.168.1.100: icmp: echo reply7.884739 hub-dia out 192.168.0.100 -> 192.168.1.100: icmp: echo reply7.884759 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x30)
8.887554 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x31)8.887582 hub-dia in 192.168.1.100 -> 192.168.0.100: icmp: echo request8.887646 port2 out 192.168.1.100 -> 192.168.0.100: icmp: echo request
8.888030 port2 in 192.168.0.100 -> 192.168.1.100: icmp: echo reply8.888051 hub-dia out 192.168.0.100 -> 192.168.1.100: icmp: echo reply8.888070 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x31)
9.889790 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x32)9.889811 hub-dia in 192.168.1.100 -> 192.168.0.100: icmp: echo request9.889850 port2 out 192.168.1.100 -> 192.168.0.100: icmp: echo request
9.890303 port2 in 192.168.0.100 -> 192.168.1.100: icmp: echo reply9.890320 hub-dia out 192.168.0.100 -> 192.168.1.100: icmp: echo reply9.890339 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x32)
SPOKE(SH) 到 SPOKE(GZ) 的业务数据抓包:FortiGate1-HQ-BJ # diagnose sniffer packet any "icmp or esp" 4interfaces=[any]filters=[icmp or esp]10.843923 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x29)10.843952 hub-dia in 192.168.1.100 -> 192.168.2.100: icmp: echo request10.844085 hub-dia out 192.168.1.100 -> 192.168.2.100: icmp: echo request10.844105 port1 out 100.1.1.1 -> 102.1.1.1: ESP(spi=0x0fc6fa09,seq=0x30)
10.845924 port1 in 102.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c08,seq=0x30)10.845939 hub-dia in 192.168.2.100 -> 192.168.1.100: icmp: echo reply10.845956 hub-dia out 192.168.2.100 -> 192.168.1.100: icmp: echo reply10.845969 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x29)
11.848076 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x2a)11.848105 hub-dia in 192.168.1.100 -> 192.168.2.100: icmp: echo request11.848155 hub-dia out 192.168.1.100 -> 192.168.2.100: icmp: echo request11.848180 port1 out 100.1.1.1 -> 102.1.1.1: ESP(spi=0x0fc6fa09,seq=0x31)
11.849841 port1 in 102.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c08,seq=0x31)11.849855 hub-dia in 192.168.2.100 -> 192.168.1.100: icmp: echo reply11.849869 hub-dia out 192.168.2.100 -> 192.168.1.100: icmp: echo reply11.849882 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x2a)
12.851853 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x2b)12.851880 hub-dia in 192.168.1.100 -> 192.168.2.100: icmp: echo request12.851943 hub-dia out 192.168.1.100 -> 192.168.2.100: icmp: echo request12.851963 port1 out 100.1.1.1 -> 102.1.1.1: ESP(spi=0x0fc6fa09,seq=0x32)
12.853503 port1 in 102.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c08,seq=0x32)12.853520 hub-dia in 192.168.2.100 -> 192.168.1.100: icmp: echo reply12.853535 hub-dia out 192.168.2.100 -> 192.168.1.100: icmp: echo reply12.853549 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x2b)
13.856033 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x2c)13.856063 hub-dia in 192.168.1.100 -> 192.168.2.100: icmp: echo request13.856127 hub-dia out 192.168.1.100 -> 192.168.2.100: icmp: echo request13.856147 port1 out 100.1.1.1 -> 102.1.1.1: ESP(spi=0x0fc6fa09,seq=0x33)
13.857770 port1 in 102.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c08,seq=0x33)13.857784 hub-dia in 192.168.2.100 -> 192.168.1.100: icmp: echo reply13.857798 hub-dia out 192.168.2.100 -> 192.168.1.100: icmp: echo reply13.857811 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x2c)
14.860246 port1 in 101.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c07,seq=0x2d)14.860269 hub-dia in 192.168.1.100 -> 192.168.2.100: icmp: echo request14.860326 hub-dia out 192.168.1.100 -> 192.168.2.100: icmp: echo request14.860345 port1 out 100.1.1.1 -> 102.1.1.1: ESP(spi=0x0fc6fa09,seq=0x34)
14.861912 port1 in 102.1.1.1 -> 100.1.1.1: ESP(spi=0x6f614c08,seq=0x34)14.861929 hub-dia in 192.168.2.100 -> 192.168.1.100: icmp: echo reply14.861943 hub-dia out 192.168.2.100 -> 192.168.1.100: icmp: echo reply14.861956 port1 out 100.1.1.1 -> 101.1.1.1: ESP(spi=0x329a5865,seq=0x2d)
说明:关于sniffer抓VPN业务和ESP的包抓取IPsec VPN的IKE协商包:diagnose sniffer packet any "host 101.1.1.1 and (port 500 or port 4500)" 4
抓取IPsec VPN的ESP加密数据包:diagnose sniffer packet any "host 101.1.1.1 and esp" 4
抓取IPsec VPN的明文业务数据包:diagnose sniffer packet any "host 192.168.1.100 and icmp" 4
注意:由于存在IPsec VPN芯片加速,因此可能数据包会抓不完全,主要指“ESP数据和明文业务数据”抓不全,因此有时候需要将VPN隧道的NP加速关闭:FortiGate1_BeiJing # config vpn ipsec phase1-interface FortiGate1_BeiJing (phase1-interface) # edit VPN-TO-SH FortiGate1_BeiJing (VPN-TO-SH) # set npu-offload disable FortiGate1_BeiJing (VPN-TO-SH) # end
补充:关于上述HUB_and_SPOKE的优化
上面的HUB and SPOKE组网有一个不安全的因素是,HUB可以接受任意的公网IP接入到总部网络中,同时所有的分支都使用相同的预共享密钥,一旦其中一个分支的预共享密钥泄漏,则第三方攻击者将有机会通过预共享密钥接入到整个HUB和SPOKE的网络中,而又没有很好的办法同时一并修改所有分支的IPsec VPN预共享密钥(当然FortiManger可以做到),因此如何避免上述的问题?
解决办法:
1.野蛮模式+Peer ID用户组(用户名+密码)替代简单的预共享密钥的身份验证。每一个SPOKE拥有独立的用户名和密码用于身份认证,并且可定期维护该用户名(SPOKE Local ID)和密码(预共享密钥)。
2.使用数字证书代替预共享密钥方式作为认证方式。
下面将介绍使用野蛮模式+Peer ID用户组(用户名+密码)的方式用于认证SPOKE的身份,这种认证方式通常只能FortiGate和FortiGate进行对接,而友商有可能不支持这种方式。
HUB 侧配置修改:
1.新建spoke端的用户名和密码并加入到用户组中,当然也可以使用Radius或LDAP进行用户名密码的维护,本例中我们选择本地用户名和密码。






2.IPsec VPN配置的调整,开启野蛮模式并Peer ID调用SPOKE-USER-GROUP用户组,以代替简单的预共享密钥认证方式。SPOKE-USER-GROUP用户组中的用户名就是对端的ID,密码就是对端的预共享密钥。

HUB 侧的配置调整完毕,其他的配置都不需要改动,包括IPsec VPN的第一阶段/第二阶段算法感兴趣流、策略等等配置。
SPOKE 侧配置修改:
SPOKE(SH)配置修改:
1.修改IPsec VPN第一阶段的模式为野蛮模式,预共享密钥为在HUB端设置的用户名spoke-sh的密码,设置本地ID,为用户名:spoke-sh。


SPOKE(SH) 侧的配置调整完毕,其他的配置都不需要改动,包括IPsec VPN的第一阶段/第二阶段、策略、路由等等配置。
SPOKE(GZ)配置修改:
1.修改IPsec VPN第一阶段的模式为野蛮模式,预共享密钥为在HUB端设置的用户名spoke-gz的密码,设置本地ID,为用户名:spoke-gz。


SPOKE(GZ) 侧的配置调整完毕,其他的配置都不需要改动,包括IPsec VPN的第一阶段/第二阶段、策略、路由等等配置。
HUB侧VPN和路由状态查看:


安全和简单往往是有些矛盾的,后续如果增加新的SPOKE,HUB仅仅需要在增加新的用户名和密码即可,IPsec VPN的配置是不需要调整的,但SPOKE侧的配置脚本则需要修改LOCAL ID、预共享密钥、第二阶段感兴趣流src-network,这三个地方。相对来说操作会复杂一些。