Policy-Based VPNs on Cisco ISRs when behind NAT

A couple years ago I wrote a post about route-based IPSec VPNs involving NAT-T on Cisco Routers. However today I had to setup a lab environment using policy-based VPNs. This was a real blast from past as I hadn’t done a policy-based VPN on a Cisco router since the late 1990s :-O

VPN Parameters:

  • Local side, private IP of external interface of router: 192.0.2.2
  • Local side, private IP subnet 192.168.100.0/24
  • Local side, public IP address: 198.18.51.78
  • Remote side, public IP address: 203.0.113.161
  • Remote side, private IP subnet: 10.13.0.0/16
  • Pre-shared key: MySecretKey1234
  • Phase 1 encryption and lifetime: AES-256, SHA-384, Group 14, 1 day
  • Phase 2 encryption and lifetime: AES-128, SHA-1, Group 2, 1 hour

With both IKEv1 or v2, you’ll want to start by verifying NAT-T is enabled, which is the default setting. This will allow the router to detect behind behind NAT and tunnel traffic on udp/4500 rather than using regular ESP (protocol 50):

crypto ipsec nat-transparency udp-encapsulation

If the other side is expecting or requiring NAT-T and it’s been disabled, Cisco IOS will log this warning:

%IKEV2-3-NEG_ABORT: Negotiation aborted due to ERROR: NAT-T disabled via cli

IKEv1

As with route-based VPN, I start by setting some global ISAKMP parameters:

crypto isakmp disconnect-revoked-peers
crypto isakmp invalid-spi-recovery
crypto isakmp keepalive 30 2 on-demand
crypto isakmp nat keepalive 900

The ISAKMP policy defines global encryption and authentication settings.

! 256-bit AES + SHA2-384 + PFS Group14 (2048-bit key)
crypto isakmp policy 100
 encr aes 256
 hash sha384
 authentication pre-share
 group 14
 lifetime 86400              ! 1 day, which is the default
!

Configure authentication for the peer by defining a keyring, specifying the public IP of the remote side. Then create an ISAKMP profile, again specifying the remote’s public IP and the local’s external interface:

crypto keyring CRYPTO_KEYRING
  local-address GigabitEthernet0/0
  pre-shared-key address 203.0.113.161 key MySecretKey1234
!
crypto isakmp profile ISAKMP_PROFILE
   keyring CRYPTO_KEYRING
   match identity address 203.0.113.161 255.255.255.255 
   local-address GigabitEthernet0/0
!

Now the crypto map, which replaces the crypto ipsec profile of route-based VPNs. I’m just using the typical encryption settings of 128-bit AES/SHA-1/Group2 PFS. The access-list must be defined to match “interesting” traffic to send across the VPN.

! LOCAL = 192.168.100.0/24.   REMOTE = 10.13.0.0/16
access-list 101 permit ip 192.168.100.0 0.0.0.255 10.13.0.0 0.0.255.255
!
crypto ipsec security-association replay window-size 1024
crypto ipsec df-bit clear
!
crypto ipsec transform-set ESP_AES128_SHA esp-aes esp-sha-hmac 
 mode tunnel
!
crypto map CRYPTO_MAP 1 ipsec-isakmp 
 set peer 203.0.113.161
 set security-association lifetime seconds 3600      ! 1 hour, which is the default
 set transform-set ESP_AES128_SHA
 set pfs group2
 match address 101
 reverse-route
!

Finish by applying the crypto map to the external interface:

ip route 0.0.0.0 0.0.0.0 192.0.2.1
!
interface GigabitEthernet0/0
 ip address 192.0.2.2 255.255.255.0
 crypto map CRYPTO_MAP
!
interface GigabitEthernet0/1
 ip address 192.168.100.100 255.255.255.0
!

Send a ping that matches the interesting traffic. Make sure to use an interface that’s with the source IP range specific on the ACL referenced by the Crypto Map.

Router# ping 10.13.113.11 source Gi0/1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.13.113.11, timeout is 2 seconds:
Packet sent with a source address of 192.168.100.100 
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 68/71/72 ms

