Hoo boy! It's been a minute since I've last written, or recorded anything. 2024 was a whirlwind year, and a lot went on then. Thank you all for reading, watching and sharing, as I do appreciate it. I do hope to keep writing/recording moving forward.
Onto today's use case. Working with a customer who had an existing Cisco > FortiGate tunnel, and needed to deploy additional devices that would normally connect to their MPLS network through this tunnel. However to keep things segmented they wished to do so via a tunnel into the appropriate environment.
Take a look at the diagram below:

The customer has a private cellular provider who connects to their network over the "outside tunnel". Once the customer wanted to start deploying services, they would need to connect from "within" the MPLS Perimeter firewall. This is for the sake of segmentation - as the cell provider private network is subject to the "field sites/MPLS" network type according to customer security policy.
This dictated the need for the "inside tunnel" to ride within the "outside tunnel". This article will cover the two most common types of IPSEC VPN - IKEv1 and IKEv2. I am of the opinion that you should do IKEv2 where you can, and IKEv1 where IKEv2 is simply not supported - the pipe dream would be to replace those devices, however this isn't practical in large environments from a time perspective.
The "Outside" Tunnel Configuration - IKEv2:
This is from a Cisco IOS-XE device to a FortiGate, here are the relevant details:
Tunnel Parameters:
Phase 1:
IKE version: 2
Proposal: aes256-sha256
Diffe-Hellman Group 19
Phase 2:
Proposal: aes256-sha256
Perfect Forward Secrecy: Yes
PFS Diffe-Hellman Group 19
Key Lifetime (seconds): 28800 - the default on the Cisco side
FortiGate (VPN Firewall) configuration:
FortiGate WAN (Port1): 172.26.210.14/24 GW: .1
FortiGate LAN (Port2): 10.10.228.0/24
Phase 1 Configuration:
config vpn ipsec phase1-interface
edit "PVT-CELL"
set interface "port1"
set ike-version 2
set peertype any
set net-device disable
set proposal aes256-sha256
set npu-offload disable
set dhgrp 19
set remote-gw 172.20.73.94
set psksecret <Super_Secret_Password>
next
end
Phase 2 Configuration:
config vpn ipsec phase2-interface
edit "PVT-CELL"
set phase1name "PVT-CELL"
set proposal aes256-sha256
set dhgrp 19
set keylifeseconds 28800
next
end
Tunnel Interface Configuration:
To ensure that this doesn't get fragmented - it's generally not ideal - and to account for the additional packet overhead of running traffic through an IPSEC tunnel, we need to bring the MTU down to 1400 - we could theoretically set it a little higher (say 1420), but I like sticking to round figures for this example.
config system interface
config system interface
edit "PVT-CELL"
set mtu-override enable
set mtu 1400
next
end
Static route configuration:
We need static routes in this case due to the fact that the tunnel is "unnumbered" and we won't be establishing any sort of dynamic routing between tunnel endpoints
config router static
edit 0
set dst 192.168.10.0 255.255.255.0
set device "PVT-CELL"
next
end
At this stage the tunnel configuration is complete, but it won't come up if we leave it as is. The reason for this is due to there not being a firewall policy present. If we left this be, and the applied the Cisco side configuration, we would get the following error message when debugging in FortiOS:

First we'll create the address objects we'll use in the firewall rules:
config firewall address
edit "port2 address"
set type interface-subnet
set subnet 10.10.228.0 255.255.255.0
set interface "port2"
next
end
config firewall address
edit "PVT_CELL_NET"
set subnet 192.168.10.0 255.255.255.0
next
end
port2 address is the address of "port2" so it's dynamic in the sense that if that interface's IP address is updated, the address object will be updated with it. That's the beauty of "type interface-subnet". You can use standard address objects, this is just a matter of preference.
Now we'll create the two rules allowing IKE, ESP, and ICMP over the tunnel bidirectionally.
config firewall policy
edit 1
set name "PVT_CELL_IN"
set srcintf "PVT-CELL"
set dstintf "port2"
set action accept
set srcaddr "PVT_CELL_NET"
set dstaddr "port2 address"
set schedule "always"
set service "ESP" "IKE" "ALL_ICMP"
set logtraffic all
next
edit 2
set name "OUT_TO_PVT_CELL"
set srcintf "port2"
set dstintf "PVT-CELL"
set action accept
set srcaddr "port2 address"
set dstaddr "PVT_CELL_NET"
set schedule "always"
set service "ESP" "IKE" "ALL_ICMP"
set logtraffic all
next
end
Now we're all set on the FortiGate side of things. Onto the Cisco configuration!
Cisco (WAN Edge Router) Configuration:
It had been a while since I have configured VPN on a Cisco device, and even longer since it was done on IOS-XE. This exercise was helpful for a refresh, and also hopefully it helps you!
Cisco Router WAN (GigabitEthernet1) 172.20.73.94/24 GW: .1
Cisco Router LAN (GigabitEthernet2) 192.168.10.0/24
Phase 1 Configuration:
The Phase 1 configuration isn't as "straight forward" in my opinion, and took a bit of reading and trial and error. However this is what is working
!
! Keyring - IKEv2 PreShared Key
!
crypto ikev2 keyring KEYS
peer FGT_OUTSIDE-VPN
! This will only be used by the FortiGate VPN peer
address 172.26.210.14
pre-shared-key <Super_Secret_Password>
!
! IKEv2 Proposal
!
! Setting the ciphers to be used by IKEv2
crypto ikev2 proposal phase1_FGT_IKEv2
encryption aes-cbc-256
integrity sha256
group 19
!
!
! Setting IKEv2 Policy to be used by the router, if you don't set this
! understand what the "Default" policy is set for
! In this case, any tunnels originating from Gi1 will have this policy
! applied
crypto ikev2 policy policy_FGT_IKEv2
match address local 172.20.73.94
proposal phase1_FGT_IKEv2
!
! IKEv2 Profile (Phase 1) - bringing it all together
!
crypto ikev2 profile prof_FGT_IKEv2
match identity remote address 172.26.210.14 255.255.255.255
identity local address 172.20.73.94
authentication remote pre-share
authentication local pre-share
keyring local KEYS
!
Phase 2 Configuration:
!
! Transform Set - setting the ciphers to be used by Phase 2
!
! We are using tunnel mode and encapsulating the entire original packet
crypto ipsec transform-set tset_FGT_IPSEC esp-aes 256 esp-sha256-hmac
mode tunnel
!
! Phase 2 - Bringing it all together and tying in Phase1
!
crypto ipsec profile prof_FGT_IPSEC
set transform-set tset_FGT_IPSEC
set pfs group19
set ikev2-profile prof_FGT_IKEv2
!
! Tunnel interface configuration
!
interface Tunnel1
! Since we're not using "IPs on the interfaces directly" we need to use
! IP unnumbered, any traffic originating from the router and going over
! the tunnel will originate from 192.168.10.1
ip unnumbered GigabitEthernet2
ip mtu 1400
ip tcp adjust-mss 1360
tunnel source 172.20.73.94
tunnel mode ipsec ipv4
tunnel destination 172.26.210.14
tunnel protection ipsec profile prof_FGT_IPSEC
!
Static route configuration:
ip route 10.10.228.0 255.255.255.0 Tunnel1
Since this is a router, this is all the configuration we need.
Verifying the tunnel came up:
FortiGate Side:

Cisco Side:

