Re: [PATCH] tun: orphan an skb on tx

From: David Woodhouse
Date: Mon Feb 02 2015 - 10:47:09 EST


On Mon, 2015-02-02 at 16:23 +0100, Phil Sutter wrote:
> Since you want to provide connectivity over HTTPS which is not possible
> in kernel space, you are stuck with keeping the tun device. So the
> packet flow in that case is identical to how e.g. OpenVPN does it:
>
> - tunX holds default route
> - OpenConnect then:
> - receives packets on /dev/tun
> - holds TCP socket to VPN concentrator
> - does encapsulation into TLS
>
> Speaking of optimisation, the interesting part is the alternative flow
> via IPsec in UDP.

Right. The packet flow you describe is what we already have. Except of
course we already *do* establish the UDP connection (which is DTLS when
we're talking to a Cisco AnyConnect server, and ESP in UDP when we're
talking to Juniper). If we get responses to keepalive packets, we'll
send outbound packets over the UDP connection. If the UDP connectivity
goes AWOL, we'll fall back to sending on TCP. Rekeying of the UDP
connection is handled over the TCP control connection too. Even in the
DTLS case, the master secret and session ID are exchanged over TCP and
the DTLS is actually done as a 'session resume', without the normal DTLS
handshake ever happening.

As you say, I'm stuck with keeping the tun device (or something very
much like it). This *isn't* like vpnc where I can set up an IPSec config
and just let it run.

> AFAICT, it should be possible to setup an ESP in UDP
> tunnel using XFRM (see ip-xfrm(8) for reference), although I didn't try
> that myself. The funny thing with XFRM is, it applies before the routing
> decision does: If my IPsec policy matches, the packet goes that way no
> matter what the routing table says about the original destination. This
> can be used to override the default route provided via tun0 in the above
> case.

Except it isn't even the default route. We get given a bunch of split
includes or split excludes from the VPN server. We pass them to
vpnc-script or NetworkManager to actually set the routes up, and those
tools may make their own tweaks to what the server requested â denying
the default route and setting up explicit routes, or adding firewall
rules or NAT to incoming/outgoing packets on the tun device.

If it is no longer *just* the single tun device, everything gets really
complicated. Even *before* we talk about changing it on the fly during
normal operation.

> Of course, OpenConnect has to manage all the XFRM/policy stuff on it's
> own, since switching from ESP in UDP back to TLS would mean to tear down
> the XFRM tunnel. OpenConnect would have to setup (a limited) XFRM and
> send test traffic to decide whether to set it up fully (if limited) or
> tear it down (if unlimited) again so traffic arrives at tunX again.

Right. And ideally without CAP_NET_ADMIN.

> In my opinion, this might work. The whole setup is probably about as
> intuitive as the fact that kernel IPsec tunnel mode does not naturally
> provide an own interface. Firewall setup on top of that might become a
> matter of try-and-error. Maybe having a VTI interface and merely moving
> the default route instead of fiddling with policies all the time might
> make things a little easier to comprehend, but surely adds some
> performance overhead.

I think even the latter is sufficiently complex to manage that it's not
worth pursuing. I may throw together my suggested hack using
tun_get_socket() and see how much it makes *me* barf before deciding
whether to show it here for more feedback :)

--
dwmw2

Attachment: smime.p7s
Description: S/MIME cryptographic signature