"The What?" - In this post we will go over setting up FlexVPN hub & spoke tunnels. We will utilize SVTIs on our spokes, DVTIs derived from virtual templates on our hub, IOS PKI certificate authentication to establish our tunnels. Lastly, we will use some smart defaults.
"The Why?" - In hub & spoke topologies the main site is known as the hub. Other remote locations are known as spokes. In these types of setups traffic from remote location flows from the spoke to our hub, and the hub acts as a relay allowing spoke to spoke communication. This type of configuration allows remote branches to communicate with each other.
"The How?" - The building blocks for this post that are required to successfully configure our topology include:
Configure our PKI that will be used for VPN certificate authentication (see more IOS PKI info here: Configuring, Verifying, & Troubleshooting IOS PKI )
Successfully configure our IKEv2 setup (see more about IKEv2 building blocks here: FlexVPN Configuration Blocks Tidbit)
Successfully configure our IPsec setup
Configure our VTI template (see more about VTIs here: SVTIs & DVTIs Tidbit)
Assign our VTI template to our IKEv2 profile that is then assigned to our IPsec profile
Assign IPsec profile to our tunnel/VTI
Brief overview of our topology:

Configuration:
Let's start with our hub (Flex server) configuration. As mentioned above we need to first configure the PKI portion which includes generating an rsa keypair, PKI trustpoint container, authenticate our CA, & finally enrollment. Here is the config snippet:
Note you must have a separate trustpoint to use on the CA for FlexVPN Authentication; See why here: IKEv2 Authentication Error Tidbit
crypto pki trustpoint Cif
enrollment url http://192.168.254.1:8080
fqdn csr1.cifelli.lab.net
subject-name CN=csr1.cifelli.lab.net
revocation-check none
rsakeypair Cifelli-Lab
This trustpoint is separate then the one used for the CA. Since this post is primarily about FlexVPN direct spoke-to-spoke tunnels I have chosen to omit our CA configuration.
Underlay interface configuration that connects our hub & spokes:
interface GigabitEthernet1.254
encapsulation dot1Q 254
ip address 192.168.254.1 255.255.255.0
As you can see next, our IKEv2 profile points to the virtual template interface that will be cloned when creating our DVTIs for the spoke tunnels. Since we our performing VPN authentication with certificates I went ahead and utilized a cert map, and both local/remote auth is configured to support cert authentication.
crypto pki certificate map Cifelli-Lab 10
subject-name co cifelli.lab.net
!
crypto ikev2 profile IKE_CIF_PROF
match certificate Cifelli-Lab
identity local dn
authentication remote rsa-sig
authentication local rsa-sig
pki trustpoint Cifelli-Lab
virtual-template 1
!
Next we setup our IPsec profile that will get assigned to our virtual-template interface so that our DVTI spoke tunnels are protected. This is where we map our IKEv2 profile to.
crypto ipsec profile CIF_IPSEC_PROF
set ikev2-profile IKE_CIF_PROF
Next we will display our configuration for the virtual-template & our loopback address. Note that IP Unnumbered allows us to process IP based packets without the need to configure a unique IP address on an interface. Essentially you borrow an IP address from another interface, which is usually (best practice) a loopback interface.
interface Virtual-Template1 type tunnel
ip unnumbered Loopback1
tunnel source GigabitEthernet1.254
tunnel protection ipsec profile CIF_IPSEC_PROF
interface Loopback1
ip address 10.0.10.1 255.255.255.255
The hub configuration to establish tunnels with each spoke will utilize DVTIs so we configured a virtual-template, which allows us to clone configs to virtual-access interfaces for each respective security association (SA). In this lab I am not pushing config to the spokes just yet so on the spokes I configured SVTIs for the hub tunnels, and also configured a DVTI to eventually establish our direct spoke-to-spoke tunnel. Cisco's smart defaults are used for the rest of the configuration.
Now let's move on to our spokes' configuration. Omitting the PKI portion, but here is what is needed to successfully stage our spokes.
Starting with Spoke 1 (CSR13): We start with covering the cert map along with our IKEv2 profile:
crypto pki certificate map Cifelli-Lab 10
subject-name co cifelli.lab.net
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
virtual-template 1
Next is our IPsec profile:
crypto ipsec profile CIF_IPSEC_PROF
set ikev2-profile IKE_CIFELLI_PROF
Lastly, is configuring our tunnel that will be used as our SVTI for the spoke-to-hub tunnel:
interface Tunnel0
ip address 10.0.10.3 255.255.255.0
tunnel source GigabitEthernet1.254
tunnel destination 192.168.254.1
tunnel protection ipsec profile CIF_IPSEC_PROF
end
Of course our underlay interface is necessary too:
interface GigabitEthernet1.254
encapsulation dot1Q 254
ip address 192.168.254.13 255.255.255.0
Quick review of the other spoke (csr14) config:
interface GigabitEthernet1.254
encapsulation dot1Q 254
ip address 192.168.254.14 255.255.255.0
!
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
virtual-template 1
!
crypto pki certificate map Cifelli-Lab 10
subject-name co cifelli.lab.net
!
crypto ipsec profile CIF_IPSEC_PROF
set ikev2-profile IKE_CIFELLI_PROF
!
interface Tunnel0
ip address 10.0.10.4 255.255.255.0
tunnel source GigabitEthernet1.254
tunnel destination 192.168.254.1
tunnel protection ipsec profile CIF_IPSEC_PROF
Verification:
Ok now that our hub & both spokes are configured let's perform some verification. Note that since both spokes are configured with SVTIs and connected to our hub we can think of these as "always on" connections.
From our hub (CSR1) lets verify our sessions. As you can see we have two UP-ACTIVE sessions using virtual-access interfaces that were cloned from our template referenced in the IKEv2 profile:
CSR1#show crypto session
Crypto session current status
Interface: Virtual-Access3
Profile: IKE_CIF_PROF
Session status: UP-ACTIVE
Peer: 192.168.254.14 port 500
Session ID: 365
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-Access1
Profile: IKE_CIF_PROF
Session status: UP-ACTIVE
Peer: 192.168.254.13 port 500
Session ID: 364
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
We can see the interfaces being used as UP/UP:
CSR1#show ip int bri | i Virt
Virtual-Access1 10.0.10.1 YES unset up up
Virtual-Access3 10.0.10.1 YES unset up up
Virtual-Template1 10.0.10.1 YES unset up down
We can also see both active IKEv2 SAs from our hub:
CSR1#show crypto ikev2 sa
IPv4 Crypto IKEv2 SA
Tunnel-id Local Remote fvrf/ivrf Status
1 192.168.254.1/500 192.168.254.13/500 none/none READY
Encr: AES-CBC, keysize: 256, PRF: SHA512, Hash: SHA512, DH Grp:19, Auth sign: RSA, Auth verify: RSA
Life/Active Time: 86400/878 sec
Tunnel-id Local Remote fvrf/ivrf Status
2 192.168.254.1/500 192.168.254.14/500 none/none READY
Encr: AES-CBC, keysize: 256, PRF: SHA512, Hash: SHA512, DH Grp:19, Auth sign: RSA, Auth verify: RSA
Life/Active Time: 86400/876 sec
Thanks for following along! In this blog we have successfully configured a hub & spoke topology, and performed verification. In later posts we will go over direct spoke-to-spoke tunnels and much more. Cheers!