IPsec/IKEv2 between Cisco CSR 1000v and OpenIKED

Recently, I have setup as part of an important lab, an IPsec site-to-site tunnel between a Cisco CSR 1000v router and an OpenBSD gateway running OpenIKED. The latter not only terminates a GRE/IP tunnel, but also provides a global internet connectivity through NAT/PAT. The intend is to secure the GRE traffic between the two devices which are located in two different sites and who are reachable across the internet. The Cisco CSR 1000v instance is also behind NAT, therefore the configuration is slightly more complex than what we may be used to and require the use of the IPsec Tunnel mode and the NAT-T capability. To establish the secure IPsec sessions I decided to use the latest iteration of the Internet Key Exchange protocol, namely IKEv2.

Figure 1 - IPsec Site-to-Site VPN Overview
IPsec Site-to-Site VPN Overview

Disclaimer

During the initial writing of this article, I had to use weak encryption ciphers and authentication algorithms. For production use, please consider using more secure transforms.

Before going into the configuration details of IKEv2 and IPsec, I always recommend to first check IP reachability between the tunnel endpoints, so potential issues at the tunnel transport level can be excluded.

OpenBSD (OpenIKED)

The first thing to do as a prerequisite is to turn on IP Forwarding, enable Generic Routing Encapsulation (GRE) and to check for IP Security (IPsec) support at the kernel-level. To do so, we add the following few lines to the /etc/sysctl.conf file.

# Enable IPv4 and IPv6 Forwarding
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
# Enable GRE support
net.inet.gre.allow=1

To avoid rebooting the OpenBSD gateway, simply use the sysctl command with the above lines as argument.

Then we ensure IPsec and IP Compression is indeed enabled with the correct parameters:

# sysctl -a | grep ipsec
net.inet.ip.ipsec-expire-acquire=30
net.inet.ip.ipsec-invalid-life=60
net.inet.ip.ipsec-pfs=1
net.inet.ip.ipsec-soft-allocs=0
net.inet.ip.ipsec-allocs=0
net.inet.ip.ipsec-soft-bytes=0
net.inet.ip.ipsec-bytes=0
net.inet.ip.ipsec-timeout=86400
net.inet.ip.ipsec-soft-timeout=80000
net.inet.ip.ipsec-soft-firstuse=3600
net.inet.ip.ipsec-firstuse=7200
net.inet.ip.ipsec-enc-alg=aes
net.inet.ip.ipsec-auth-alg=hmac-sha1
net.inet.ip.ipsec-comp-alg=deflate
# sysctl -a | grep ipcomp  
net.inet.ipcomp.enable=0

Now, we can go straight to the IKEv2 configuration. OpenBSD ship by default with the OpenIKED implementation; all important configuration parameters are located in /etc/iked.conf.

ikev2 "lab.n3network.ch-gre0" \
        esp proto gre \
        from 185.52.1.195 to 10.240.0.107 \
        peer 213.221.130.39 local 185.52.1.195 \
        ikesa enc aes-256 auth hmac-sha1 group modp1536 \
        childsa enc aes-256 auth hmac-sha1 \
        srcid er1.nl.n3network.ch \
        psk "ScMLFcEUMjZ/jGxx7+FgQw"
  1. The ikev2 keyword identify IKEv2 as the automatic keying protocol. A unique but optional name 'lab.n3network.ch-gre0' has been given to identify the policy.
  2. The second line defines the encapsulation, here Encapsulating Security Payload (ESP). Then the protected (or tunneled) upper-layer protocol which is in our case Generic Routing Encapsulation (GRE).
  3. The third line is a traffic selector, which identify the traffic flows to be protected in addition to the protocol we already defined in the second line. To resume, IPsec will generate a pair of security associations (SAs) for the GRE traffic between 185.52.1.195 and 10.240.0.107. These addresses may looks weird, in fact they are the addresses used inside the IPsec Tunnel, which explain why the Cisco CSR 1000v endpoint is a RFC1918 address.
  4. The fourth line identify the globally-reachable peers addresses used for the IKEv2 negotiation.
  5. Line 5 and 6 defines the modes and cryptographic transforms to be used in IKE (Phase1) and IPsec (Phase2) negotiations respectively.
  6. Line 7 provides the local peer's identifier. Here I chose to use a FQDN type identifier to ease identification of the peer at the other side of the IPsec session..
  7. Finally, line 8 simply provides the pre-shared key (PSK). I recommend to use a long string, with a length appropriate to the algorithms you are using.

