[Swan-dev] the coding twine holding end's .host_addr, .client, .port, .protocol and .has_client together

Paul Wouters paul at nohats.ca
Fri Mar 5 19:52:24 UTC 2021


On Fri, 5 Mar 2021, Andrew Cagney wrote:

>>> The original idea was that connections were immutable -- all changes were in state objects.
>
> I think that explains:
> -       /* my stuff */
> -
> -       /* Phase 2 ID payload info about my user */
> -       uint8_t st_myuserprotoid;             /* IDcx.protoid */
> -       uint16_t st_myuserport;
p
> -       /* peers stuff */

[...]

Yes.

>> This is what is basically happening with labeled IPsec. You configure
>> one security label. You install this policy, and when you get a %trap,
>> it is not for this label but for a "more narrow" label. We should
>> instantiate the connection with this updated label and bring it up.
>>
>> That way, each label gets its own IPsec SA, which is the goal of
>> labeled IPsec. The other end can then re-mark these packets with
>> the same label (that did not travel across the network otherwise)
>>
>> The odd thing is that if the first connection is auto=start and not
>> auto=ondemand (aka auto=route) then you do not get an ACQUIRE and
>> you can only install the configured label, which actually never gets
>> an ACQUIRE itself. But it is harmless.
>>
>> The IKEv1 code did this, but without using CK_TEMPLATE and CK_INSTANCE.
>> It kind of abused the CK_PERMANENT type connection. The core libreswan
>> devs thought this was all a bug and it should setup just 1 connection.
>> We only recently understood the full design explained above. But it was
>> too late to rewrite this into proper instantiating connections and
>> template. But, that is what we should be doing.
>>
>> The old IKEv1 code ended up with multiple connections of CK_PERMANENT,
>> where there was 1 set of SPD policies and multiple sets of SPD state.
>> Apparently, the kernel would match the states with the security label,
>> despite the policy having the wider label only. This worked due to
>> some kernel magic. The reqid for all of these states are the same,
>> but the label is different, so the kernel manages to find the right
>> one despite this. But I doubt the kernel model is meant to be used
>> in this way either,

We had another talk about this and while this is true, there is a subtle
thing here. They might be adding 10s of thousands of these. And all of
these have basically the same policy IP/proto/port wise and only differ
in security label. The kernel however, does its matching of label to
the xfrm state regardless of the policy. It's kind of a side-check on
the SPD policies. So, with that implementation, it can actually use
a single SPD policy set (in/out/fwd) with many SPD states. This would
strongly reduce the SPD policy lookup since instead of many thousands,
there would be only one. This slightly deviates from the libreswan
model, but with some checks for labels on the connection configuration,
we should be able to do this. Eg to prevent the Nth connection going
down from taking down the shared SPD policies.

>> But our code for instantiation seems to have a buildin assumption that
>> it only instantiates for incoming connections (aka roadwarriors) or
>> for OE group instances. The narrowing=yes code also causes a connection
>> to turn into a CK_TEMPLATE, and there are some hacks to make that work
>> properly. But the support for this is a hack - the code assumes there
>> is still only ever 1 connection that is just narrowed from the
>> configuration, while full proper narrowing support would allow multiple
>> instances that cover part of the original CK_TEMPLATE IP/port ranges of
>> the connection.

Perhaps we need a new CK_LABELCONN and CK_NARROWED type connections to
properly support these? Where the first type uses a shared SPD policy
(aka eroute) and the second uses fully seperate IPsec SA's (state+policy)

Although the users of the labeled IPsec code, did seem to think that
perhaps in the future, combining these two would be a good idea too.
Possibly to do Opportunistic style narroing of 0.0.0.0/0 to a specific
/32 to /32, while also subdiving that again over 1 Child SA per SElinux
domain. Then we are back to perhaps using POLICY_ bits ?

Paul


More information about the Swan-dev mailing list