[tcpm] Some ideas building on draft-ietf-tcpm-fastopen-01

<bob.briscoe@bt.com> Fri, 27 July 2012 05:19 UTC

Return-Path: <bob.briscoe@bt.com>
X-Original-To: tcpm@ietfa.amsl.com
Delivered-To: tcpm@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 0B11F21F85C2 for <tcpm@ietfa.amsl.com>; Thu, 26 Jul 2012 22:19:54 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -3.598
X-Spam-Level:
X-Spam-Status: No, score=-3.598 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-1]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yRF+InBkxHnw for <tcpm@ietfa.amsl.com>; Thu, 26 Jul 2012 22:19:52 -0700 (PDT)
Received: from smtpe1.intersmtp.com (smtp62.intersmtp.com [62.239.224.235]) by ietfa.amsl.com (Postfix) with ESMTP id 3C30E21F85C0 for <tcpm@ietf.org>; Thu, 26 Jul 2012 22:19:52 -0700 (PDT)
Received: from EVMHT63-UKRD.domain1.systemhost.net (10.36.3.100) by RDW083A006ED62.smtp-e2.hygiene.service (10.187.98.11) with Microsoft SMTP Server (TLS) id 8.3.264.0; Fri, 27 Jul 2012 06:19:51 +0100
Received: from EVMHT04-UKBR.domain1.systemhost.net (193.113.108.57) by EVMHT63-UKRD.domain1.systemhost.net (10.36.3.100) with Microsoft SMTP Server (TLS) id 8.3.264.0; Fri, 27 Jul 2012 06:19:51 +0100
Received: from EMV04-UKBR.domain1.systemhost.net ([169.254.1.122]) by EVMHT04-UKBR.domain1.systemhost.net ([193.113.108.57]) with mapi; Fri, 27 Jul 2012 06:19:50 +0100
From: <bob.briscoe@bt.com>
To: <draft-ietf-tcpm-fastopen@tools.ietf.org>
Date: Fri, 27 Jul 2012 06:19:49 +0100
Thread-Topic: Some ideas building on draft-ietf-tcpm-fastopen-01
Thread-Index: AQHNa7dyBV6au7zMHEKTqw5AZStHJQ==
Message-ID: <69ACA3A4BA39B0499C1917FB0718BB254BE747BB86@EMV04-UKBR.domain1.systemhost.net>
Accept-Language: en-US, en-GB
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
acceptlanguage: en-US, en-GB
Content-Type: multipart/alternative; boundary="_000_69ACA3A4BA39B0499C1917FB0718BB254BE747BB86EMV04UKBRdoma_"
MIME-Version: 1.0
Cc: tcpm@ietf.org
Subject: [tcpm] Some ideas building on draft-ietf-tcpm-fastopen-01
X-BeenThere: tcpm@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <tcpm.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tcpm>, <mailto:tcpm-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/tcpm>
List-Post: <mailto:tcpm@ietf.org>
List-Help: <mailto:tcpm-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 27 Jul 2012 05:19:54 -0000

Yuchung, Jerry, Sivasankar, Arvind,

I liked this enough to want to work on improving it. I have a couple of proposals that occurred to me, which I've finally made time to write up.

(I'll send editorial nits from reviewing the draft later)

==Proposal #1/ ==
Fast Open Cookie Request MUST (SHOULD?) be on a FIN

I believe it would be better for the reasons below if:
* the client put a fast open cookie request in its FIN, not its SYN (whether or not the server has sent a FIN first).
* Then the server can send the fastopen cookie on the FIN-ACK.
* If the client times out waiting for a FIN-ACK, it just re-sends as usual.
* If the server's FIN-ACK never arrives (perhaps because a middlebox has eaten it), the client just doesn't have a cookie for the next session and uses a 3WHS as normal.

Note, only the Request would have to be on a FIN. The Fast Open Cookie itself would obviously still be on the SYN of subsequent connections. Then, when a subsequent connection finishes, it can refresh the cookie on its FIN, ready for another connection later.

This solves a couple of potential problems with a fastopen request-response on the initial SYN exchange:
a) A FIN-cookie sidesteps the risk of unpredictable delay of the very first SYN due to some middleboxes dropping new TCP options (any timeouts due to non-delivery don't hold up the session, which has already finished)
b) Transports GETting typical Web pages could (ab)use the fastopen cookie on the SYN exchange by opening multiple TCP connections during the initial connection without each one suffering the delay of a 3WHS. This creates a perverse incentive to use multiple parallel connections, because you can get the same latency benefit as HTTP pipelining [Yoshifumi posed this problem some time ago].  If clients can only request a fastopen cookie on a FIN, they don't have this perverse incentive to not bother with pipelining.

