Friday, August 15, 2008

Sorry folks, I think Obfuscated TCP died

Introduction: "Obfuscated TCP is a backwards-compatible modification to the TCP protocol which adds opportunistic encryption. It's designed to hamper and detect large-scale wiretapping and corruption of TCP traffic on the Internet" [1].

I'm afraid that the IETF wouldn't go for it. You can see the mailing list archives if you wish, but it's a lot of email.

In short, I requested an option in order to use as a switch at the application layer. (Thus, you would still be able to connect to an HTTP server and it could upgrade transparently.) This, it was felt, was a laying violation and the working group members didn't feel there was sufficient motivation to allow it.

Of course, I'm saddened that they didn't agree. I'm also a little relieved that it's done one way or another. Dealing with defending the draft morning, noon and night for days on end was shockingly draining.

Obfuscated TCP might regenerate, Time Lord like, but it will end up in a very different form if it does. Below is a list of possible futures. To be more complete, it includes options that I've already decided against. Also, it's in some sort of order, worse first. You'll also note that some of these are sacrificing the original, TCP wide goals for a specific HTTP target.

  1. Ignore the IETF and just take the option number. This is a really nasty thing to do. I could probably do it, at least as far as getting the patch into the Linux mainline, but it would really hurt the chances of future adoption and the IETF would be mad at me.
  2. Stuff the needed extensions in somewhere else in the header. This is possible, if icky. A SYN frame typically has 8 bytes unused (the ACK and the timestamp echo). The SYNACK is more troublesome, but I might be able to find somewhere. It would be a painful hack.
  3. Go back to the first design: long options and all in kernel. Long options requires IETF permission again and I've already been bitten by that. Also, it's known that there's little support in the IETF for long options. Additionally, putting all the crypto in kernel is a nasty wort on the TCP stack. This was a bad design which I dismissed early on; it's still a bad design.
  4. Concurrent SYNs. (Idea from Joe Touch) define a new default HTTP port and have web browsers race two connection opens, one to each port. If the old and the new both come back, close the old. I feel this is fairly ugly, probabilistic and wasteful.
  5. Burn a round trip. This is the general advice of the IETF. It's also the TLS upgrade method suggested in RFC2817 (which went nowhere). The problem is that, if browsers started deploying this, it would cost a round trip everywhere. Amazon, Google etc would go balistic because they know how much latency matters. IETF members, sadly, don't. I, personally, couldn't support this.
  6. Exploit connection history. The idea would be that browsers connect to a new site as they do now, but HTTP headers can advertise support. Then, for future connections to the same site, the browser can optimistically try an obfuscated request, wrapped in HTTP such that it only costs a RTT in the (hopefully rare) case that the optimism was unfounded. Problems here are that the interaction with pipelining is complicated, it's ugly and it doesn't work will with incremental deployment for a single site (if you have many servers). It doesn't, however, require TCP changes. Of anything, this seems like the least bad.

I'm going to take a few days to think about it. Comments are welcome: agl AT imperialviolet DOT org.

Special thanks also go to Dave McBride for his support of the project thus far. Also to my generous employer.

5 comments:

shapr said...

Maybe a write-in petition would sway the IETF? I'd very much like to have an IETF approved ObsTCP in the Linux mainline kernel.

Adam Langley said...

I wouldn't like for it to seem that I'm trying to use political pressure to get something past the IETF - it's supposed to be a technical organisation after all. You are quite welcome to post to the tcpm list requesting /something/ which met a bunch of goals. If you listed no-additional-latency as one of the goals, you would be challenged on that point. Sadly, the data to back it up is kept very confidential by Google/Amazon etc.

I have requested that we (Google) release some of it, but it doesn't look promising I'm afraid.

mattw said...

How about using dns to indicate obtcp support instead of http headers? Caching and distribution are handled, and there are some complementary effects when dnssec is added to the mix.

Adam Langley said...

mattw: either DNS or keeping information across connections are my current thoughts. Keeping information across sessions is easier to deploy, whist DNS changes are (arguably) cleaner.

(Or one could do both)

And there's the question of letting the server back off in case someone screws up the deployment - we don't want obfuscation to make things more fragile.

Also, it's not obvious what record type would carry the public value. TXT is pretty overloaded these days, but the CERT type has less DNS server support.

But thanks for the suggestion. It's always nice to know that I'm not just posting into the void :)

Subscribe to the blog RSS and I'll post when I've got something. First I need to experiment with overriding XPCOM interfaces in Firefox in order to create the client side.

Also, right now I'm looking at working with djb on securing DNS.

Cheers


AGL

Adam Langley said...

For people following the comments on this post: see the main blog for my thoughts. http://obstcp.blogspot.com