Subject: [IPsec] collison during initial exchange - RFC 5996

From: "Prashant Batra (prbatra)" <[email-masked]>
Date: Fri, 16 Dec 2011 17:35:57 +0530

Hi,

I have a question on possible collision that can occur during initial
exchange (INIT). 

If two peers send INIT_REQ at the same time,

maybe  because of some data which matches the traffic_selector on both
the peers, how a peer should decide whether it has to drop 

the request and wait for the response or send the response for this
request.

This is similar to collision in case of IKE_REKEY, but I could not find
any text in RFC 5996 to handle this scenario.

Regards,

Prashant

---

From: Tero Kivinen <[email-masked]>
Date: Fri, 16 Dec 2011 15:55:09 +0200

> the request and wait for the response or send the response for this

This is not collision, as there is no way to detect this at
IKE_SA_INIT phase. We do not know wheter the identities used are going
to be the same.

Implementations should simply continue processing both requests and
create two separate IKE SAs. 

> any text in RFC 5996 to handle this scenario.

This is different from IKE_REKEY collision, as here we create two
overlapping IKE (and most likely also Child) SAs. This is completely
valid and allowed by the RFC5996, and there is no need to delete
either one of them. The reason IKE_REKEY etc needs special checks for
the collisions is to ensure that Child SAs are moved to the correct
IKE SA after the rekey, and that the number of IKE SAs would not
multiply after each rekey (i.e. if each IKE SA rekey could potentially
create 2 new IKE SAs, which each of them could again be rekeyed and
potentially create 2 more (in total of 4) IKE SAs etc).

In the initial connection case there is no possiblity for that as
after the peers do have IKE SAs up they use normal rekey procedure
which does include collision detection, so the worst case scenario is
that those two IKE SAs stay up and both of them will get rekeyed as
normally.

Note, that INITIAL_CONTACT notification can also make situation
different. In this kind of situation where both ends does simultaneous
connect, both ends are likely to include INITIAL_CONTACT notification
too.

Now if one of the IKE_AUTH exchanges finishes first, then when the
later exchange will notice that there is old IKE SA between the same
authenticated identities, and will silently remove that older first
IKE SA (and Child SA) and create new second one. This will cause the
first peer to send packets to SAs which have already been deleted,
which will cause the receiving peer to send INVALID_SPI message inside
the surviving 2nd IKE SA, thus deleting the first Child SA. In this
case the first peer will then most likely move its traffic to the
surving 2nd Child SA, and later also delete the IKE SA when it times
out.

If first peer is sending IKE packets to the IKE SA which have already
been deleted, then second peer will reply with INVALID_IKE_SPI outside
the IKE SAs, and then first peer will delete its IKE SA (after
timeout) and will most likely move to use the surviving IKE SA and
Child SA.

If the IKE_AUTH exchanges are processed simultaneously then neither
end has IKE SAs between the peers, as both of the IKE SAs are still in
the process of being created. Neither end deleteds IKE SAs, thus this
will cause two IKE SAs to be created (which again is not a problem).
It is important that INITIAL_CONTACT processing do not remove half
created IKE SAs, only fully connected IKE SAs, as otherwise in this
case the both ends would delete the IKE SAs and then the whole process
would start over.
-- 
[email-masked]

---

From: Suresh Melam <[email-masked]>
Date: Fri, 16 Dec 2011 17:41:50 -0800

Ending up with two IKE SAs, may not be an issue in terms of functionality,
but can be seen as an issue in terms of scalability.

Can we come up with a "standard" way of discarding the extraneous IKE SA,
so that both peers will discard the "same" extraneous SA?  Any non standard
method to discard, may end up in two peers discarding both the SAs.

It may also be just plain confusing to the end user, as you mentioned
below, in a scenario with two CHILD SAs negotiated from two IKE SAs can
continue to rekey forever, and then one peer may use one CHILD SA for its
outgoing traffic whereas other peer use the "other" CHILD SA for its
outgoing traffic.

Again not a functionality issue, but could be seen as an usability issue.

thanks,
-suresh

On Fri, Dec 16, 2011 at 05:55:09AM -0800, Tero Kivinen wrote:
> _______________________________________________
> IPsec mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/ipsec

---

From: Tero Kivinen <[email-masked]>
Date: Mon, 19 Dec 2011 16:14:56 +0200

> but can be seen as an issue in terms of scalability.

I do not think so. I do not think this is very common situation
hapening in the wild. It can happen if both ends decide to try to
connect to each other exactly at the same time, which is usually not
so common.