The fifth line deserve another mention: I omitted the 'group' keyword because this connection is not using Perfect Forward Secrecy (PFS), a very important security and confidentiality feature. During my tests, I came across a number of issues, in particular with the support of some ciphers, therefore I had to use some weak one to first ensure both implementation were interoperable.

Now the IKEv2 service is configured, you can launch the daemon directly from the command-line using the ked -dvvv command. The process will output you the negotiation debug information which may be very useful in troubleshooting any outstanding issues.

Cisco CSR 1000v

For the purpose of the lab, the Cisco CSR 1000v router has been configured with one VRF, the latter being used initially for management purposes and also to connect the router outside of the lab, to the internet and further to provide IP reachability to the ER1 secure gateway. The global, default routing table will carry the VPN routes.

The first thing we must do, is to configure the IKEv2 (Phase1) proposals:

crypto ikev2 proposal dflt-ikev2-prop 
 encryption aes-cbc-256
 integrity sha1
 group 5

Next, we must define the IKEv2 policies:

crypto ikev2 policy ikev2-policy-01 
 match fvrf any
 proposal dflt-ikev2-prop

As you can see above, I used the special keyword any to define the front door VRF. I could have explicitly configured the 'management' VRF here, as the following will be used to host the IKEv2 negotiation.

We now define the pre-shared key (PSK) for our remote peer:

crypto ikev2 keyring nl.n3network.ch-key
 peer er1
  address 185.52.1.195
  pre-shared-key ScMLFcEUMjZ/jGxx7+FgQw

To complete the Phase1 configuration, we create an IKEv2 profile. The following regroups all the non-negociable parameters of the IKE security associations.

crypto ikev2 profile nl.n3network.ch-prof
 match fvrf any
 match identity remote address 185.52.1.195 255.255.255.255 
 match identity remote fqdn er1.nl.n3network.ch
 identity local address 10.240.0.107
 authentication remote pre-share
 authentication local pre-share
 keyring local nl.n3network.ch-key

Most of the above lines are relatively self explanatory. However, the two lines regarding the peer identities deserve some brief explanations: the local router is using an IPv4 address as a identifier; the remote endpoint who runs OpenIKED use a FQDN type identity by default, therefore we explicitly define it in our profile to ensure the latter is matched during the negotiation process.

The second part of our Cisco CSR 1000v configuration relate to IPsec (Phase 2).

We first define the IPsec transform set(s). These sets must usually match the same encryption and authentication algorithms, including the DH group we use in IKE or Phase 1 of the negocation process.

crypto ipsec transform-set esp-aes-256-sha esp-aes 256 esp-sha-hmac 
 mode tunnel

Last but not least, we configure the ipsec-isakmp crypto map. The latter defines the remote peer, the transform set and the IKEv2 profile we just configured, but more importantly, it defines with the help of an ACL, the traffic to protect. The ACL is directly used during the Phase 2 negotiation, therefore it must match at both ends of the IPsec session.

crypto map nl.n3network.ch-crypto 10 ipsec-isakmp 
 set peer 185.52.1.195
 set transform-set esp-aes-256-sha 
 set ikev2-profile nl.n3network.ch-prof
 match address nl.n3network.ch-protect

ip access-list extended nl.n3network.ch-protect
 permit gre host 10.240.0.107 host 185.52.1.195

The only operation that left to be done is to associate the above crypto map with an interface:

interface GigabitEthernet1
 description Dedicated Management Interface
 ip vrf forwarding management
 ip address 10.240.0.107 255.255.255.0
 negotiation auto
 crypto map nl.n3network.ch-crypto

The use of a crypto-map is not random. It's actually one of the only way to protect GRE traffic on Cisco IOS while maintaining full interoperability between multiple vendors implementations.

Now it's time to bring up our IPsec security-associations. You must generate some traffic to trigger the negotiation process:

R1#ping 10.6.250.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.6.250.2, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)

R1#sh crypto session 
Crypto session current status

Interface: GigabitEthernet1
Profile: nl.n3network.ch-prof
Session status: UP-ACTIVE     
Peer: 185.52.1.195 port 4500 
  Session ID: 1  
  IKEv2 SA: local 10.240.0.107/4500 remote 185.52.1.195/4500 Active 
  IPSEC FLOW: permit 47 host 10.240.0.107 host 185.52.1.195 
        Active SAs: 2, origin: crypto map

R1#ping 10.6.250.2   
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.6.250.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 32/35/42 ms

The session has been established as expected. We've now full IP reachability inside the tunnel, and a pair of IPsec security association as shown by the show crypto ipsec sa command:

R1#show crypto ipsec sa   

interface: GigabitEthernet1
    Crypto map tag: nl.n3network.ch-crypto, local addr 10.240.0.107

   protected vrf: management
   local  ident (addr/mask/prot/port): (10.240.0.107/255.255.255.255/47/0)
   remote ident (addr/mask/prot/port): (185.52.1.195/255.255.255.255/47/0)
   current_peer 185.52.1.195 port 4500
     PERMIT, flags={origin_is_acl,}
    #pkts encaps: 10572, #pkts encrypt: 10572, #pkts digest: 10572
    #pkts decaps: 10975, #pkts decrypt: 10975, #pkts verify: 10975
    #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.: 10.240.0.107, remote crypto endpt.: 185.52.1.195
     plaintext mtu 1422, path mtu 1500, ip mtu 1500, ip mtu idb GigabitEthernet1
     current outbound spi: 0xEAB4C3A2(3937715106)
     PFS (Y/N): N, DH group: none

     inbound esp sas:
      spi: 0x2505825A(621118042)
        transform: esp-256-aes esp-sha-hmac ,
        in use settings ={Tunnel UDP-Encaps, }
        conn id: 2014, flow_id: CSR:14, sibling_flags FFFFFFFF80000048, crypto map: nl.n3network.ch-crypto
        sa timing: remaining key lifetime (k/sec): (4607999/1516)
        IV size: 16 bytes
        replay detection support: Y
        Status: ACTIVE(ACTIVE)
          
     inbound ah sas:

     inbound pcp sas:

     outbound esp sas:
      spi: 0xEAB4C3A2(3937715106)
        transform: esp-256-aes esp-sha-hmac ,
        in use settings ={Tunnel UDP-Encaps, }
        conn id: 2013, flow_id: CSR:13, sibling_flags FFFFFFFF80000048, crypto map: nl.n3network.ch-crypto
        sa timing: remaining key lifetime (k/sec): (4607999/1516)
        IV size: 16 bytes
        replay detection support: Y
        Status: ACTIVE(ACTIVE)

     outbound ah sas:

     outbound pcp sas:

Recently, I decided to give the OpenBSD operating system another try. In fact, I didn't use it since a long time and I wanted to look at some recently introduced features. In a matter of 20 minutes, I had a working IPsec gateway and NAT/PAT router up and running, on what is supposed to be one of the most secure operating system.

This conclude this article on IPsec/IKEv2 configuration between a Cisco CSR 1000v and a gateway running OpenBSD's OpenIKED.

About the author Nicolas Chabbey

Nicolas Chabbey is a Network Engineer certified with Cisco Systems and Juniper Networks. He has begun his career in 2003, and has designed, implemented and maintained networks for enterprises and service providers. When he is not behind a computer, he is riding his mountain bike across the Swiss alps.

Previous Home Next

Comments

blog comments powered by Disqus