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

Integrate with Charon #68

Open
eugeneia opened this issue Dec 17, 2018 · 5 comments
Open

Integrate with Charon #68

eugeneia opened this issue Dec 17, 2018 · 5 comments

Comments

@eugeneia
Copy link
Member

eugeneia commented Dec 17, 2018

I would be nice to support integration with Charon, the StrongSwan IKE daemon, out of the box. Steps towards that goal seem to be:

  • punt IKE packets to a TUN/TAP interface (Charon would listen on this interface)
  • implement a libcharon plugin (see the kernel_pfkey plugin as a reference) that emits Vita configurations
@alexandergall
Copy link

I have similar needs for my l2vpn program. I've looked at Charon and talked a bit to the principal author Tobias Brunner and I'd like to suggest a slightly different but more general approach.

My idea is to let a Snabb program pose as a "Pseudo-Kernel" to Charon. The plugin would implement the "kernel-ipsec" feature (in Strongswan-speak), which replaces the standard kernel plugin (e.g. kernel_netlink). This plugin receives the keys for a CHILD-SA. One could create a configuration for vita or l2vpn from that, but I would actually write the keys to a shared memory segment in a well-defined format instead (or do both, whatever). A running Snabb program would read the keys from there and use it directly. This would have the advantage that we could even implement rekeying during runtime.

In my use case, the IKE packets are exchanged via a regular interface on the host, not Snabb, so I would not need a TAP interface for punting, but this is orthogonal to the implementation of the plugin.

I already have some running code but not yet the actual passing of keys to Snabb.

@eugeneia
Copy link
Member Author

Neat! So the idea behind "emitting Vita configurations" was that Vita already supports on-line reconfiguration of child SAs via lib.ptree YANG RPCs. I.e., one can do something like

$ snabb config add vita-node /inbound-sa
spi 1234;
route foo;
aead "cipher";
key "xxx";
salt "xxx";

so I imagined that would be what the charon plugin would do.

Your proposal sounds reasonable to me. :-)

@alexandergall
Copy link

The first version of the kernel_snabb plugin is done: https://github.com/alexandergall/strongswan/tree/kernel-snabb-5.6.3
It's based on 5.6.3 because that's the current version in NixOS 18.09 on which my appliance is based. To build, just add --enable-kernel-snabb to the configure flags, then add

charon-systemd {
  plugins {
    kernel-snabb {
      load = 1000
    }
  }
}

to your strongswan.conf file to override the standard kernel_netlink plugin.

I have implemented the Snabb side of things for apps.ipsec.esp only ATM, because that is my use case. I've created a new module Transport6_IKE which inherits from Transport6. You can find it here: https://github.com/alexandergall/snabbswitch/tree/ipsec-ike

The documentation of the interface is in lib.ipsec.shm. I don't really know what your requirements are. I'd appreciate if you could have a look at all of this and let me know what you think :)

@eugeneia
Copy link
Member Author

eugeneia commented Mar 5, 2019

This looks really neat to me! Awesome!

For Vita I might not go for the ESP app re-configuring itself, but instead have changes to SAs trigger updates to the YANG model which then causes reconfiguration etc.. but the mechanism will be much the same.

The only thing I do not immediately understand is the hashing. What is the advantage of hashing the traffic selector instead of just embedding it in the filename?

The charon plugin seems really straight forward (is it really just 500 lines? That is awesome!) I am bit worried about potential races through partial reads/writes to the SHM file, but I do not know enough about the semantics to be a judge of that.

@alexandergall
Copy link

I've chosen the hash to be independent of discrepancies how the addresses are formatted, but I guess just using the standard ntop() would have been fine, too :) It would also make it easier to identify the connection by looking at the directory name. Well, maybe I'll change that.

The potential race is probably a valid point, I'm also not sure. I guess I could simply use flock(2) to synchronize.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants