IPsec

FlexVPN Explained: One Framework for Site-to-Site, Hub-Spoke, and Remote Access

FlexVPN: real routing table showing spoke LANs injected by IKEv2 via Virtual-Access interfaces
In: IPsec, VPN, FlexVPN, CCIE, Labs

Every Cisco engineer eventually inherits a router with four different VPN styles bolted onto it: a crypto map for the legacy branch, a static VTI for the partner link, DMVPN for the regional spokes, and EzVPN for the handful of teleworkers who never got a proper laptop image. Four configuration models, four troubleshooting workflows, four sets of gotchas. FlexVPN exists to collapse all of that into one. It is the modern Cisco answer to the question "how should I build IPsec on IOS XE today", and it sits at the top of the IPsec VPN cluster for a reason.

The single most surprising thing about FlexVPN, and the thing that makes it click once you see it, is this: IKEv2 itself carries the addresses and the routes. There is no IGP running over the overlay. No OSPF adjacency, no EIGRP neighbor, no BGP session. The tunnel comes up, and the routes are simply there. This article walks through why that works, using real output from our CML lab (HUB, SPOKE1, and SPOKE2, all cat8000v running IOS XE 17.18.02).

The Zoo FlexVPN Replaces

Before FlexVPN, Cisco IPsec was a collection of unrelated configuration dialects. Each one solved a real problem, and each one was configured completely differently from the others.

Crypto Maps
Built for: Classic site-to-site between two known peers.
Interesting traffic: An ACL bolted to a physical interface.
Pain: No tunnel interface, so no routing protocol, no QoS, no per-tunnel stats. Every new subnet means editing the crypto ACL on both ends.
Static VTI
Built for: Site-to-site with a real routable interface.
Interesting traffic: Anything routed into the tunnel. No crypto ACL.
Pain: One tunnel interface per peer, statically configured. Fine for five sites, miserable for five hundred.
DMVPN
Built for: Large hub-and-spoke with dynamic spoke-to-spoke.
Interesting traffic: Routed into a single mGRE tunnel; NHRP maps overlay to underlay.
Pain: Needs a routing protocol over the overlay, plus NHRP, plus GRE, plus IPsec profiles. Three technologies stacked to make one design work.
EzVPN
Built for: Remote access. A client pulls an address and a policy from a server.
Interesting traffic: Pushed down as split-tunnel policy from the head end.
Pain: A completely separate config model from every site-to-site option, and it never scaled cleanly into site-to-site territory.

Look at what those four have in common: every single one is IPsec, and every single one needs to authenticate a peer, negotiate policy, decide what traffic to protect, and get routes across. FlexVPN's insight is that all four are the same problem wearing different clothes, and that IKEv2 already has the machinery to solve it in one model.

FlexVPN Is a Framework, Not a Protocol

This trips people up constantly, so let us be blunt: there is no FlexVPN protocol. Nothing on the wire says "FlexVPN". Run a packet capture on a FlexVPN tunnel and you will see standards-based IKEv2 (RFC 7296) and standards-based ESP. That is it.

FlexVPN is Cisco's name for a configuration framework: a consistent set of IOS XE building blocks that use IKEv2's own features (the configuration payload, the authorization exchange, and IKEv2 route injection) to do the work that crypto maps, static VTIs, DMVPN, and EzVPN each did their own way. Because the framework leans on IKEv2 rather than on Cisco-proprietary glue, the same config model covers a hub-and-spoke fabric, a point-to-point site-to-site tunnel, and a remote-access client. That is the "flex" part.

The Building Blocks

A FlexVPN head end is assembled from five pieces. Learn these five and the rest is variation.

IKEv2 profile
Job: Match the remote peer's identity, decide how both sides authenticate, and bind the session to a virtual-template and an authorization list. This is the front door.
IKEv2 authorization policy
Job: The payload of attributes handed to the peer once it authenticates. Address pool, DNS, and critically the routes. This is where the magic lives.
AAA
Job: The lookup mechanism that connects the IKEv2 profile to the authorization policy. Can be local (our lab) or a RADIUS server (production, per-user policy).
Virtual-Template
Job: A blueprint interface. It is never used to pass traffic itself. It defines what a per-peer tunnel should look like: source, mode, IPsec protection, NHRP settings.
Virtual-Access
Job: The real interface, cloned from the template automatically when a peer authenticates, and destroyed when the session tears down. One per peer. You never configure it by hand.

