[Swan] ike_frag= options - what should it mean and do?

Wolfgang Nothdurft wolfgang at linogate.de
Thu Feb 14 13:29:18 EET 2013


Am 14.02.2013 06:37, schrieb Paul Wouters:
>
> Hi
>
> So we implemented IKE fragments, but there are some unanswered questions
> on the design when the options don't match up. We have to make some
> decisions, for which I would like some input from others.
>
> currently we have:
>
> ike_frag=no|yes|force with the default being yes
>
> - When yes or force, send the FRAGMENTATION vendorid
> - When yes, on retransmit for packets > FRAG_LEN, send in fragments
> - when force, don't wait for retransmit, do it right away (and don't
> care about seeing vendorid)
> - When no, don't send vendorids, dont send fragments (but assemble
>    received fragments)
>
> These do not seem the right choices now that we are doing some tests
>
> Image your roadwarrior "road" knows it is on bad a network. It can set
> ike_frag=force so it does not have to wait on that one retransmit. But
> the other end does not use force, so on its answer, there is a still a
> packet being lost and re-transmitted. This could be resolved if we not
> only remember receiving a vendorid, but also remember if the peer has
> sent us fragments. If so, we should probably assume the link problem is
> symmetrical and fragment immediately instead of waiting on a retransmit.
>
> My thoughts right now are leaning towards:
>
> - Never ignore vendorid. If we don't see it from the peer, don't send
>    fragments.
> - When using force, fragment without waiting for a retransmit
> - When using yes, fragment when retransmitting if vendorid was seen, or
>    fragment immediately when we received fragments from the peer already.
> - When using no, don't send fragmentation vendorid and don't send
>    fragments. (be Postel on receiving fragments)
>
> There is the corner case of not seeing a vendorid but receiving
> fragments. I don't know of any such implementations. However, currently
> we never refuse to assemble fragments, even if we did not see a
> vendorid. This _could_ become a security issue, although the code is
> pretty restrictive. We don't allow more then 16 fragments before giving
> up. Worst case they give us a 552*16 garbled IKE packet, but they might
> as well send us 1500+ byte garbled IKE packets...
>
> What racoon has for yes/no/force is kinda strange to me:
>
>               ike_frag (on | off | force);
>                       Enable receiver-side IKE fragmentation if
> racoon(8) has been built with this feature.  If set to on, racoon will
>                       advertise itself as being capable of receiving
> packets split by IKE fragmentation.  This extension is there to
>                       work around broken firewalls that do not work with
> fragmented UDP packets.  IKE fragmentation is always enabled
>                       on the sender-side, and it is used if the peer
> advertises itself as IKE fragmentation capable.  By selecting
>                       force, IKE Fragmentation will be used when racoon
> is acting as the initiator even before the remote peer has
>                       advertised itself as IKE fragmentation capable.
>
> Having the on/off be different for receiver/sender seems weird to me.
>
> Note that on the first packet of an exchange, we cannot reassmble
> because we have no state object to match it with, so we currently
> don't support that and the packet is lost. However, the first packet
> is never that big, and if you cannot do UDP packets of say 1200 MTU,
> then even establishing the tunnel will be pretty useless, as all traffic
> in that tunnel will hit an even worse MTU limit (due to ESPinUDP and
> tunnel mode overhead)
>
> Thoughts?

I'm with you in the most cases.
But all optimization on one side doesn't help, if the peer uses its own 
standard.

I think a discussion about the max frag size is senseless, because 
cisco, microsoft and maybe others uses 552 for ikev1.
Did you really get a huge speed increase if you use 1200 instead.
With 552 it is guaranteed that the negotiation works in all cases.
If the connection than is really slow, because of a very low mtu is 
another problem, where the user have to decide how to solve it (e.g. buy 
a non broken router ;) ), but the connection itself work.
Otherwise you have make it configurable or detect it dynamically, which 
make it more complicated.

For security reasons, we can restrict the ike fragments to MAIN_I3 and 
MAIN_R3, where it is only needed.
The first packet can be exceed 552 bytes also, but can't be handled 
because of no state.
We could implement something like a new intermediate state MAIN_R1_FRAG 
to handle the first fragments, but I don't think other implementations 
handle this as well. So also senseless.

So my suggestions are:

no or disabled:
* no fragmentation at all
* log if the peer send fragments anyway

yes or enabled:
* send vendorid
* handle fragments
* decrease retransmit timers to at least 5 seconds to speed up negotiation
* send fragments direct, if we already get fragments

always:
* if the peer support fragments send always fragments

and maybe:

force or debug: (only for debug purposes)
* send fragments even if the peer doesn't announced to support it


Wolfgang


More information about the Swan mailing list