I have no evidence, but it seems intuitive that if the TCP option got through on the first FIN, it might be more likely to get through on the next SYN, altho I admit options on SYNs are looked at more closely by middleboxes.


==Proposal #2/ ==
Fastopen cookies (optionally) authenticate both the client's network address and the its knowledge of the TCP timestamp option on the segment carrying the server's cookie.

I would like to propose that if the server TCP-timestamps the segment carrying its cookie, the client MUST use a timestamp option on the segment that starts the subsequent fast open, and in its timestamp echo field it must echo the timestamp sent with the earlier cookie. Then:
i) the server can use the timestamp as part of the material for generating and validating the cookie and
ii) the server can set an expiry_duration, and check whether the echoed timestamp is older than time(now) - expiry_duration.

Reasoning:
The draft currently says:
"   3. The cookie expires after a certain amount of time. The reason is
       detailed in the "Security Consideration" section. This can be
       done by either periodically changing the server key used to
       generate cookies or including a timestamp in the cookie.
"

Let's take each in turn:
* Periodically changing the server key: Let's imagine the key changes every 30 min. Then all cookies issued in the last 30 mins stop being useful, even those just issued a second ago, or a minute ago, or 15 minutes ago...
* Including a timestamp in the cookie. This is only useful if the timestamp is in the clear within the cookie, otherwise the server cannot use it to key the cookie. But a timestamp in the clear takes valuable bits away from the cookie, weakening its strength. This is unnecessary if there's already space for a timestamp option on the segment (which is very common).

Security Considerations mentions only two ways a client can collect valid cookies from other hosts:
i) compromising other hosts, or
ii) (legally) taking over the lease of an IP address from a DHCP server.
But there is a much more problematic third way:
iii) sitting behind the same NAT as a neighbour (esp. a carrier-grade NAT serving thousands of clients), where the NAT uses a common IP address for many clients.

As it stands, the cookie is only dependent on the client's network address. Binding a TCP timestamp option into the cookie as well adds a lot more entropy.

With only the IP address for entropy, a client behind a NAT (or an attacker in control of a compromised host behind a NAT) can get its own (valid) cookie and use it in a brute-force spoof of numerous neighbouring clients - to either SYN-flood the server or launch a reflection attack on its neighbours by fast-opening loads of new TCP connections requesting large data items on behalf of its neighbours, bypassing the safety check of the 3WHS.

In contrast, if a cookie depends on both the client's network address and server's timestamp, a cookie requested by a client behind a NAT will only be the same as a neighbours cookie served by the same server within the same clock tick.

This doesn't stop attackers getting valid cookies from compromised hosts, but it does effectively prevent these more trivial attacks on neighbours.


==Proposal #3/ ==
Special cookie values

(A minor point compared to the two above)

4.1.2 Server Cookie handling

"  Also note the server may want to use special cookie values, e.g.,
   "0", for specific scenarios. For example, the server wants to notify
   the client the support of TFO, but chooses not to return a valid
   cookie for security or performance reasons upon receiving a TFO
   request.
"

I suggest the server just returns the cookie option with length 2 and no cookie data, to show it supports the option, but chooses not to give a cookie. Then the server doesn't have to run an extra 'if' test every time it generates a cookie, just to check the cookie doesn't collide with a special value.

This would require the value of the cookie option request kind to be different from the cookie option kind. Otherwise a response meaning "cookie supported but empty" would be confused with a cookie request for the half-connection in the opposite direction.


== Outstanding concern ==

Similar to a concern of Joe Touch's and Richard Scheffeneger's: dividing up TCP implementations into ones with idempotent semantics and ones without. This confuses the simple applicability of TCP. We need to work on that - but manyana.



Bob



[PS. Apologies if you already got this once - I've been 'experimenting' with my email]