top of page

Use Case Explorer - Nested IPSEC Cisco to FortiGate

Writer's picture: Matt SherifMatt Sherif

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:

A high level diagram of what we aim to accomplish.
A high level diagram of what we aim to accomplish.

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:

This is what happens when you configure a tunnel with no associated policy
This is what happens when you configure a tunnel with no associated policy

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:

The above output indicates the tunnel is up
The above output indicates the tunnel is up

Cisco Side:

The above output indicates the tunnel is up
The above output indicates the tunnel is up

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:

The above output indicates the tunnel is up
The above output indicates the tunnel is up

Cisco Side:

The above output indicates the tunnel is up
The above output indicates the tunnel is up

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:

SSH Session Established Successfully
SSH Session Established Successfully

Logs on MPLS Perimeter Firewall:

Traffic shows originating from 192.168.83.10
Traffic shows originating from 192.168.83.10

Note the source/destination interfaces and addresses. So this is successful!


For an added bonus, let's see what the "outside" VPN FortiGate sees:

Nothing to see here - except for IKE and ESP
Nothing to see here - except for IKE and ESP

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!


 
 
 

Recent Posts

See All

Comments


bottom of page