Verify IPSEC SAs are up:

Router# show crypto ipsec sa peer 203.0.113.161

interface: GigabitEthernet0/0
    Crypto map tag: CRYPTO_MAP, local addr 192.0.2.2

   protected vrf: (none)
   local  ident (addr/mask/prot/port): (192.168.100.0/255.255.255.0/0/0)
   remote ident (addr/mask/prot/port): (10.13.0.0/255.255.0.0/0/0)
   current_peer 203.0.113.161 port 4500
     PERMIT, flags={origin_is_acl,}
    #pkts encaps: 4, #pkts encrypt: 4, #pkts digest: 4
    #pkts decaps: 4, #pkts decrypt: 4, #pkts verify: 4

IKEv2

I always start IKEv2 configuration with some global settings:

crypto ikev2 nat keepalive 900
crypto ikev2 dpd 30 2 on-demand
crypto logging ikev2

As with route-based VPN, configure an IKEv2 proposal and policy. Here’s a broad one that should match anything with reason:

crypto ikev2 proposal IKEV2_PROPOSAL
 encryption aes-cbc-256 aes-cbc-128 3des
 integrity sha512 sha384 sha256 sha1
 group 21 20 19 16 14 2
!
crypto ikev2 policy IKEV2_POLICY 
 match fvrf any
 proposal IKEV2_PROPOSAL
!

Create a keyring entry for the other side specifying their public IP, then an IKEv2 profile. If the other side is expecting to see the public IP address, configure that with the identity local address option. The match identity remote address must match their IKEv2 remote ID. This usually will be the public IP, but may require the private IP if they are also behind NAT and not overriding.

crypto ikev2 keyring IKEV2_KEYRING
 peer TEST1
  address 203.0.113.161
  pre-shared-key MySecretKey1234
 !
crypto ikev2 profile IKEV2_PROFILE
 match address local interface GigabitEthernet0/0
 match identity remote address 203.0.113.161     ! Other side's remote ID
 identity local address 198.51.100.78            ! My public IP
 authentication local pre-share
 authentication remote pre-share
 keyring local IKEV2_KEYRING
 dpd 60 5 on-demand             ! override global DPD setting, if desired
!

Crypto map is same as IKEv1 (see above), just with the IKEv2 profile specified:

crypto map CRYPTO_MAP 1 ipsec-isakmp 
 set ikev2-profile IKEV2_PROFILE
!

Finally apply crypto map to external interface. The IKEv2 SA should pop up within a few seconds.

*Feb 26 22:07:41 PST: %IKEV2-5-SA_UP: SA UP

Verify details of the IKEv2 SA:

Router# show crypto ikev2 sa remote 203.0.113.161 detailed 
 IPv4 Crypto IKEv2  SA 

Tunnel-id Local                 Remote                fvrf/ivrf            Status 
1         192.0.2.2/4500        203.0.113.161/4500    none/none            READY  
      Encr: AES-CBC, keysize: 256, PRF: SHA384, Hash: SHA384, DH Grp:14, Auth sign: PSK, Auth verify: PSK
      Life/Active Time: 86400/115 sec
      CE id: 1007, Session-id: 4
      Status Description: Negotiation done
      Local spi: 55543FD20BD46FA2       Remote spi: 03B6B07E9090FCF2
      Local id: 192.0.2.2
      Remote id: 10.113.13.2
      Local req msg id:  0              Remote req msg id:  14        
      Local next msg id: 0              Remote next msg id: 14        
      Local req queued:  0              Remote req queued:  14        
      Local window:      5              Remote window:      1         
      DPD configured for 10 seconds, retry 2
      Fragmentation not  configured.
      Extended Authentication not configured.
      NAT-T is detected inside 
      Cisco Trust Security SGT is disabled
      Initiator of SA : No

 IPv6 Crypto IKEv2  SA

As with IKEv1, the final step is verify the IPSEC SA.

Advertisement

CheckPoint SmartView Monitor shows Permanent Tunnels Down, even though they’re up