The more common situation is that the network breaks down and both
ends drop connections, and then connection come up again, and both
ends try to reconnect, but in this situation this kind of thing can be
solved by good implementation solutions, like using random backoff,
jitter in the connections, checking out whether other end has already
started connecting to us before starting to connect to them etc, or
using different timers depending whether the original lost connection
was initiated by this end or other end.

As this kind of timing issues usually only happen (in large scale)
between very similar implementations (i.e. both ends are from same
vendor) it is usually enough to have vendor specific implementation
solution for this.

> method to discard, may end up in two peers discarding both the SAs.

There is no way to know they are really extraneous, as it is
completely legal for other end to create two IKE SAs if he feels like
it. So neither one of them is extraneous in that sense. 

> outgoing traffic whereas other peer use the "other" CHILD SA for its

End user does not see any difference. For end user his traffic just
goes through and thats it. End users should not see IKE SAs or Child
SAs.... 

> Again not a functionality issue, but could be seen as an usability

Which can be solved by good engineering solutions in the vendors
implementations. For example if this is really a scalability issue for
the scenario, then the vendor having scalability problems can detect
this situation and move his Child SAs from his own IKE SA to the other
ends IKE SA, and when that is done (and ole Child SAs have been
deleted) delete the old IKE SA. Again the implementation needs to add
jitter and bias to make sure that if two of the same vendors
implementations are talking to each other, both ends do not start
doing this simultaneously. 
-- 
[email-masked]

---

From: Praveen Sathyanarayan <[email-masked]>
Date: Mon, 19 Dec 2011 12:16:12 -0800

Hi Tero,

Looks like there were few discussion happened on this topic while writing
RFC 5996. Why it was not noted in RFC? Even if it was not decided to
address it in RFC, I think there is a good value to note it.

I have few more comments inline.

-- Praveen

On 12/19/11 6:14 AM, "Tero Kivinen" <[email-masked]> wrote:

ends try to reconnect,

[PRAVEEN] It is not very common, but common enough. We have seen several
customer running into it. Again this is more of scalability issue. Takes
more CPU and memory in maintaining this extraneous SAs. Also it is a
source of confusion for several customers.

 but in this situation this kind of thing can be

[PRAVEEN] Are you suggesting that add jitter before triggering the
negotiation? If so, it is not practical. Adding jitter will result in
packet loss. If you are suggesting jitter in state m/c (delay in
responding to 2nd or 3rd packet so that one of the negotiation will be
completed soon), then it should be done only after authenticating peer
(for security reasons). And this can be too late in IKEv2 (as there are
only 2 pair of exchange). Thus I don't see a practical solution for it.
IMO, we should let negotiation to complete and come up with tie breaker to
cleanup extraneous SAs.

[PRAVEEN] In our opinion, there should be a optional standard way of
cleaning up extraneous SAs. It is shouldn't be mandatory but it can be
optional. Vendor can decide if they want to implement it or not. I believe
there are vendors already doing it in non standard way if both devices
belongs to same vendor.

---

From: "Valery Smyslov" <[email-masked]>
Date: Tue, 20 Dec 2011 10:35:36 +0300

Hi,

section 2.25.2 describes some rules to deal with IKE SA close and rekey collisions.
In particular, it states:

   If a peer receives a request to close an IKE SA that it is currently
   rekeying, it SHOULD reply as usual, and forget about its own rekeying
   request.  

Following this rule may lead to situation when IKE SA states become out of sync.
Consider the following example:

   Host A                      Host B
   -------------------------------------------------------------------
   send req1:
        SA(..,SPIa1,..),Ni1,.. -->
                             --> recv req1
                             <-- send resp1: SA(..,SPIb2,..),Nr2,.. (lost)

Consider the situation when resp1 get lost. At this point
Host B thinks that old SA is successfully rekeyed.
And if it has any reason to close it (for example, its
lifetime is over and Host B was about to start its 
rekeying by itself unless it noticed that Host A has
already done it), it will safely (as it thinks) make 
close request. 

                             <-- send req2 D()
   recv resq2 <--

>From Host A's point of view this is exactly the situation
described in 2.25.2. According to the given rule it replies
as usual to req2 and forgets about its req1.

   resend resp2 -->
                                -->  recv resp2

As a result - old IKE SA is closed, but the two peers
have different views on its successor- Host A thinks
that old SA wasn't rekeyed at all and kills its Child SAs, 
while Host B thinks it was successfully rekeyed and all its 
Child SAs survived.

>From my point of view correct rule for this situation should be:

    If a peer receives a request to close an IKE SA that it is currently
    rekeying and it did notice simultaneous rekey, it SHOULD reply 
    as usual, and forget about its own rekeying request.

    If a peer receives a request to close an IKE SA that it is currently
    rekeying and it didn't notice simultaneous rekey, it SHOULD 
    postpone to reply to this request untill its own rekeying request 
    is completed (successfully or not).

