So this week I was tasked with bringing up a site-to-site VPN between a Cisco ISR and Cisco ASA. Every site-to-site VPN I’ve done over the last 10 years or so has been route-based. But the older Cisco ASA code won’t support those, so it was back to isakmp profiles and crypto-maps. The real trick was the ISR was using both frontdoor and interior VRFs, and HSRP for failover for added complexity.
Here’s was the information:
- Site A (Cisco ISR 4431, IOS-XE version 16.6.8):
- public IP: 198.51.100.52/29, HSRP IP: 198.51.100.54, VRF: EXTERNAL
- private IP IP: 10.111.111.1/24, VRF: INTERNAL
- Site B (Cisco ASA, software version 9.4):
- public IP: 203.0.113.105
- private network: 10.222.222.0/24
The configuration for the ISR starts with the ISAKMP policy, which basically sets encryption parameters. This is global, and not VRF-aware:
crypto isakmp invalid-spi-recovery crypto isakmp keepalive 10 ! crypto isakmp policy 1 encr aes 256 ! 256-bit AES encrytpion authentication pre-share group 2 ! 1024-bit key lifetime 86400 ! default setting hash sha ! default setting !
The pre-shared key is set in the crypto keyring, with needs to be mapped to the frontdoor VRF (the VRF set on the public interface)
crypto keyring MY_KEYRING vrf EXTERNAL local-address 198.51.100.54 EXTERNAL pre-shared-key address 203.0.113.105 key xxxxxxxxxxxxxxx
Unlike route-based VPNs, an ISAKMP profile is required, which is VRF-aware. Note the presence of the iVRF (internal one) on the “vrf” line:
crypto isakmp profile MY_ISAKMP_PROFILE vrf INTERNAL keyring MY_KEYRING match identity address 203.0.113.105 255.255.255.255 EXTERNAL local-address 198.51.100.54 EXTERNAL !
For IPSec / Phase 2, a transform set of course should be defined. Here I’m using Encapsulation Security Payload, AES 128-bit encryption with SHA-1 hashing, operating in IPSec tunnel mode:
crypto ipsec transform-set ESP_AES-128_SHA_TUNNEL esp-aes esp-sha-hmac mode tunnel ! crypto ipsec df-bit clear
Since this is not route-based, an ACL defines the “interesting” traffic to send via the tunnel:
ip access-list extended 101 permit ip 10.111.111.0 0.0.0.255 10.222.222.0 0.0.0.255 !
Then a crypto map links this ACL with the ISAKMP profile and IPSec settings:
crypto map MY_CMAP 1 ipsec-isakmp set peer 203.0.113.105 set transform-set ESP_AES-128_SHA_TUNNEL set pfs group5 set isakmp-profile MY_ISAKMP_PROFILE match address 101 reverse-route lifetime 3600 ! default setting !
Finally, the crypto map is applied to the public interface. If HSRP is being used between a pair of routers, a name for the HSRP group must be set, then added to the crypto map statement:
interface Port-channel1 description Public Interface vrf forwarding EXTERNAL ip address 198.51.100.52 255.255.255.248 ip nat outside standby delay minimum 30 standby 1 ip 198.51.100.54 standby 1 priority 254 standby 1 preempt standby 1 name VPNHA load-interval 30 no negotiation auto crypto map MY_CMAP redundancy VPNHA ! ip route vrf EXTERNAL 0.0.0.0 0.0.0.0 198.51.100.49
I had missed the “redundancy” option on the crypto map in my initial config, which probably cause the traffic to source from the primary IP address rather than the HSRP one. Running debug crypto isakmp, I would see this:
May 15 17:15:35.892: ISAKMP: (0):SA request profile is MY_ISAKMP_PROFILE May 15 17:15:35.892: ISAKMP: (0):Created a peer struct for 203.0.113.105, peer port 500 May 15 17:15:35.892: ISAKMP: (0):New peer created peer = 0x80007FAD0B334DB8 peer_handle = 0x8000000080000012 May 15 17:15:35.892: ISAKMP: (0):Locking peer struct 0x80007FAD0B334DB8, refcount 1 for isakmp_initiator May 15 17:15:35.892: ISAKMP: (0):local port 500, remote port 500 May 15 17:15:35.892: ISAKMP: (0):set new node 0 to QM_IDLE May 15 17:15:35.893: ISAKMP: (0):insert sa successfully sa = 80007FAD0B75C470 May 15 17:15:35.893: ISAKMP: (0):Can not start Aggressive mode, trying Main mode. May 15 17:15:35.893: ISAKMP-ERROR: (0):No Cert or pre-shared address key. May 15 17:15:35.894: ISAKMP-ERROR: (0):construct_initial_message: Can not start Main mode
Since the debug wasn’t showing the source IP for this traffic, I spent several hours troubleshooting the ISAKMP profile and VRF statements, only to conclude they were in fact correct.