Being fairly new to CheckPoint, I hadn’t yet used SmartView monitor, which is the windows desktop monitoring application. At first glance it wasn’t very useful. I had terminated several test tunnels to various Cisco, FortiGate, and Palo Alto firewalls, all of which were working fine. But they all showed down in SmartView. What the heck?

Reason: When it comes to monitoring tunnels, CheckPoint by default uses a proprietary protocol they call “tunnel_test” (udp/18234). In order to properly monitor VPN tunnels to Non-CheckPoint Devices, DPD (dead peer detection) must be used.

Here’s how to enable DPD on an interoperable device:

  1. In the CheckPoint SmartConsole folder (usually C:\Program Files (x86)\CheckPoint\SmartConsole), run GuiDBedit.exe
  2. Under Network Objects folder -> network_objects, look for the interoperable device Object. The class name will be “gateway_plain”
  3. Search for Field name tunnel_keepalive_method and change it to dpd
  4. File -> Save All, exit.
  5. Restart SmartConsole and install policy to the applicable Checkpoint gateways / clusters

After making that change, pushing policy, and restarting SmartView Monitor, the tunnels now show green:

VPN throughput Tests – Palo Alto VM-300 to GCP

I was doing a deep dive read of supported IKEv2 ciphers on GCP native VPNs today and thought I’d setup a quick lab to see which settings would provide best throughput. Lab setup was as follows:

  • Palo Alto VM-300 on m4.xlarge in us-east-2 (Ohio)
  • IKEv2 VPN to GCP us-east4 (N. Virginia)
  • Latency is a steady 13ms round trip time
  • AWS side test instance is t3.xlarge (4 vCPU / 16 GB RAM)
  • GCP side test instance is e2-standard-4 (4 vCPU / 16 GB RAM)
  • Both VMs running Ubuntu Linux 18.04.4
  • File is 500 MB binary file transfer via SCP

Throughput speeds (in Mbps) using DH Group 14 (2048-bit) PFS:

Encryption / HashSHA-512SHA-256SHA-1
AES-GCM 256-bit664668672
AES-GCM 128-bit648680704
AES-CBC 256-bit510516616
AES-CBC 192-bit492523624
AES-CBC 128-bit494573658
Average: 604 Mbps

Throughput speeds (in Mbps) using DH Group 5 (1536-bit) PFS:

Encryption / HashSHA-512SHA-256SHA-1
AES-GCM 256-bit700557571
AES-GCM 128-bit660676616
AES-CBC 256-bit464448656
AES-CBC 192-bit595528464
AES-CBC 128-bit605484587
Average: 574 Mbps

Throughput speeds (in Mbps) using DH Group 2 (1024-bit) PFS:

Encryption / HashSHA-512SHA-256SHA-1
AES-GCM 256-bit680626635
AES-GCM 128-bit672664680
AES-CBC 256-bit584452664
AES-CBC 192-bit536520664
AES-CBC 128-bit528502656
Average: 608 Mbps

Key Takeaways

GCP will prefer AES-CBC in their negotiations, but AES-GCM provides roughly 25% better throughput. So if throughput is paramount, be sure to have only AES-GCM in the IPSec profile.

If using AES-CBC, SHA-1, while deprecated, is 13% faster than SHA-256 and 25% faster than SHA-512. Since SAs are rebuilt every 3 hours, cracking isn’t as large a concern as in typical SHA-1 use cases.

DH Group does not affect speeds. May as well use the strongest mutually supported value, which is Group 14 (2048-bit). GCP does not support Elliptic Curve (Groups 19-21) so these couldn’t be tested. I would expect faster SA build times, but no change in transfer speeds.

Assuming SHA-256 and Group 14 PFS, this graph summarizes the results:

Site-to-Site IPSec VPNs on CheckPoint R80.30

The first step is to create a new object with the public IP address of the other side of the tunnel.  This is fairly well buried in the menus:

R80_30_new_VPN_interop_device

After that, create a new VPN “community” in Objects -> More object types -> VPN Community -> New Meshed VPN and walk through the wizard.

The main gotcha is watch out for weird default settings.  In particular, AES-128 is disabled as encryption cipher for Phase 1.  My guess is since it’s the most popular cipher for Phase 2, they go with the “mix ciphers” strategy.  But personally I just like to use AES-128 for everything – it’s simple, fast, and plenty secure.

VPNs to GCP using IKEv2 when your Cisco router is behind NAT

I was able to follow this tutorial but had to make a few adjustments.  The main one is to configure the public IP address in the IKEv2 profile (see step 3 below). 

Remember of course that the router will need UDP ports 500 & 4500 forwarded by the firewall, which also must support ESP passthrough.

1) Configure a global IKEv2 proposal and policy. 

crypto ikev2 proposal MY_IKEV2_PROPOSAL 
 encryption aes-cbc-256 aes-cbc-192 aes-cbc-128
 integrity sha512 sha384 sha256
 group 24 16 14
!
crypto ikev2 policy MY_IKEV2_POLICY 
 proposal MY_IKEV2_PROPOSAL

2) And add the peer to the keyring:

crypto ikev2 keyring MY_KEYRING
 peer gcp1
  address 35.212.226.126
  pre-shared-key abcdef1234567890

3) Create a custom IKEv2 profile.  Note the highlighted public IP address and also the lifetime and DPD interval settings.

crypto ikev2 profile GCP_IKEV2_PROFILE
 match address local interface GigabitEthernet0
 match identity remote address 0.0.0.0
 ! If router is behind NAT, set this to the public IP
 identity local address 203.0.113.222
 authentication remote pre-share
 authentication local pre-share
 keyring local MY_KEYRING
 lifetime 36000                       ! 10 hour SA lifetime
 dpd 60 5 periodic                    ! 1 minute keepalives
!

4) Configure a custom IPSec transform set and profile.  This is 128-bit AES encryption with SHA-256 integrity:

! IPsec Settings
crypto ipsec transform-set ESP_AES128_SHA256 esp-aes esp-sha256-hmac
!
crypto ipsec profile GCP_IPSEC_PROFILE
 set security-association lifetime kilobytes disable
 set security-association lifetime seconds 10800
 set transform-set ESP_AES128_SHA256
 set pfs group14                          ! 2048-bit
 set ikev2-profile GCP_IKEV2_PROFILE
!

5) Finally, create the tunnel interface.  Unlike the IKEv2 profile, this simply references the External interface, not the public IP:

interface Tunnel1
 ip address 169.254.0.2 255.255.255.252
 ip mtu 1460
 ip virtual-reassembly in 
 ip tcp adjust-mss 1420
 tunnel source GigabitEthernet0
 tunnel mode ipsec ipv4
 tunnel destination 35.212.226.126
 tunnel protection ipsec profile GCP_IPSEC_PROFILE
!

Troubleshooting

The SAs should look like this:

Router#show crypto ikev2 sa
IPv4 Crypto IKEv2 SA

Tunnel-id Local Remote fvrf/ivrf Status 
2 192.168.1.123/4500 35.212.226.126/4500 none/none READY 
Encr: AES-CBC, keysize: 128, Hash: SHA256, DH Grp:14, Auth sign: PSK, Auth verify: PSK
Life/Active Time: 36000/1226 sec

Router#show crypto ipsec sa peer 35.212.226.126

interface: Tunnel1
    Crypto map tag: Tunnel1-head-0, local addr 192.168.1.123

   protected vrf: (none)
   local  ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
   remote ident (addr/mask/prot/port): (0.0.0.0/0.0.0.0/0/0)
   current_peer 35.212.226.126 port 4500
     PERMIT, flags={origin_is_acl,}
    #pkts encaps: 45, #pkts encrypt: 45, #pkts digest: 45
    #pkts decaps: 58, #pkts decrypt: 58, #pkts verify: 58
    #pkts compressed: 0, #pkts decompressed: 0
    #pkts not compressed: 0, #pkts compr. failed: 0
    #pkts not decompressed: 0, #pkts decompress failed: 0
    #send errors 0, #recv errors 0

     local crypto endpt.: 192.168.1.123, remote crypto endpt.: 35.212.226.126
     path mtu 1500, ip mtu 1500, ip mtu idb GigabitEthernet0
     current outbound spi: 0x962EDB69(2519653225)
     PFS (Y/N): N, DH group: none

     inbound esp sas:
      spi: 0x10B829B(17531547)
        transform: esp-aes esp-sha-hmac ,
        in use settings ={Tunnel UDP-Encaps, }
        conn id: 5, flow_id: Onboard VPN:5, sibling_flags 80000040, crypto map: Tunnel1-head-0
        sa timing: remaining key lifetime (sec): (14259)
        Kilobyte Volume Rekey has been disabled
        IV size: 16 bytes
        replay detection support: Y  replay window size: 1024
        Status: ACTIVE(ACTIVE)

     inbound ah sas:

     inbound pcp sas:

     outbound esp sas:
      spi: 0x962EDB69(2519653225)
        transform: esp-aes esp-sha-hmac ,
        in use settings ={Tunnel UDP-Encaps, }
        conn id: 6, flow_id: Onboard VPN:6, sibling_flags 80000040, crypto map: Tunnel1-head-0
        sa timing: remaining key lifetime (sec): (14259)
        Kilobyte Volume Rekey has been disabled
        IV size: 16 bytes
        replay detection support: Y  replay window size: 1024
        Status: ACTIVE(ACTIVE)

     outbound ah sas:

     outbound pcp sas:

IPSec VPN Spoke Router using FQDN authentication

In a previous post I’d covered doing site-to-site IPSec tunnels on Cisco routers when one or both devices are behind NAT.  But what if multiple spoke routers have dynamic IP addresses? Or how about many behind the same NAT address? 

The solution is to have the spoke routers authenticate using FQDN hostname rather than IP address.  I’ve seen lots of examples which overly complicate how to do this.  It’s actually pretty simple and only requires minor changes.  Let’s assume the spoke routers have dynamic IPs and the hub has a static IP of 203.0.113.222…

IKEv1

Spoke Router

On spoke routers with IKEv1, simply replace  the “crypto keyring” statement with “crypto isakmp peer” to use FQDN authentication and IKE aggressive mode, like this:

hostname spoke1
! 
no crypto keyring MyHub
crypto isakmp peer address 203.0.113.222 [vrf InternetVRFName]
 set aggressive-mode password XXXXXXXX
 set aggressive-mode client-endpoint fqdn spoke1.mydomain.com 
!

Note the fqdn hostname doesn’t necessarily need to match the router’s hostname

IKEv2

Spoke Router

Set the Hub’s IP address and pre-shared key in an IKEv2 keyring:

crypto ikev2 keyring MY_IKEV2_KEYRING
 peer MyHub
  address 203.0.113.222
  pre-shared-key MySecretKey1234    ! Must be 16 chars or longer

The identity (hostname) in the IKEv2 profile via the identity local line:

hostname spoke1
!
crypto ikev2 profile SPOKE_IKEV2_PROFILE
 match address local interface GigabitEthernet0/0
 match identity remote address 203.0.113.222 255.255.255.255
 identity local fqdn spoke1.spokedomain.com
 authentication remote pre-share
 authentication local pre-share
 keyring local MY_IKEV2_KEYRING
 dpd 20 2 periodic 
!

IPSec profile:

crypto ipsec profile SPOKE_IPSEC_PROFILE
 set security-association lifetime kilobytes disable
 set pfs group14
 set ikev2-profile SPOKE_IKEV2_PROFILE
!

Tunnel Interface and static route to 10.0.0.0/8:

interface Tunnel1
 ip address 169.254.1.100 255.255.255.0
 ip tcp adjust-mss 1379
 keepalive 10 3
 tunnel source GigabitEthernet0/0
 tunnel mode ipsec ipv4
 tunnel destination 203.0.113.222
 tunnel protection ipsec profile SPOKE_IPSEC_PROFILE
!
ip route 10.0.0.0 255.0.0.0 Tunnel1

Hub Router

Each Spoke will need an entry. Use identity in the entry, not hostname

crypto ikev2 keyring SPOKES_IKEV2_KEYRING
 peer spoke1
  identity fqdn spoke1.spokedomain.com
  pre-shared-key MySecretKey1234
 !

The IKEv2 profile will be a bit different. The domain is used to match multiple spokes:

crypto ikev2 profile HUB_IKEV2_PROFILE
 match address local interface GigabitEthernet0/0
 match identity remote fqdn domain spokedomain.com
 identity local fqdn myhub.hubdomain.com
 authentication remote pre-share
 authentication local pre-share
 keyring local SPOKES_IKEV2_KEYRING
 dpd 10 2 on-demand
 virtual-template 1

The IPSec profile is almost the same but is responder-only (passive):

crypto ipsec profile HUB_IPSEC_PROFILE
 set security-association lifetime kilobytes disable
 set pfs group14
 set ikev2-profile HUB_IKEV2_PROFILE
 responder-only

Rather than a regular tunnel interface, a virtual template one is used:

interface Virtual-Template1 type tunnel
 ip unnumbered Loopback0
 tunnel source GigabitEthernet0/0
 tunnel mode ipsec ipv4
 tunnel destination dynamic
 tunnel protection ipsec profile HUB_IPSEC_PROFILE

IPSec VPNs on Cisco routers when both are behind NAT

IPSec VPNs or really any site-to-site VPN works best when at least one of the sides or better yet both have Public IP addresses.  But what if one is behind NAT, or even both?  It gets increasing tricky to configure the correct IP addresses for authentication, and forward correct ports on protocols.  As I recently discovered, using IKEv2 and/or GRE further complicates things.  Consider this setup:

IPSecVPNsBehindNATs

Both routers are behind NAT/PAT firewalls without static 1-to-1 NATs configured.  There are still some requirements though:

  • Both firewalls must allow for protocol 50 passthrough for IPSec, or protocol 47 passthough if using GRE, which most do
  • At least one side must be forwarding ports udp/500 (isakmp) and udp/4500 (nat-t) to the router’s internet-facing interface so the connection can be established
  • Both routers need crypto ipsec nat-transparency udp-encapsulation enabled, which is the default setting.  

Let’s look at sample configs for each scenario.  These assume 1921 ISR G2 routers but IOS-XE configs should be exactly the same.

IPSec with ISAKMP / IKEv1

The is the simplest way to do it since only public IPs need to be referenced.

1) The ISAKMP portion:

crypto isakmp invalid-spi-recovery
crypto isakmp disconnect-revoked-peers
crypto isakmp keepalive 10 crypto isakmp nat keepalive 900 ! Policy supporting strong encryption crypto isakmp policy 100 encr aes 256 ! 256-bit AES encryption hash sha384 ! SHA-384 hashing authentication pre-share ! Using pre-shared keys lifetime 28800 ! 28000 seconds = 8 hours group 14 ! group 14 = 2048 bit key
! Backup policy supporting weaker encryption support for older devices crypto isakmp policy 200 encr aes ! 128-bit AES encryption hash sha ! SHA-1 hashing authentication pre-share ! Using pre-shared keys lifetime 28800 ! 28000 seconds = 8 hours group 2 ! group 2 = 1024 bit key ! FYI - default values are still des, sha, rsa-sig, 86400, group 1 :-O

2) And then pre-shared keys:

! Key for site 1 router
crypto keyring Site2
  local-address GigabitEthernet0/0
  pre-shared-key address 203.0.113.222 key 0 MySecretKey

! Key for site 2 router
crypto keyring Site1
 local-address GigabitEthernet0/0
 pre-shared-key address 198.51.100.111 key 0 MySecretKey

! Can also use "crypto isakmp key 0 MySecretKey address 1.2.3.4"

3) IPSec parameters.  For encryption, I like to just use 128-bit AES with either SHA-256 or SHA-1 signing with a group 2 (1024-bit) key to make the tunnel negotiation quick as possible.

! Create some IPSec Transform sets for ESP & 128-bit AES
crypto ipsec transform-set ESP_AES128_SHA256 esp-aes esp-sha256-hmac 
 mode tunnel
crypto ipsec transform-set ESP_AES128_SHA esp-aes esp-sha-hmac 
 mode tunnel

! Create IPSec profile
crypto ipsec profile MY_IPSEC_PROFILE
 set transform-set ESP_AES128_SHA256 ESP_AES128_SHA 
 set pfs group2    ! group 2 = 1024-bit key

Optional step: since the “client” side isn’t reachable on port udp/500, the “server” side may be configured as a responder.  This cuts down superfluous traffic, especially when the client is unreachable.

crypto ipsec profile IPSEC_PROFILE
 responder-only

5) The last step is build the tunnel interfaces.  For the “client” side:

interface Tunnel1000
 ip address 169.254.0.1 255.255.255.252
 ip tcp adjust-mss 1379
 keepalive 10 3
 tunnel source GigabitEthernet0/0
 tunnel mode ipsec ipv4
 tunnel destination 203.0.113.222
 tunnel protection ipsec profile IPSEC_PROFILE

Server side is exactly the same but with different IP addresses:

interface Tunnel1000
 ip address 169.254.0.2 255.255.255.252
 tunnel destination 198.51.100.111

Doing debug crypto isakmp on the server side while the tunnels come up shows the public IP address of the client.  Note the client’s random source ports.

ISAKMP (0): received packet from 198.51.100.111 dport 500 sport 14972 Global (R) MM_SA_SETUP
ISAKMP (1003): received packet from 198.51.100.111 dport 4500 sport 51597 Global (R) MM_KEY_EXCH
ISAKMP (1003): received packet from 198.51.100.111 dport 4500 sport 51597 Global (R) MM_KEY_EXCH
ISAKMP:(1003):SA has been authenticated with 198.51.100.111
ISAKMP:(1003):Detected port floating to port = 51597

We never see client’s private IP, but we do see the server side’s private IP at the end when the SA is finally built:

ISAKMP:(1003): Process initial contact,
bring down existing phase 1 and 2 SA's with local 192.168.2.222 remote 198.51.100.111 remote port 51597
ISAKMP: Trying to insert a peer 192.168.2.222/198.51.100.111/51597/, and inserted successfully

Can also see the other site’s private IP by examining the SAs once built:

Site1#show crypto isakmp peers 203.0.113.222
Peer: 203.0.113.222 Port: 4500 Local: 192.168.1.111
Phase1 id: 192.168.2.222

Site2#show crypto isakmp peers 198.51.100.111
Peer: 198.51.100.111 Port: 51597 Local: 192.168.2.222
Phase1 id: 192.168.1.111

 

IPSec with IKEv2

IKEv2 is new to me, but it was a surprise to see slightly different behavior when using NAT. Run through of the configuration:

1) Set some global IKEv2 parameters

crypto logging ikev2
crypto ikev2 nat keepalive 900
crypto ikev2 dpd 10 2 periodic

2) Create an IKEv2 Proposal and Policy

3) Keys are defined in the IKEv2 keyring, which has each site’s public IP address:

crypto ikev2 keyring MY_IKEV2_KEYRING
 ! Use this on site 1 router
 peer Site2
  address 203.0.113.222
  pre-shared-key MySecretKey1234    ! Must be 16 chars or longer
 ! Use this on site 2 router
 peer Site1
  address 198.51.100.111
  pre-shared-key MySecretKey1234    ! Must be 16 chars or longer

4) Create IKEv2 Profile

crypto ikev2 profile MY_IKEV2_PROFILE
 match address local interface GigabitEthernet0/0
 match identity remote address 192.168.0.0 255.255.0.0
 authentication remote pre-share
 authentication local pre-share
 keyring local MY_IKEV2_KEYRING
 dpd 20 2 periodic

This is where is gets weird because the “remote address” parameter needs to match the internal IP address(es) of the other sides.  The simple and lazy approach is use 0.0.0.0 since that will match anything.  The other option is use a different profile for each peer.