The Headline Feature: IKEv2 Pushes the Routes

Here is the hub configuration from our lab. Read the authorization policy carefully, because those three lines are the entire routing design.

aaa new-model
aaa authorization network PLZ-FLEX-LIST local
ip local pool PLZ-FLEX-POOL 10.0.9.10 10.0.9.100

ip access-list standard PLZ-FLEX-ROUTES
 permit 10.20.10.0 0.0.0.255
 permit 192.168.99.0 0.0.0.255
 permit 10.30.0.0 0.0.255.255

crypto ikev2 authorization policy PLZ-AUTHOR-POL
 pool PLZ-FLEX-POOL
 route set interface
 route set access-list PLZ-FLEX-ROUTES

crypto ikev2 profile PLZ-FLEX-PROF
 match identity remote fqdn domain pinglabz.lab
 identity local fqdn hub.pinglabz.lab
 authentication local pre-share
 authentication remote pre-share
 keyring local PLZ-FLEX-KEYRING
 aaa authorization group psk list PLZ-FLEX-LIST PLZ-AUTHOR-POL
 virtual-template 1

route set interface tells IKEv2 to advertise the address on the tunnel interface itself. route set access-list PLZ-FLEX-ROUTES tells it to advertise every prefix permitted by that standard ACL. Those routes are then delivered to the peer inside the IKEv2 authorization exchange, as attributes, during tunnel setup.

Once both spokes connect, the hub's routing table looks like this:

HUB#show ip route | include Virtual-Access
S        10.0.9.24/32 is directly connected, Virtual-Access1
S        10.0.9.25/32 is directly connected, Virtual-Access2
S        10.30.10.0/24 is directly connected, Virtual-Access1
S        10.30.20.0/24 is directly connected, Virtual-Access2

SPOKE1's LAN (10.30.10.0/24) is reachable via Virtual-Access1. SPOKE2's LAN (10.30.20.0/24) is reachable via Virtual-Access2. The hub learned both, plus each spoke's assigned tunnel address, without a single line of routing protocol configuration.

The spoke side is the mirror image. Here is SPOKE1's static route table (and remember, the only static route we typed was the default toward the ISP):

SPOKE1#show ip route static
S*    0.0.0.0/0 [1/0] via 198.51.100.1
S        10.20.10.0/24 is directly connected, Tunnel0
S        10.30.0.0/16 is directly connected, Tunnel0
S        10.255.0.1/32 is directly connected, Tunnel0
S     192.168.99.0/24 is directly connected, Tunnel0

Every one of those tunnel routes came from the hub. 10.20.10.0/24 and 192.168.99.0/24 and 10.30.0.0/16 are exactly the three lines in PLZ-FLEX-ROUTES, and 10.255.0.1/32 is the hub's tunnel address, delivered by route set interface. Say it plainly: no OSPF, no EIGRP, no BGP. The IKEv2 AAA authorization policy injected all of it.

That has real operational consequences. Adding a new subnet to the hub site is one line in a standard ACL, and every spoke picks it up on its next rekey or reconnect. There is no adjacency to babysit, no overlay flap to chase, no "why is my EIGRP neighbor bouncing over the DMVPN cloud" ticket. For a hub-and-spoke topology where the routing is fundamentally hierarchical anyway, running a full IGP over the tunnel was always a bit of an overreach.

Dynamic Addressing Is the Same Mechanism as Remote Access

Look at the spoke's tunnel interface:

interface Tunnel0
 ip address negotiated
 ip nhrp network-id 1
 ip nhrp shortcut virtual-template 1
 tunnel source GigabitEthernet2
 tunnel mode ipsec ipv4
 tunnel destination 203.0.113.1
 tunnel protection ipsec profile PLZ-FLEX-IPSEC

ip address negotiated. The spoke has no idea what its own tunnel address is until IKEv2 tells it. On the hub, ip local pool PLZ-FLEX-POOL 10.0.9.10 10.0.9.100 plus the pool line in the authorization policy hands one out. Check the pool after both spokes are up:

HUB#show ip local pool PLZ-FLEX-POOL
 Pool                     Begin           End             Free  In use
 PLZ-FLEX-POOL            10.0.9.10       10.0.9.100        89       2
Inuse addresses:
   10.0.9.24          IKEv2 Addr IDB
   10.0.9.25          IKEv2 Addr IDB

Note the label: IKEv2 Addr IDB. IOS XE is telling you exactly who allocated those addresses. This is the IKEv2 configuration payload (CFG_REQUEST / CFG_REPLY in RFC 7296), and it is precisely the same mechanism a remote-access VPN client uses when it dials into a head end and gets an inside address, a DNS server, and a split-tunnel list.

That is the whole reason one framework can cover both worlds. To the hub, a branch router with ip address negotiated and a laptop running an IKEv2 client are the same kind of thing: a peer that authenticates, requests configuration, and gets an address and a set of routes. Swap pre-share for certificates and EAP, point the AAA list at RADIUS instead of local, and the identical head-end config serves remote-access users. Nothing else changes.

Virtual-Access: Cloning a Tunnel Per Peer

The hub never has a Tunnel interface for each spoke. It has one Virtual-Template1, and IOS XE clones it:

interface Virtual-Template1 type tunnel
 ip unnumbered Loopback0
 ip nhrp network-id 1
 ip nhrp redirect
 tunnel source GigabitEthernet2
 tunnel mode ipsec ipv4
 tunnel protection ipsec profile PLZ-FLEX-IPSEC

When SPOKE1 authenticates, IOS XE stamps out a copy of that template as Virtual-Access1, fills in the tunnel destination from the IKEv2 session, and brings it up. When SPOKE2 authenticates, it gets Virtual-Access2. Both spokes up:

HUB#show ip interface brief | include Virtual-Access
Virtual-Access1        10.255.0.1      YES unset  up                    up
Virtual-Access2        10.255.0.1      YES unset  up                    up

HUB#show crypto session
Interface: Virtual-Access1
Session status: UP-ACTIVE
Peer: 198.51.100.2 port 500
Interface: Virtual-Access2
Session status: UP-ACTIVE
Peer: 198.51.100.6 port 500

Both Virtual-Access interfaces share the same IP (10.255.0.1) because the template is ip unnumbered Loopback0. That is normal and correct. The per-peer state that makes them distinct is the tunnel destination, the IPsec SA, and the routes installed behind them. Add a hundred spokes and you get a hundred Virtual-Access interfaces, from that one template, with no additional hub configuration.

The Gotcha We Actually Hit

Our first attempt at the Virtual-Template omitted tunnel source and tunnel mode. IKEv2 authenticated perfectly. The debug showed the authorization request going through cleanly. And yet the tunnel refused to stay up, cycling in a loop:

%LINK-3-UPDOWN: Interface Virtual-Access1, changed state to down
%DMVPN-5-NHRP_NETID_UNCONFIGURED:  Virtual-Access1: NETID : 1 Unconfigured (Tunnel: 0.0.0.0 NBMA:  UNKNOWN)

Read that message closely: Tunnel: 0.0.0.0 NBMA: UNKNOWN. The cloned Virtual-Access had no idea what its own source address was, because the template never told it. It came up, discovered it was an incomplete tunnel, and died. Then IKEv2 (still perfectly happy) rebuilt the session, which cloned a new Virtual-Access, which also died.

The trap is that this looks like a crypto failure. You are staring at a VPN that will not come up, so you go debug IKEv2, and IKEv2 tells you everything is fine (you will see IKEv2:Using mlist PLZ-FLEX-LIST and username PLZ-AUTHOR-POL for group author request in the debug output, which is IKEv2 saying "authorization done, over to you"). It is not a crypto problem. It is an interface problem. The fix was adding the two missing lines to the template:

interface Virtual-Template1 type tunnel
 tunnel source GigabitEthernet2
 tunnel mode ipsec ipv4

The general lesson: in FlexVPN, a Virtual-Access is only ever as complete as the Virtual-Template it was cloned from. If the tunnel is flapping but IKEv2 says READY, stop debugging crypto and go read show derived-config interface Virtual-Access1 to see what IOS XE actually built.

