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

FortiGate 60-E not supporting AES-GCM in Hardware

On a previous post I’d recommended using AES-GCM on VPNs to AWS and GCP since it’s generally a more efficient algorithm that offers higher throughput. So it came as a surprised today doing some deep-diving on my Fortigate 60-E today: AES-GCM is supported for Phase 2, it is not supported in hardware on the NPU:

FGT60ETK18XXXXXX # get vpn ipsec tunnel details
 gateway
   name: 'aws1'
   type: route-based
   local-gateway: 198.51.100.78:4500 (static)
   remote-gateway: 3.140.149.245:4500 (static)
   mode: ike-v1
   interface: 'wan1' (5)
   rx  packets: 52  bytes: 6524  errors: 0
   tx  packets: 110  bytes: 6932  errors: 3
   dpd: on-demand/negotiated  idle: 20000ms  retry: 3  count: 0
   nat traversal mode: keep-alive   RFC 3947   interval: 10
   selectors
     name: 'aws1'
     auto-negotiate: disable
     mode: tunnel
     src: 0:0.0.0.0/0.0.0.0:0
     dst: 0:0.0.0.0/0.0.0.0:0
     SA
       lifetime/rekey: 3600/3289   
       mtu: 1438
       tx-esp-seq: 2
       replay: enabled
       qat: 0
       inbound
         spi: 7dbc0283
         enc:  aes-gc  35a72036fa9a87000c90415b1863827652bf9dfd875f28a6d20fd1569e5c0099de639dcc
         auth:   null  
       outbound
         spi: ccdb6ab8
         enc:  aes-gc  21dd5c71a83142b0ecee1efe2c000c0dae586054160eb76df6f338d9071380b12103b0d9
         auth:   null  
       NPU acceleration: none

FGT60ETK18XXXXXX # get vpn ipsec stats crypto
NPU Host Offloading:
     Encryption (encrypted/decrypted)
     null      : 0                0               
     des       : 0                0               
     3des      : 0                0               
     aes-cbc   : 833309           0               
     aes-gcm   : 0                0               
     aria      : 0                0               
     seed      : 0                0               
     chacha20poly1305: 0                0               
     Integrity (generated/validated)
     null      : 0                0               
     md5       : 0                0               
     sha1      : 803671           0               
     sha256    : 29540            0               
     sha384    : 48               0               
     sha512    : 50               0 

Since the hardware offload isn’t occurring, the main CPU is moderately taxed when doing transfers via AES-GCM. Also, the throughput is only ~ 100 Mbps:

Reconfiguring the VPNs to AES-CBC and redoing the transfers, we get lower CPU usage and significantly higher throughput:

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:

Cisco ISR G2 to CheckPoint R80.30 IKEv1 VPN woes

I had previously done Cisco router to CheckPoint R80.30 gateway VPNs before without issue, but for whatever reason could not even establish phase 1 for this one. CheckPoint R80 VPN communities default to AES-256, SHA-1, Group 2, and 1-day timetime which is easy to match on the Cisco with this config:

crypto keyring mycheckpoint
 local-address GigabitEthernet0/0
 pre-shared-key address 192.0.2.190 key abcdefghij1234567890
!
crypto isakmp policy 100
 encr aes 256
 authentication pre-share
 group 2
 hash sha          ! <--- default value
 lifetime 864000   ! <--- default value
!

After verifying connectivity, doing packet captures, and multiple reboots on on both ends, IKE simply would not come up. On the Cisco ISR, debug crypto isakmp wasn’t especially helpful:

Jun 18 11:06:17.085: ISAKMP: (0):purging SA., sa=3246F97C, delme=3246F97C
Jun 18 11:06:17.285: ISAKMP: (0):SA request profile is (NULL)
Jun 18 11:06:17.285: ISAKMP: (0):Created a peer struct for 35.245.62.190, peer port 500
Jun 18 11:06:17.285: ISAKMP: (0):New peer created peer = 0x2CE62C3C peer_handle = 0x80000005
Jun 18 11:06:17.285: ISAKMP: (0):Locking peer struct 0x2CE62C3C, refcount 1 for isakmp_initiator
Jun 18 11:06:17.285: ISAKMP: (0):local port 500, remote port 500
Jun 18 11:06:17.285: ISAKMP: (0):set new node 0 to QM_IDLE
Jun 18 11:06:17.285: ISAKMP: (0):insert sa successfully sa = 2CE620E8
Jun 18 11:06:17.285: ISAKMP: (0):Can not start Aggressive mode, trying Main mode.
Jun 18 11:06:17.285: ISAKMP: (0):found peer pre-shared key matching 192.0.2.190
Jun 18 11:06:17.285: ISAKMP: (0):constructed NAT-T vendor-rfc3947 ID
Jun 18 11:06:17.285: ISAKMP: (0):constructed NAT-T vendor-07 ID
Jun 18 11:06:17.285: ISAKMP: (0):constructed NAT-T vendor-03 ID
Jun 18 11:06:17.285: ISAKMP: (0):constructed NAT-T vendor-02 ID
Jun 18 11:06:17.285: ISAKMP: (0):Input = IKE_MESG_FROM_IPSEC, IKE_SA_REQ_MM
Jun 18 11:06:17.285: ISAKMP: (0):Old State = IKE_READY New State = IKE_I_MM1
Jun 18 11:06:17.285: ISAKMP: (0):beginning Main Mode exchange
Jun 18 11:06:17.285: ISAKMP-PAK: (0):sending packet to 192.0.2.190 my_port 500 peer_port 500 (I) MM_NO_STATE
Jun 18 11:06:17.285: ISAKMP: (0):Sending an IKE IPv4 Packet.
Jun 18 11:06:17.369: ISAKMP-PAK: (0):received packet from 192.0.2.190 dport 500 sport 500 Global (I) MM_NO_STATE
Jun 18 11:06:17.369: ISAKMP-ERROR: (0):Couldn't find node: message_id 2303169274
Jun 18 11:06:17.369: ISAKMP-ERROR: (0):(0): Unknown Input IKE_MESG_FROM_PEER, IKE_INFO_NOTIFY: state = IKE_I_MM1
Jun 18 11:06:17.369: ISAKMP: (0):Input = IKE_MESG_FROM_PEER, IKE_INFO_NOTIFY
Jun 18 11:06:17.369: ISAKMP: (0):Old State = IKE_I_MM1 New State = IKE_I_MM1

The CheckPoint gave a more “useful” error:

Main Mode Failed to match proposal: Transform: AES-256, SHA1, Group 2 (1024 bit); Reason: Wrong value for: Authentication Method

This seemed to imply the CheckPoint was expecting certificate-based authentication rather than PSK. In traditional mode, the gateway is set by default for certificate only. But it’s not clear how this is configured in newer versions.

After poking around settings for quite a while, I simply deleted the VPN community in CheckPoint SmartConsole and re-created it. The connection then popped up immediately.

¯\_(ツ)_/¯

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:

VPN from Cisco ISR with frontdoor and interior VRFs + HSRP to a Cisco ASA

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.

 

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.

OpenVPN Server in AWS

Licensing costs start at just under $100 per user per year.  For compute costs, these are common supported instance sizes in a typical region:

  • t2.micro 1 vCPU, 1 GB RAM, ~75 Mpbs = ~$100/yr
  • t2.small 1 vCPU, 2 GB RAM, ~125 Mbps = ~$200/yr
  • t2.medium 2 vCPU, 2 GB RAM, ~250 Mbps = ~ $400/yr
  • t2.large 2 vCPU, 8 GB RAM, ~500 Mbps = ~$800/yr

SSH to the IP address using the correct private SSH key and ‘openvpnas’ as the username

The setup wizard should start automatically.  To run it again:

sudo su
/usr/bin/ovpn-init –ec2

To use the second (eth1) interface as the internal interface, get the IP address from AWS console and then edit /etc/netplan/50-cloud-init.yaml to add these lines ( (i.e. 192.168.101.123/255.255.255.0)

        eth1:
            dhcp4: no
            addresses: [192.168.101.123/24, ]

After saving the file, restart netplan and verify eth1 has the new IP address

sudo netplan apply
ifconfig eth1

To add internal static routes (for example, the RFC-1918 blocks) add these lines too:

            routes:
            - to: 192.168.0.0/16
                  via: 192.168.101.1
            - to: 172.16.0.0/12
                  via: 192.168.101.1
            - to: 10.0.0.0/8
                  via: 192.168.101.1

Then another restart netplan and verify the routes are working as entered

sudo netplan apply
netstat -rn

Set an initial password for the openvpn admin account via this command:

sudo passwd openvpn

Access the web gui at https://ip.address/admin/ logging in as openvpn with the password that was just set

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:

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

Tried my first VPN to GCP and didn’t have much luck with IKEv1.  While it did detect the remote router being behind NAT, Phase1 wouldn’t come up due to an ID mismatch:

received NAT-T (RFC 3947) vendor ID
remote host is behind NAT
IDir '192.168.1.123' does not match to '203.0.113.222'

Where 192.168.1.123 is the Real private IP of the router and 203.0.113.222 is the public NAT IP.

This is consistent with the GCP documentation on this topic, which states the following:

When using one-to-one NAT, your on-premises VPN gateway must identify itself using the same external IP address of the NAT device

See also the same configuration with IKEv2.