Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPsec mechanism support #638

Closed
glazychev-art opened this issue Sep 9, 2022 · 13 comments
Closed

Add IPsec mechanism support #638

glazychev-art opened this issue Sep 9, 2022 · 13 comments
Assignees
Labels
enhancement New feature or request

Comments

@glazychev-art
Copy link
Contributor

glazychev-art commented Sep 9, 2022

Description

Depends on: networkservicemesh/api#149

Explore how to use VPP to integrate IPsec protocol

@glazychev-art glazychev-art added the enhancement New feature or request label Sep 9, 2022
@glazychev-art glazychev-art self-assigned this Sep 22, 2022
@glazychev-art
Copy link
Contributor Author

glazychev-art commented Sep 23, 2022

@edwarnicke
There are a couple of questions regarding the implementation:

  1. Do I understand correctly that we should use IKEv2 for IPSec?
  2. How will we choose an IP protocol if we have a choice: Wireguard or IPSec? Do you have any thoughts?

@glazychev-art
Copy link
Contributor Author

@edwarnicke
Is it really not enough for us to use the built-in VPP IKEv2?
I see several problems with - https://gerrit.fd.io/r/c/vpp/+/36552

  1. This is a new plugin for VPP and so far this does not work on the fly (I've tried to run docker examples).
  2. It is not clear how the interfaces will be configured - we will have to configure both the VPP and the strongSwan kernel side. And for the latter, we will need some kind of go-package.
  3. We need to update VPP to the latest version. But as we remember, we are very dependent on Calico-VPP, which uses the old version. And I think it will not be possible to solve this issue with patches because of the huge number of conflicts.

@glazychev-art
Copy link
Contributor Author

@edwarnicke
I work with built-in IKEv2 plugin, and faced the problem.
IKEv2 uses ipip tunnel by default - https://github.com/FDio/vpp/blob/master/src/plugins/ikev2/ikev2.c#L2001.
In order to properly get the state of the tunnel, I create it myself and then protect it.

The problem is that we can only create one tunnel between forwarders. Because the ipip-tunnel has only two main parameters - srcIP and dstIP. How do we deal with multiple clients? How to do cross-connect?
The IKEv2 protocol has a traffic-selector, but I'm not sure if it covers all cases.
Ipip tunnels can be placed in different fib-tables, do we need to look in this direction?

@glazychev-art
Copy link
Contributor Author

There was an idea to check GRE tunnel. Unfortunately, it seems that VPP does not support full functionality - https://datatracker.ietf.org/doc/html/rfc2890. I think Key field would help, it would allow to create many tunnels with the same Src and Dst addresses.
But it is not used in VPP - https://github.com/FDio/vpp/blob/master/src/vnet/gre/packet.h#L38-L56

@glazychev-art
Copy link
Contributor Author

@edwarnicke
Based on the IPIP-tunnel issue we have options:

  1. Modify VPP GRE tunnel and add Key field support (as described in the spec - https://datatracker.ietf.org/doc/html/rfc2890).
  2. Use different fib-tables for different IPIP tunnels. Please note, all current interfaces are using default fib table (index 0). This will require a rework of cross-connects, routing...
  3. Your option

@glazychev-art
Copy link
Contributor Author

@edwarnicke
I checked the possibility of using different UDP ports for different tunnels - I'm not sure if this is possible. We are protecting the already created tunnel. IPIP does not allow us to assign ports.

But, I found a replacement for ipip tunnels - https://github.com/FDio/vpp/blob/master/src/vnet/ipsec/ipsec.api#L348

@gmslabs
Copy link

gmslabs commented Nov 22, 2022

Hi! Sorry for asking, why would you like multiple ports for different tunnels? The tunnel are distinguished by the SA assigned.

The only reason I see for a need to control the ports is for nat traversal or passing traffic on udp.

In any case, by default ipsec is assumed to be set on 4500, 500.

@gmslabs
Copy link

gmslabs commented Nov 22, 2022

One more thing, if in the future we would like to allow connectivity from a “virtual NSC” - lets say something like a pre-configured IPsec capable device( sdwan devices, firewalls, etc) Strongswan’s IKE daemon is more generic, stable and has better support for other 3rd party devices than the one built in vpp - the vppswan plugin is good (in theory) as it keeps the esp datapath in vpp (for far better performance) while allowing to punt the ike to sswan.

@glazychev-art
Copy link
Contributor Author

@gmslabs
Thanks for your interest in this feature!

why would you like multiple ports for different tunnels?

It was just an idea how to distinguish tunnels. This was solved by using ipsec underlying tunnel instead of ipip (why vpp manuals only point to ipip?)

Strongswan’s IKE daemon is more generic

Yes, we thought about that too. And I tried to run it, but it did not work for me (I saw that additional fixes were made later).

But the main problem in my opinion is that we need to configure both the host and the vpp part (if I understand the plugin correctly).
For example, for our kernel mechanisms, we have netlink package. Is there anything for strongswan?
In my opinion, this is an tricky task, how to maintain several tunnels and, for example, a healing feature.

@gmslabs
Copy link

gmslabs commented Nov 22, 2022

Hi @glazychev-art , thanks for the quick response!

For example, for our kernel mechanisms, we have netlink package. Is there anything for strongswan?

from my experience a good way to programmatically manage sswan’s ike daemon is by using the vici interface -
https://github.com/strongswan/govici

@glazychev-art
Copy link
Contributor Author

Thanks @gmslabs ,

I started looking at strongswan vpp again, ran docker examples and now they are working.

But there is another question.
On our forwarder we use cross-connect for interfaces. For example, if we have 2 clients with TAP interfaces and we use VXLAN mechanisms between forwarders, we create:

... client1[tap1] --- L2XC --- [vxlan1a][src 1.1.1.1, VNI 1] ---------- [dst 1.1.1.2, VNI 1][vxlan1b] --- ...
... client2[tap2] --- L2XC --- [vxlan2a][src 1.1.1.1, VNI 2] ---------- [src 1.1.1.2, VNI 2][vxlan2b] --- ...

in other words, there are as many vxlan interfaces as there are clients.

Is it possible to create several IPSec interfaces via lcp (or strongswan) in VPP to make such cross-connects? So far I haven't found this.
Any thoughts would be helpful!

@gmslabs
Copy link

gmslabs commented Nov 30, 2022

Hi,
AFAIK, in standard linux datapath sswan with route based vpn, you can create vti interface per incoming connection, or xfrmi(xfrm interface, newer kernels + linux kernel flag) with similar functionality.
Route based vpn and vti/xfrm

not sure how that flow will be translated to the sswan+vpp datapath…

@denis-tingaikin
Copy link
Member

Seems like done!

@glazychev-art Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

No branches or pull requests

3 participants