This concludes the outside tunnel configuration
"Inside" Tunnel Configuration - IKEv1:
The inside tunnel will be using IKEv1, and this is a good exercise for understanding each vendor's implementation of IKE.
Tunnel Parameters:
Phase 1:
IKE version: 1
Mode: Aggressive
Proposal: aes128-sha1 3des-sha1
Diffe-Hellman Group 5
Phase 2:
Proposal: aes128-sha1
Perfect Forward Secrecy: No
Key Lifetime (seconds): 3600
FortiGate (MPLS Perimeter) Configuration:
Phase 1 Configuration:
config vpn ipsec phase1-interface
edit "CELL-TO-MPLS"
set type dynamic
set interface "port1"
set mode aggressive
set peertype one
set net-device disable
set proposal aes128-sha1 3des-sha1
set dpd disable
set dhgrp 5
set idle-timeout enable
set peerid "FIELD_VPN_TM"
set psksecret <Super_Secret_Password_v2>
next
end
Aside from IKEv1 in this configuration, one big difference to point out, is the "type dynamic" tunnel here - also known as a Dial-Up tunnel in the GUI. We expect MANY devices from the private cell to connect in, maintaining 1-to-1 tunnels is an administrative nightmare and doesn't scale well. Hence this tunnel will listen for connections only, and use the peerid "FIELD_VPN_TM" for validation of the peer.
Phase 2 Configuration:
config vpn ipsec phase2-interface
edit "CELL-TO-MPLS"
set phase1name "CELL-TO-MPLS"
set proposal aes128-sha1
set pfs disable
set keylifeseconds 3600
next
end
Tunnel interface configuration:
For the inside tunnel, we'll bring down the MTU to 1300.
config system interface
edit "CELL-TO-MPLS"
set mtu-override enable
set mtu 1300
next
end
Static route configuration:
config router static
edit 3
set dst 192.168.83.0 255.255.255.0
set device "CELL-TO-MPLS"
next
end
As mentioned in the "Outside" tunnel we still need to configure the address objects and policies to allow traffic to flow over the tunnel, and for the tunnel to come up
Address Objects:
config firewall address
edit "MPLS_NETS"
set type interface-subnet
set subnet 192.168.12.0 255.255.255.0
set interface "port2"
next
end
config firewall address
edit "Field_Site_A"
set subnet 192.168.83.0 255.255.255.0
next
end
config firewall addrgrp
edit "CELL_FIELD_SITES"
set member "Field_Site_A"
next
end
A slight difference since this Firewall will be expected to provide connectivity to a large number of remote sites, we created a firewall address group, and added Field_Site_A to it. This allows for future revisions to create the address object, and add to the group without editing the firewall policy directly.
Firewall Policy:
config firewall policy
edit 1
set name "MPLS_FIELD_TO_CELL_FIELD"
set srcintf "port2"
set dstintf "CELL-TO-MPLS"
set action accept
set srcaddr "MPLS_NETS"
set dstaddr "CELL_FIELD_SITES"
set schedule "always"
set service "ALL"
set logtraffic all
next
edit 2
set name "CELL_FIELD_TO_MPLS_FIELD"
set srcintf "CELL-TO-MPLS"
set dstintf "port2"
set action accept
set srcaddr "CELL_FIELD_SITES"
set dstaddr "MPLS_NETS"
set schedule "always"
set service "ALL"
set logtraffic all
next
end
Now we're all set on the FortiGate side of things. Onto the Cisco configuration!
Cisco (Customer CE) Configuration:
This is where things got wonky for me, as the command structure for IKEv1 is a little different, whereas I'd gotten used to a very similar command structure, save for which version of IKE I was using - the available commands depended on th the version of IKE in FortiOS, but that was the only major difference.
One other difference is that we'll be putting the LAN side in VRF TRX.
vrf definition trx
address-family ipv4
exit-address-family
!
Phase 1 Configuration:
! Key Ring
!
crypto keyring MPLSfw
local-address Gi1
pre-shared-key address 10.10.228.1 255.255.255.255 key <Super_Secret_Password_v2>
!
! IKEv1 (ISAKMP) policy
!
crypto isakmp policy 20
encryption 3des
hash sha
authentication pre-share
group 5
lifetime 28800
!
crypto isakmp invalid-spi-recovery
crypto isakmp keepalive 15 5 periodic
!
! IKEv1 (ISAKMP) Profile
!
crypto isakmp profile MPLS-FW-Profile
keyring MPLSfw
! use the self-identity fqdn to set local ID - it must match the
! peerid we set on the Fortinet side
self-identity fqdn FIELD_VPN_TM
match identity address 10.10.228.1 255.255.255.255
initiate mode aggressive
!
Phase 2 Configuration:
crypto ipsec transform-set tset-aes-sha1 esp-aes esp-sha-hmac
mode tunnel
!
! Bringing Phase2 Together
!
crypto ipsec profile IKEv1-Tunnel
set transform-set tset-aes-sha1
set isakmp-profile MPLS-FW-Profile
!
! Tunnel interface configruation
!
interface Tunnel1
description Cellular Connection To MPLSfw VPN
vrf forwarding trx
ip unnumbered GigabitEthernet 2
ip mtu 1300
ip tcp adjust-mss 1260
tunnel source Gi1
tunnel mode ipsec ipv4
tunnel destination 10.10.228.1
tunnel protection ipsec profile IKEv1-Tunnel
Static Route Configuration:
ip route vrf trx 192.168.12.0 255.255.255.0 Tunnel1
Verifying the tunnel came up:
FortiGate Side:

Cisco Side:

Validating end to end connectivity.
I will initiate an SSH session from our desktop at 192.168.83.10 to 192.168.12.10 - and should show the logs on the MPLS Perimeter Firewall indicating as such.
SSH Session:

Logs on MPLS Perimeter Firewall:

Note the source/destination interfaces and addresses. So this is successful!
For an added bonus, let's see what the "outside" VPN FortiGate sees:

The outside FortiGate only sees the IKE and ESP traffic - but as you can see it's tunnel traffic from 10.10.228.1 to 192.168.10.10 and vice versa. And the source destination interfaces indicated that the "inside tunnel" is then being insert into the "outside" tunnel.
Conclusion:
Based on the examples above it is possible to configure a "Nested IPSec" using multivendor VPN, your biggest consideration for such an endeavor would be the performance impact of the "smaller" MTU size of the inner tunnel - but in scenarios where you need the connectivity, it can be a handy tool to add to the bag.
I hope this has been helpful, and I look forward to our next topic.
Madman out!
Comments