In the last article, we configured a site-to-site (or LAN-to-LAN) VPN tunnel between two Cisco IOS routers using IKEv2 and crypto maps. In this article, we will turn on debugging while the VPN tunnel is being built so that we can see how IKEv2 works behind the scenes.

The topology from our last article is as shown below:

Just to give a recap of our configuration: we used the default IKEv2 proposal, policy and IPsec transform-set. We configured PSK for authentication under our IKEv2 profile and attached this profile to a crypto map. You can copy the configuration from the previous article.

As I mentioned in the introduction to this series, IKEv2 makes use of four different messages: IKE_SA_INIT, IKE_AUTH, CREATE_CHILD_SA and INFORMATIONAL. For the initial negotiation of SAs, two exchanges usually occur: a pair of IKE_SA_INIT messages and a pair of IKE_AUTH messages. Most of the time, these exchanges are enough to also set up the first Child SA, but there are times when variations will occur e.g. two pairs of IKE_SA_INIT messages instead one.

Let’s now go into the debugging. I will turn on IKEv2 debugging on one of the routers (R1) using the debug crypto ikev2 command. I will then initiate a ping to 192.168.20.2 from R1’s Loopback 0 interface.

IKE_SA_INIT Exchange

The IKE_SA_INIT exchange is used to negotiate the cryptographic algorithms, exchange nonces, and do Diffie-Hellman exchange (RFC 5996). When a router receives a packet that matches traffic to be protected, it will generate the first IKE_SA_INIT message and send it to the other peer (responder).

Looking at the debug output above, you can see that the initiator computes a DH public key and then generates an IKE_SA_INIT message that includes all the transforms it supports. This IKE_SA_INIT packet is sent to the peer 10.0.0.2 (R2).

The header of that packet contains the initiator’s SPI, which is “F7FFCF9CF569BFC2” in our case. Since the initiator does not yet know the SPI of the responder, it sets it to all 0s. Also notice a field called “Message id,” which is currently set to 0: This field is used to match response messages to request messages and also to identity retransmissions of messages. This means that the IKE_SA_INIT response message from R2 should have a message ID of 0.

We also see that this IKE_SA_INIT message is a request message that contains the following payloads:

  • Security association (SA) contains the transforms that the initiator supports, e.g., AES_CBC_256, SHA512, etc.
  • Key exchange (KE) contains the DH public key generated by the initiator,
  • The initiator’s nonce (N)
  • Vendor ID (VID) and
  • NOTIFY payloads used for NAT detection in this case.

The snapshot below shows what this IKE_SA_INIT packet looks like in Wireshark:

If all goes well, the responder will send back the second IKE_SA_INIT message, completing the IKE_SA_INIT exchange. Notice from the debug output below that R1 received an IKE_SA_INIT response message from R2.

As you can see, the responder SPI now contains a value, “9CC9B8A97A11E049” and the message ID of 0 tells R1 that this is the response to the IKE_SA_INIT message R1 sent. This message contains the SA payload which informs R1 about the cryptographic algorithm that the responder has chosen; the DH public key of the responder; the responder’s nonce and other payloads like Vendor ID and notify payloads.

Note: There may be instances when an error occurs and the responder sends back an IKE_SA_INIT with an error payload. For example, since the DH public key generated by the initiator is carried in the first message, it means the initiator had to guess what DH group to use to generate this public key, i.e., what DH group the responder will select. If the responder is configured to use another DH group, then it will send a notify payload of type INVALID_KE_PAYLOAD informing the initiator of which group it has selected.

Upon receipt and verification of the IKE_SA_INIT response message, the initiator now generates its own DH secret key and also “SKEYSEED,” which is used to derive all cryptographic keys for the IKE SA.

With this, the IKE_SA_INIT exchange is now complete and all other messages that follow (except the headers) are encrypted.

IKE_AUTH Exchange

This exchange is used to exchange identities, authenticate peers, and also establish the first Child SA.

Looking at the payload contents of this IKE_AUTH message, we see the IDi (identity of initiator) payload, which will be 10.0.0.1. The SA payload starts the negotiation of the child SA and it contains the transforms specified in our IPsec transform-set (i.e. AES and SHA). The TSi (traffic selector-initiator) and TSr (traffic selector-responder) payloads contain the range of addresses for which traffic to/from such addresses should be encrypted. In our case, the TSi and TSr payloads will look something like:

You will also see that the Payload contents are shown as “ENCR,” meaning they are encrypted. We can actually see the unencrypted contents of the packet on the router by debugging IKEv2 packets using the command debug crypto ikev2 packet. You can do that in your own lab because it would have been too verbose for this article.

If all is acceptable to the responder, it will also send its own IKE_AUTH message which will complete the IKE_AUTH Exchange. The IPsec SA is then created and we see that the ping traffic was successful.

CREATE_CHILD_SA Exchange

The CREATE_CHILD_SA exchange is used to create new Child SAs and also to rekey both IKE SAs and Child SAs. In our scenario, the first Child SA was created during the IKE_AUTH exchange. We can verify this by looking at the show crypto ikev2 session output.

To see a CREATE_CHILD_SA exchange, there are two things we can do:

  1. We can wait for the rekey to happen or we can set the lifetime under the IKEv2 profile to a small value, e.g., 120 seconds. This will trigger the CREATE_CHILD_SA exchange for rekeying.
  2. We can add another entry under the crypto map ACL and then initiate traffic to this new entry. This will trigger the CREATE_CHILD_SA exchange to create a new child SA.

We will use the first method for simplicity’s sake. The configuration on both routers is as follows:

crypto ikev2 profile R1-R2-PROFILE
lifetime 120

You can clear the previous IKE SA using the clear crypto ikev2 sa command so that the new configuration will take effect. When the IKE SA has been formed (e.g., by pinging between R1 and R2’s Lo0 interfaces), then the rekey will take place after some time as shown below:

INFORMATIONAL Exchange

The INFORMATIONAL Exchange can be used to send notifications or errors of events. A common use of this exchange is to delete an existing SA. In the screenshot below, after the rekey took place, the previous IKE SA was deleted using the INFORMATIONAL exchange:

Summary

This brings us to the end of this article, in which we have seen the different exchanges used in IKEv2. In your own lab, you should turn on IKEv2 packet debugging so that you can see the contents of the packets as they are sent and received.

I hope you have found this article insightful.

References and Further Reading