Configuring & Verifying FlexVPN Direct Spoke-Spoke Tunnels

"The What?" - In this post I plan to go over how to create FlexVPN direct spoke-spoke tunnels. We will see & understand how NHRP is used to aide in this process. We will also utilize another IKEv2 feature known as the configuration payload.


See here to see more about NHRP: Next Hop Resolution Protocol (NHRP) Tidbit

See here to see more about IKEv2 Config Payload Feature: IKEv2 Configuration Payload Tidbit


"The Why?" - Direct tunnels between spokes can aide in saving bandwidth on the hub, unnecessary hops, & overall less latency for the spokes.


"The How?" - To start, I will be utilizing a previous blog/demo topology & configuration. To accomplish our goal of utilizing IKEv2 Config Payload feature & direct spoke-spoke tunnels we will go over the necessary configuration changes on both the hub & 2 spokes. The meat of the configuration & the topology from the previous FlexVPN blog can be found here: Configuring & Verifying FlexVPN Hub & Spoke Tunnels


Configuration:

The first step will be adding & tweaking parts of our hub config. This includes the following:

  • Create a local IP pool that will be used to issue out spoke overlay addresses

  • Enable AAA & create the authorization list

  • Configure a local pool that the hub will use to deploy overlay addresses to our spokes

  • Create an ACL that will be used to advertise IKEv2 routes

  • Create an authorization policy that ties things together

  • Update our IKEv2 profile

  • Enable NHRP & NHRP Redirect in our virtual-template

I first enabled AAA & created the AAA authorization list to be used:

aaa new-model
aaa authorization network FLEX_CIF local 

Below I created the pool of IP addresses that our hub will reference/use in the IKEv2 configuration payload feature for the spokes overlay tunnel addresses:

ip local pool CIF_POOL 10.0.10.2 10.0.10.254

Next I created the ACL that will advertise & allow connectivity to a local loopback on our hub that is acting as a LAN in this demo:

ip access-list standard CIF_ROUTES
 permit 11.11.11.11

Then the IKEv2 authorization profile gets created that ties together the first 3 items we created on our hub:

crypto ikev2 authorization policy IKE_CIF_AUTHZ 
 pool CIF_POOL
 route set interface
 route set access-list CIF_ROUTES

Before we move further a few important things to note:

  • The IKEv2 authorization policy drives route exchange during IKE negotiation

  • The authorization profiles are defined locally or via a remote AAA server

Now it is time to tie it all together inside of our IKEv2 profile:

crypto ikev2 profile IKE_CIF_PROF
 match certificate Cifelli-Lab
 identity local dn 
 authentication remote rsa-sig
 authentication local rsa-sig
 pki trustpoint Cif
 aaa authorization group cert list FLEX_CIF IKE_CIF_AUTHZ
 virtual-template 1

Lastly, before our hub is ready we update our virtual-template to enable NHRP & NHRP Redirect as shown below:

interface Virtual-Template1 type tunnel
 ip unnumbered Loopback1
 ip nhrp network-id 10
 ip nhrp redirect
 tunnel source GigabitEthernet1.254
 tunnel protection ipsec profile CIF_IPSEC_PROF
end

Ok so now the the hub is ready let's move to the first spoke (CSR13). If you need to see the topology used reference "The How?" further up. I will go over what configuration changes need to be made in order to prep our first spoke so that we can eventually deploy a spoke-spoke tunnel successfully. Here is an overview of what needs to occur on our spoke:

  • Create a virtual-template & enable NHRP & NHRP shortcut on the SVTI connecting to the hub

  • Enable AAA & create the authorization list

  • Create an ACL that will be used to advertise IKEv2 routes

  • Create an authorization policy that ties things together

  • Update our IKEv2 profile

First thing first, we still will use our SVTI for our connection to the hub. However, we need to change our static address used in the previous lab & enable NHRP with NHRP shortcut using the virtual-template (created later). I changed the IP address to negotiated so we can utilize the IKEv2 config payload feature. The config is as follows:

