Project

General

Profile

Feature #2845

Support virtual XFRM interfaces added in 4.19

Added by Stijn Tintel 4 months ago. Updated 5 days ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Category:
-
Target version:
-
Start date:
30.11.2018
Due date:
Estimated time:
Resolution:

Description

See https://www.mail-archive.com/netdev@vger.kernel.org/msg239295.html
Would be nice if this can be supported in strongSwan.

xfrm-interface-cross-ns.patch (1.18 KB) xfrm-interface-cross-ns.patch Tobias Brunner, 13.02.2019 13:56
xfrm-interface-cross-ns-v2.patch (964 Bytes) xfrm-interface-cross-ns-v2.patch Tobias Brunner, 18.02.2019 10:20

History

#1 Updated by Roman Moschenski 3 months ago

Stijn Tintel wrote:

See https://www.mail-archive.com/netdev@vger.kernel.org/msg239295.html
Would be nice if this can be supported in strongSwan.

Would be great to have a strongswan support for this new kernel feature. If I understand that correctly, we have to extend add_policy_internal function (https://github.com/strongswan/strongswan/blob/master/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c#L2669) of the kernel_netlink plugin by passing a XFRMA_IF_ID beside of XFRMA_TMPL. That would add an ID of our virtual interface to the corresponding XFRM policy in the kernel:
https://github.com/torvalds/linux/blob/master/net/xfrm/xfrm_user.c#L1620
This feature could be a compile time flag to stay backwards compatible with older kernels or with kernels compiled with CONFIG_XFRM_INTERFACE=n

What do you think Tobias?

#2 Updated by Martin Willi 3 months ago

I have some plans to add XFRM interfaces support to strongSwan. No code and no schedule yet, though.

I guess the technical details about installing policies tied to interfaces are rather clear.
From a configuration perspective, we probably want to configure a (shared?) XFRM interface per CHILD_SA.

The question is what are the use cases and who is responsible for creating these interfaces (externally or strongSwan):

  • One of my use cases is certainly layer 3 master devices, to bind specific tunnels to certain VRF domains
  • Another nice use case could be passing XFRM interfaces into network namespaces, so a host can provide secured links to its containers
  • Most users probably just want IPsec interfaces for simplified firewalling

#3 Updated by Markus Sattler 2 months ago

I created some basic patch to allow to set the XFRMA_IF_ID via config.

the PR can be found here:
https://github.com/strongswan/strongswan/pull/122

#4 Updated by Tobias Brunner about 1 month ago

  • Status changed from New to Feedback

I pushed some patches to the 2845-xfrmi branch. They include a small utility that allows creating XFRM interfaces on newer kernels without having to patch iproute2.

I also did some tests, with the following findings:

  • We definitely want to set the interface ID on the SAs as well as on the policies because that...
    • ...allows duplicate policies (the functionality in the kernel is similar to that of marks, two policies can use the same selector as long as their interface ID is different)
    • ...lets inbound traffic pass. Without matching inbound policy (including the interface ID) traffic is otherwise dropped...
      • ...unless net.<ipv4|6>.conf.<xfrm-if>.disable_policy=1 is set to disable the inbound policy check on the XFRM interface (but that seems needlessly open)
    • ...prevents that the policies affect all matching traffic. Only with an ID are they specific to traffic routed to the associated XFRM interface (again that's similar to marks, where policies without them affect all packets and with only those that were previously marked)
  • It's possible to use different interfaces and IDs for in- and outbound traffic
    • That's why I added two configuration options and the ability to allocate unique interface IDs per CHILD_SA and per direction (similar to the in-/outbound marks)
  • It doesn't matter if a matching XFRM interface already exists when SAs are installed with a particular interface ID
    • That's why CHILD_SA-specific interfaces can easily be created in updown/vici scripts as long as the potentially unique interface ID is known (patches for this are included in the branch)
  • Routing traffic that doesn't match a policy to an XFRM interface has the following effect:
    • outbound: dropped counter of the interface increases, no errors in /proc/net/xfrm_stat
    • inbound: error/dropped counter does not increase, however, XfrmInNoPols in /proc/net/xfrm_stat does, unless the policy check is disabled (see above)
  • The physical interface that's associated with an XFRM interface doesn't seem to matter much (at least in our testing environment, where eth1 could be used on sun/moon even though the ESP packets are then exchanged over eth0)
    • Edit: If an outbound interface is configured in the child config, this is enforced (i.e. traffic is dropped if the associated physical interface does not match that of the policy)
  • The same XFRM interface can be shared by multiple SAs/policies (e.g. for all CHILD_SAs created by multiple roadwarriors)
  • Using trap policies in combination with XFRM interfaces is possible
  • IPComp can be used

Another nice use case could be passing XFRM interfaces into network namespaces, so a host can provide secured links to its containers

I tried that. However, it currently only works partially (4.20 kernel). While it works fine for outbound traffic, it currently doesn't for inbound traffic. It seems the XFRM interface is stored in a list that's associated with the original netns and for inbound traffic the lookup uses the current netns (i.e. the one the interface was moved to), so no XFRM interface is found and the packet is dropped. So it looks like this requires a kernel patch.

One of my use cases is certainly layer 3 master devices, to bind specific tunnels to certain VRF domains

How would such a scenario look like exactly?

#5 Updated by Tobias Brunner about 1 month ago

Attached a hackish kernel patch for the cross network namespace issue. Edit: A better patch can be found below.

#6 Updated by Martin Willi about 1 month ago

I pushed some patches to the 2845-xfrmi branch. [...]
I also did some tests, with the following findings:

Thanks for your work on this, and for sharing your findings. Sounds promising so far.

One of my use cases is certainly layer 3 master devices, to bind specific tunnels to certain VRF domains

How would such a scenario look like exactly?

The idea is to bind one or more tunnels to a VRF domain using layer 3 master devices. This would allow proper separation of traffic flows, for example when using a multi-tenancy capable IPsec gateway. So for each customer, one would have an xfrmi associated to a dedicated physical or VLAN internal interface, where traffic is forwarded to/from:

          +-------+  +-----------+  +--------+
external  | xfrmi |--| L3 master |--| VLAN-X | internal network
encrypted +-------+  +-----------+  +--------+ plain
                          |
                    +------------+
                    | associated |
                    |  routing   |
                    |   table    |
                    +------------+

As the customer tunnel configuration defines the xfrmi and indirectly the VRF domain, we can provide IPsec for multiple customers using a single public IP. Also, the different customers can even use overlapping subnets.

I guess this can be achieved also by namespacing the xfrmi and the associated internal interface, but VRFs might be somewhat simpler from an administration perspective.

#7 Updated by Roman Moschenski about 1 month ago

Great work! Have I to use vici/swanctl.conf ? No way to add new parameters (if_id_in, if_id_out) in ipsec.conf ?

#8 Updated by Tobias Brunner about 1 month ago

Thanks for the explanation Martin. I'd have to look into that VRF stuff at some point.

Have I to use vici/swanctl.conf ? No way to add new parameters (if_id_in, if_id_out) in ipsec.conf ?

Yes and no (ipsec.conf is deprecated, no new features will be added).

#9 Updated by Tobias Brunner about 1 month ago

Better kernel patch for the cross namespace issue (also against 4.20, for 5.0 the skb->sp check has to be replaced with secpath_exists()). Edit: The 5.0 kernel contains this patch. For 4.19 and 4.20 kernels it's still required to fix this issue (unless it gets backported).

#10 Updated by Roman Moschenski about 1 month ago

Do you plan to include these new patches in 2845-xfrmi branch in to a new strongswan release?

#11 Updated by Eyal Birger 5 days ago

For a responder it would be nice if there were an option for the if_id to be allocated per IKE SA so that all child SAs of the same IKE SA could share the same if_id.

Also available in: Atom PDF