Integrate with Charon
eugeneia opened this issue · 5 comments
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
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.
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. :-)
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 :)
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.
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.