testing a new SSL+ESP VPN

David Woodhouse dwmw2 at infradead.org
Wed Oct 5 01:58:09 PDT 2016

On Wed, 2016-10-05 at 00:38 -0500, Daniel Lenski wrote:
> On Tue, Oct 4, 2016 at 1:47 PM, David Woodhouse <dwmw2 at infradead.org> wrote:
> > At least Cisco had the decency to call this a 'CONNECT' request :)
> Gotcha. Clearly more than one brilliant mind has thought, "IP over TCP
> is such a beautiful idea. Let's add HTTP and make it even more
> beautiful."

I detect sarcasm, but this is actually a sane design choice. If you
want a VPN to work from anywhere, you *have* to run it over HTTPS.

There are *plenty* of networks from which a client can't connect to
*anything* except HTTPS in the outside world.

Coupled with SOCKS/HTTP proxy support in the client, you can connect to
an HTTPS service from fairly much *anything*.

Having the UDP connectivity is needed too, of course, but you *have* to
fall back to actually passing traffic over HTTPS if you want to provide
a reliable service.

> Here's the authentication process as logged by mitmproxy, with
> identifying information and keys redacted or bowdlerized:
> https://gist.github.com/dlenski/5046e5f934ac111e8d8718fc10c25703
> It's extremely verbose, what with the XML and all, but this does make
> it pretty straightforward to interpret the IPsec configuration with
> confidence.

Right. Unlike the binary stuff in the Juniper protocol :)

So actually, any time you spend playing with 'ip xfrm' is probably not
directly useful to the end goal — it's not like you really need to
experiment and work out what the configuration *means*. You may do
better just to proceed to a real implementation.

Although I do concede the joy of just getting packets moving under your
own control for the first time, even if it's a "waste" of time. There's
a reason http://david.woodhou.se/cisco.c still exists for posterity. :)

Speaking of which... take a look at that and notice the 8-byte
'STF\x01....' header at the start of each IP packet over the TCP
connection. This contains a length, and frames the packets. 

Without that, you'd be left inferring the length of the packets from
the IPv[46] header, which is suboptimal. You don't mention any framing
like this in the above gist... is there any?

We're also looking for "probes" over the ESP connection, like Juniper's
trick of sending a zero-byte payload and expecting to receive one back
from the server before it considers the UDP link "alive" and switches
to using it for real traffic.

You might want to experiment with pointing your existing client at a
nasty hack that pretends to be a server, like the one at 

Obviously yours will have much less *binary* crap captured from an
existing session, and much more human-readable XML.

> I probably won't have any more time to play around with it until the weekend.

Sounds good. I think it should fit into the OpenConnect two-phase model
relatively well. For the authentication phase (obtain_cookie) we
probably use just your Request #1 and Response #2. Remember, this runs
in the *user's* session, and can interact with the user for passwords
and can have access to client certificate if there is one.

The "cookie" is an arbitrary opaque string passed from the
authentication phase (potentially via NetworkManager) to the connection
phase. In your case you'd want it to contain at least the "Myusername",
"Gateway-Name", "cookie" and perhaps also the 'company domain name'. 

Then the tcp_connect() function makes Request #2 and receives the IP
and routing information, then tcp_mainloop() passes traffic.

Personally, I'd worry about doing the ESP later, after all that is

I note your example is all Legacy IP — can you observe it using IPv6?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5760 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20161005/ba2c6480/attachment.bin>

More information about the openconnect-devel mailing list