5) Add IKEv2 profile to the existing IPSec profile.  Note that doing so shouldn’t break IKEv1 clients as the IKEv2 stuff should just be ignored.

crypto ipsec profile MY_IPSEC_PROFILE
 set transform-set ESP_AES128_SHA256_TUNNEL ESP_AES128_SHA1_TUNNEL 
 set pfs group2
 set ikev2-profile MY_IKEV2_PROFILE

In the SAs, we can see our private IP,  but not the other side’s:

Site1#show crypto ikev2 sa remote 203.0.113.222
Tunnel-id Local                 Remote                fvrf/ivrf            Status
1         192.168.1.111/4500    203.0.113.222/4500    none/none            READY  
      Encr: AES-CBC, keysize: 128, Hash: SHA256, DH Grp:14, Auth sign: PSK, Auth verify: PSK
      Life/Active Time: 86400/30 sec

Site2#sh crypto ikev2 sa remote 198.51.100.111      
Tunnel-id Local                 Remote                fvrf/ivrf            Status 
1         192.168.2.222/4500    198.51.100.111/51597  none/none            READY  
      Encr: AES-CBC, keysize: 128, Hash: SHA256, DH Grp:14, Auth sign: PSK, Auth verify: PSK
      Life/Active Time: 86400/71 sec

BTW, if NAT-T has been disabled but is required by the other end, debug crypto ikev2 will show this:

Oct 12 19:53:08.620: IKEv2-ERROR:(SESSION ID = 1075,SA ID = 2): NAT is found but it is not supported.: NAT-T disabled via cli
Oct 12 19:53:08.620: IKEv2-ERROR:(SESSION ID = 1075,SA ID = 2):: NAT-T disabled via cli

IKEv2 Policies, Proposals, and Profiles on Cisco Routers

Just like “crypto isakmp policy”, the “crypto ikev2 policy” configuration is global and cannot be specified on a per-peer basis.  If there’s a mismatch, “debug crypto ikev2 error” will show something like this:

IKEv2-ERROR:(SESSION ID = 685,SA ID = 1):Expected Policies: : Failed to find a matching policyProposal 1: AES-CBC-128 SHA256 SHA256 DH_GROUP_2048_MODP/Group 14

There are two solutions.  The simplest is specify all possible encryption, integrity, and PFS parameters in a single proposal:

crypto ikev2 proposal MY_IKEV2_PROPOSAL 
 encryption aes-cbc-256 aes-cbc-192 aes-cbc-128 3des
 integrity sha512 sha384 sha256 sha1
 group 21 20 19 16 14 5 2

crypto ikev2 policy MY_IKEV2_POLICY 
 proposal MY_IKEV2_PROPOSAL

Alternately, write separate proposals, then list them in the policy by preference:

crypto ikev2 proposal HIGH 
 encryption aes-cbc-256 aes-cbc-192 aes-cbc-128 
 integrity sha512 sha384 sha256 
 group 21 20 19
crypto ikev2 proposal MEDIUM
 encryption aes-cbc-256 aes-cbc-192 aes-cbc-128 
 integrity sha256 sha1
 group 16 14
crypto ikev2 proposal LOW 
 encryption aes-cbc-128 3des
 integrity sha1 md5
 group 5 2
crypto ikev2 policy MY_IKEV2_POLICY 
 proposal HIGH
 proposal MEDIUM
 proposal LOW

It’s disappointing Cisco did not design things so policies could be associated with individual peers.   Imagine a router terminating VPNs to different business partners, where Partner A insists on AES256/SHA512/Group16, while Partner B is still doing 3DES/MD5/Group2.  You would write the policy with the most secure at the top, but there’s nothing to stop partner A from downgrading to partner B’s policy.  It’s a security concern, plus takes extra time to negotiate.

Palo Alto Firewalls supports different ISAKMP policies on a per-IKE gateway basis and it’s one of the reasons I’ve really preferred them for Site-to-Site VPNs over the years.