Regards,
Valery Smyslov.

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 20 Dec 2011 14:38:05 +0200

> source of confusion for several customers.

If it is ont very common, it should not really affect scalability, I
mean you should not design system so that adding 1% of more SAs will
cause it to run out of CPU or memory... And if this happens more than
1% of all IKE SA, then I think there is something in the scenario or
implementation which causes it to happen.

> packet loss.

Adding jitter before triggering after the connection has been lost
because network breakdown should not affect that much. When the
network connection broke down you already lost packets regardless what
you did. The only way I could think how this could happen a bit more
often is the case where there is already IPsec connection between the
peers, and networks breaks down, and both ends try to reconnect the
IKE SA simultaneously. 

> If you are suggesting jitter in state m/c (delay in responding to

m/c? No idea what that state is.

> 2nd or 3rd packet so that one of the negotiation will be completed
> soon), then it should be done only after authenticating peer (for
> security reasons). And this can be too late in IKEv2 (as there are
> only 2 pair of exchange). 

I was suggesting jittering and random backoff for the retransmissions
of the IKE SA INIT. I.e. when the network comes up again after the
break, both ends (or only one end) might detect that link came up and
it might want to add some random 2 second jitter before retransmission
of its packet.

> Thus I don't see a practical solution for it. IMO, we should let
> negotiation to complete and come up with tie breaker to cleanup
> extraneous SAs.

As I do not think this is problem really happening that often, that
adding special code for it will most likely just cause more problems
than solve issues. For example I am not sure how many implementations
actually implement the current simultaneous exchanges stuff we have in
the RFC5996. My guess is that there are several implementations
implementing at least some parts of it, but not that many who
implement every single parts of it.

> there are vendors already doing it in non standard way if both devices

And I think this kind of solution is best to be left to the vendors.
Especially if we do not mandate it, then either end still needs to be
able to cope with implementations not implementing it. Having vendors
specific way of solving this is fine, as this kind of timing issues
mostly only occur when you have two similar implementations (i.e. from
same vendor) talking to each other. Usually different vendors use so
different timers, and jitters etc that this kind of problems do not
occur between implementations of different vendors.
-- 
[email-masked]

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 20 Dec 2011 15:02:38 +0200

> Consider the following example:

RFC 5996 section 2.8 says:

              After the new equivalent IKE SA is created, the initiator
   deletes the old IKE SA, and the Delete payload to delete itself MUST
   be the last request sent over the old IKE SA.

I.e. host B is not supposed to delete the IKE SA, it is supposed to
wait for the host A to delete the SA. This is required as otherwise
host B does not know whether the Host A received the its IKE SA rekey
response. When the host A send delete on the old IKE SA, host B will
know that the host A has finished the rekey, and the old IKE SA can be
deleted.

So here host B is not following the RFC5996 and that causes the
problem. 

> while Host B thinks it was successfully rekeyed and all its 

I think host B never should start any new operations on the old IKE
SA after it has been rekeyed. I.e. when host B notices that old IKE SA
has (from its point of view) being rekeyed, it should not send
any new requests through it. It should always use the new IKE SA.

On the other hand if host B has already decided to delete the IKE SA,
and his request has for example got lost before it receives the IKE SA
rekey, it should fail the rekey request with TEMPORARY_FAILURE
(2.25.2, first paragraph, last sentence: "If a peer receives a request
to rekey an IKE SA that it is currently trying to close, it SHOULD
reply with TEMPORARY_FAILURE.")

>     is completed (successfully or not).

I think the correct solution is to say that peer should not send any
new exchanges through the IKE SA the other end has already rekeyed. It
can only wait for its older requests to finish, and wait for the other
end (the one who initiated the IKE SA rekey) to delete the old IKE SA.

Currently we only have "SHOULD NOT start new CREATE_CHILD_SA
exchanges" (section 1.3.2):

                             Once a peer receives a request to rekey an
   IKE SA or sends a request to rekey an IKE SA, it SHOULD NOT start any
   new CREATE_CHILD_SA exchanges on the IKE SA that is being rekeyed.

I think this should really have been

                             Once a peer receives a request to rekey an
   IKE SA or sends a request to rekey an IKE SA, it SHOULD NOT start any
   new exchanges on the IKE SA that is being rekeyed (except the final
   IKE SA delete from the peer who initiated IKE SA rekey).

I.e. SHOULD NOT start any new exchanges, not only CREATE_CHILD_SA
exchanges. 
-- 
[email-masked]