interface Tunnel0
 ip address negotiated
 ip nhrp network-id 10
 ip nhrp shortcut virtual-template 1
 tunnel source GigabitEthernet1.254
 tunnel destination 192.168.254.1
 tunnel protection ipsec profile CIF_IPSEC_PROF

Below is the virtual-template created that will allow us to spawn DVTIs for direct spoke-spoke tunnels later on. We will borrow our tunnel IP address and protect the tunnel via the same IPsec profile used across the board:

interface Virtual-Template1 type tunnel
 ip unnumbered Tunnel0
 ip nhrp network-id 10
 ip nhrp shortcut virtual-template 1
 tunnel protection ipsec profile CIF_IPSEC_PROF

Next, we take care of our AAA configuration by enabling AAA & creating the authorization list to be used:

aaa new-model
aaa authorization network FLEX_CIF local

Next I created the ACL that will advertise & allow connectivity to a local loopback on our spoke that is acting as a LAN in this demo:

Standard IP access list CIF_ROUTES
    10 permit 13.13.13.13

Next I created the IKE authorization profile that will be used on spoke1 to tie things together:

crypto ikev2 authorization policy IKE_CIF_AUTHZ 
 route set interface
 route set access-list CIF_ROUTES

Note: the command route set interface will send the tunnel IP address as a static ip address to the peer.

Now for the last piece I updated the IKEv2 profile as follows:

crypto ikev2 profile IKE_CIFELLI_PROF
 match certificate Cifelli-Lab
 identity local dn 
 authentication remote rsa-sig
 authentication local rsa-sig
 pki trustpoint Cifelli-Lab
 aaa authorization group cert list FLEX_CIF IKE_CIF_AUTHZ
 virtual-template 1

Now spoke 1 (CSR13 from topology) is ready & configured. Let's move on to CSR14 (spoke2). For the sake of brevity the steps are the same as spoke 1, excluding the ip access-list used to protect lan (in our case loopback interface). Here is the necessary spoke2 configuration:

interface Tunnel0
 ip address negotiated
 ip nhrp network-id 10
 ip nhrp shortcut virtual-template 1
 shutdown
 tunnel source GigabitEthernet1.254
 tunnel destination 192.168.254.1
 tunnel protection ipsec profile CIF_IPSEC_PROF
!
interface Virtual-Template1 type tunnel
 ip unnumbered Tunnel0
 ip nhrp network-id 10
 ip nhrp shortcut virtual-template 1
 tunnel protection ipsec profile CIF_IPSEC_PROF
!
aaa new-model
aaa authorization network FLEX_CIF local 
!
crypto ikev2 authorization policy IKE_CIF_AUTHZ 
 route set interface
 route set access-list CIF_ROUTES
!
ip access-list standard CIF_ROUTES
 permit 14.14.14.14 (local loopback acting as lan)
!

Verification:

Now that our hub & 2 spokes are configured let's verify connectivity, our configuration, & run through some debugs. Remember our goal is to successfully establish direct spoke-spoke tunnels. Before that though here are a couple reminders:


Since we are not doing any fancy routing for this topology I chose to work from spoke2 to spoke1 and debug NHRP on all 3 nodes. For reference again, CSR13 has a local loopback 13.13.13.13 that is configured to act as the lan & CSR14 has a loopback 14.14.14.14 doing the same thing. To successfully utilize NHRP shortcut switching I added a static route for 13.13.13.13 on CSR14 pointing to the hub.


Before we dive into spoke-spoke tunnel creation & verification I want to go through some quick debugs on the IKEv2 config payload feature from CSR1 (hub):

During the SVTI tunnel creation from spoke2 to the hub we can see IKEv2 authentication & authorization working as expected, and the start of the CFG-REQUEST:

Next the hub processes the IKE_AUTH message containing the config request & begins processing the config reply using the IP pool & ACL configured earlier in IKEv2 steps to send an IP + IKEv2 routes:

Lastly, after everything has successfully been negotiated we see the IPsec SA created and our VTI come up:

Now that we did a brief debug on IKEv2 config payload feature I want to dive into NHRP & verifying the direct spoke-spoke tunnel.