FlexVPN vs DMVPN

These two overlap heavily, and the honest answer is that both are good. Neither one is deprecated, and DMVPN is not going anywhere.

DMVPN
Transport: mGRE plus NHRP, with IPsec layered on for protection.
Routing: A real IGP over the overlay (EIGRP, OSPF, or BGP). You own it, you tune it, you troubleshoot it.
Remote access: Not its job.
Maturity: Very high. Enormous installed base, deep documentation, a decade of field scar tissue.
Spoke-to-spoke: Proven and routine (Phase 2 and Phase 3).
FlexVPN
Transport: IKEv2-native. IPsec VTI, no GRE required.
Routing: Injected by IKEv2 from the authorization policy. No IGP needed.
Remote access: Same framework. Site-to-site and RA share one head-end model.
Maturity: Solid on modern IOS XE, but a smaller installed base and thinner community troubleshooting knowledge.
Spoke-to-spoke: Supported via NHRP shortcut, and it is the piece most likely to bite you on a given platform and release.

The short version: if you already run DMVPN at scale and it works, FlexVPN is not a reason to rip it out. If you are building green field on modern IOS XE, or if you need site-to-site and remote access to share one head end and one policy engine, FlexVPN is the cleaner starting point. If you want the deep dive on the other option, our DMVPN cluster covers mGRE, NHRP, and all three phases with working lab output.

Where FlexVPN Fits

Four deployment shapes, one framework:

  • Hub-and-spoke. The canonical FlexVPN design and the one in this article. Hub runs a virtual-template, spokes run a static Tunnel with a tunnel destination, IKEv2 hands out addresses and routes.
  • Point-to-point site-to-site. A degenerate hub-and-spoke with one spoke, or a pair of routers that each run a static tunnel. Covered step by step in FlexVPN site-to-site configuration.
  • Remote access. Same head end, certificates or EAP instead of a pre-shared key, AAA pointed at RADIUS. The client is just another peer requesting a config payload.
  • Spoke-to-spoke. NHRP shortcut and redirect let two spokes build a direct tunnel and bypass the hub. Worth being honest here: in our lab, on cat8000v 17.18.02, spoke-to-spoke traffic worked but only by hairpinning through the hub, and the NHRP shortcut never formed (every NHRP counter stayed at zero). We wrote up exactly what we could and could not prove in FlexVPN spoke-to-spoke, including the traceroute that shows the two-hop path.

Key Takeaways

  • FlexVPN is not a protocol. It is a Cisco configuration framework built entirely on standards-based IKEv2 and ESP. Nothing proprietary crosses the wire.
  • One model replaces four. Crypto maps, static VTIs, DMVPN, and EzVPN each solved one shape of the problem. FlexVPN covers all of them with the same building blocks.
  • IKEv2 carries the routes. route set interface and route set access-list in the IKEv2 authorization policy inject prefixes into the peer's routing table during tunnel setup. Our hub learned both spoke LANs, and both spokes learned the hub's networks, with no OSPF, EIGRP, or BGP anywhere.
  • IKEv2 carries the addresses too. ip address negotiated on the spoke plus ip local pool on the hub is the IKEv2 configuration payload, the same mechanism that gives a remote-access client its inside address. That is why one framework spans site-to-site and RA.
  • Virtual-Access interfaces are cloned, not configured. One Virtual-Template becomes one Virtual-Access per authenticated peer, created and destroyed with the session.
  • If the tunnel flaps but IKEv2 says READY, it is not crypto. A Virtual-Template missing tunnel source or tunnel mode clones a broken Virtual-Access that comes up and dies in a loop, and the NHRP_NETID_UNCONFIGURED message is your clue.
  • DMVPN is still fine. Pick FlexVPN for green field, for IKEv2-native designs, and when remote access and site-to-site should share a head end. Pick DMVPN when you need a battle-tested spoke-to-spoke fabric with a routing protocol you already run.

FlexVPN is the piece that makes the rest of the modern Cisco IPsec story hang together. If you want the full picture, from ESP and IKE fundamentals through crypto maps, VTIs, and IKEv2 itself, start at the IPsec VPN pillar and work outward.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.