So let's walkthrough debugging NHRP so we understand how we establish our direct spoke-spoke tunnel. For direct spoke-spoke tunnel clarity purposes: On our hub both virtual-access interfaces to each respective spoke are up. Interface VA3 connects to spoke1 (CSR13) & interface VA1 connects to spoke2 (CSR14):

Virtual-Access1        10.0.10.1       YES unset  up                    up      
Virtual-Access3        10.0.10.1       YES unset  up                    up 
Interface: Virtual-Access1
Profile: IKE_CIF_PROF
Session status: UP-ACTIVE     
Peer: 192.168.254.14 port 500 
  Session ID: 22  
  IKEv2 SA: local 192.168.254.1/500 remote 192.168.254.14/500 Active 
  IPSEC FLOW: permit 47 host 192.168.254.1 host 192.168.254.14 
        Active SAs: 2, origin: crypto map

Interface: Virtual-Access3
Profile: IKE_CIF_PROF
Session status: UP-ACTIVE     
Peer: 192.168.254.13 port 500 
  Session ID: 21  
  IKEv2 SA: local 192.168.254.1/500 remote 192.168.254.13/500 Active 
  IPSEC FLOW: permit 47 host 192.168.254.1 host 192.168.254.13 
        Active SAs: 2, origin: crypto map

Below is a portion of the hub route table relating to our topology:

CSR1#show ip route static | i Virt

S        10.0.10.28/32 is directly connected, Virtual-Access1
S        10.0.10.29/32 is directly connected, Virtual-Access3
S        13.13.13.13 is directly connected, Virtual-Access3
S        14.14.14.14 is directly connected, Virtual-Access1

We can see from above that both spokes successfully sent routes via IKEv2 from the authorization configuration deployed earlier.


Debug verification from spoke2 (CSR14) - initiating spoke:

Now let's run through a few important debugs to better understand the flow. Beginning with the ping initiation from spoke2 (CSR14) to the "lan" on spoke 1 (13.13.13.13) we can see that the NHRP resolution request for 13.13.13.13 (spoke1) is sent via the overlay (tunnel 0)to the hub:

The initiating spoke (spoke2) eventually receives the resolution reply from spoke1:

Now let's digest some important NHRP debugs from the hub:

Below shows the hub triggering NHRP redirect:

We also can see the hub receiving the resolution request:

The hub then processes a route lookup for 13.13.13.13 and determines that the egress interface is VA3 for spoke1:

The hub now forwards the resolution request out interface VA3:

Now let's take a peek under the hood at what is happening on spoke1 (CSR13):

Spoke1 receives the resolution request from the hub, performs a route lookup, and determines that itself is the egress router. It then begins the NHRP resolution request.

Spoke1 is aware it needs to wait for an IPsec SA to establish:

Spoke1 eventually creates a VA interface, & begins updating the delayed event:

Continuing on we see that there is no longer a need to delay the processing of the resolution even as IKEv2/IPsec SA has been established (not shown here):

Spoke1 attempts to send the resolution reply out of the newly deployed VA interface directly connected to the initiating spoke (CSR14; spoke2):

At this point the direct tunnel between spokes is up thanks to shortcut switching.


Lastly, here are additional verifications from our initiating spoke (CSR14; spoke2) confirming shortcut switching & that the direct spoke-spoke tunnel is working:

Viewing both crypto sessions (SVTI to hub; DVTI to spoke1):

Part of route table:

Verifying NHRP shortcut:

So there you have it. We have successfully configured & verified direct spoke-spoke tunnels. We also debugged NHRP to better understand the process of shortcut switching & performed a brief debug so we could see the IKEv2 config payload feature in action. Cheers!

0 comments

Recent Posts

See All

Debugging IKEv1 on ASA

In the post I want to cover understanding IKEv1 status messages & debugging IKEv1 main mode. It is important as each message has its own unique meaning, and these messages are typically seen when att

Configuring & Verifying ASA Legacy IKEv1 L2L VPN - CLI

"The What?" - In this post I will cover configuring & verifying a basic site-to-site VPN tunnel between two Cisco ASAs using IKEv1 with pre-shared keys (PSK). These types of VPNs are also known as L2