From d9389f05d48bebc8caf9fc0d6dafc7e8b62a1d21 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 17 Oct 2017 15:11:19 +1100 Subject: [PATCH 1/7] Ignore upload files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b83b1d1116..f5de85b1be 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ issues.json pulls.json lib .targets.mk +*.upload From ded8d4fab722c5909c97aa58e618e8da7f2d189c Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 14 Aug 2017 19:06:28 +1000 Subject: [PATCH 2/7] Address validation for connection migration This has been much-discussed, and it's a relatively isolated change, so I did it. This modifies PING to have an optional payload and adds a PONG frame to echo the PING. An empty PING generates an ACK; a PING with a payload demands a PONG. Generating an unguessable PING is the basis of mid-connection address validation. If the PING is sent on the new path, and the PONG comes back, then the remote address is probably OK to use. I've taken the discussion in the issue into consideration here. There's a lot of potential nuance to capture in terms of how an endpoint might reduce and restore send rates, but I've done what I can to thread the gap between allowing unbounded sending along new and untested paths and allowing connections to get back to doing business. It's annoying that this makes PING and PONG so disparate. I think that we have a re-ordering of frames in our near future to correct minor infidelities like this. I didn't want to do that here and pollute this PR though. Closes #161. --- draft-ietf-quic-transport.md | 76 ++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 0256536d10..2a50c4078d 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1343,6 +1343,9 @@ Source address validation is therefore performed during the establishment of a connection. TLS provides the tools that support the feature, but basic validation is performed by the core transport protocol. +A different type of source address validation is performed after a connection +migration, see {{migrate-validate}}. + ### Client Address Validation Procedure @@ -1431,6 +1434,19 @@ connection when they move networks. This includes state that can be hard to recover such as outstanding requests, which might otherwise be lost with no easy way to retry them. +An endpoint that receives packets that contain a source IP address and port that +has not yet been used MUST start sending new packets with those as a destination +IP address and port. Packets exchanged between endpoints now follow a new path. + +Due to variations in path latency or packet reordering, packets from different +source addresses might be reordered. The packet with the highest packet number +MUST be used to determine which path to use. Endpoints also need to be prepared +to receive packets from an older source address. + +An endpoint MUST validate that its peer can receive packets at the new address +before sending any significant quantity of data to that address, or it risks +being used for denial of service. See {{migrate-validate}} for details. + ### Privacy Implications of Connection Migration {#migration-linkability} @@ -1485,9 +1501,63 @@ number. "packet_number_secret" is derived from the TLS key exchange, as described in Section 5.6 of {{QUIC-TLS}}. -### Address Validation for Migrated Connections - -TODO: see issue #161 +### Address Validation for Migrated Connections {#migrate-validate} + +An endpoint that see a new source IP address and port (or just a new source +port) on packets from its peer is likely seeing a connection migration at the +peer. + +However, it is also possible that the peer is spoofing its source address in +order to cause the endpoint to send excessive amounts of data to an unwilling +host. If the endpoint sends significantly more data than the peer, connection +migration might be used to amplify the volume of data that an attacker can +generate toward a victim. + +Thus, when seeing a new remote transport address, an endpoint MUST verify that +its peer can receive and respond to packets at that new address. By providing +copies of the frames that it receives, the peer proves that it is receiving +packets at the new address and consents to receive data. + +Prior to validating the new remote address, and endpoint MUST limit the amount +of data and packets that it sends to its peer. At a minimum, this needs to +consider the possibility that packets are sent without congestion feedback. + +Once a connection is established, address validation is relatively simple (see +{{address-validation}} for the process that is used during the handshake). An +endpoint validates a remote address by sending a PING frame containing a payload +that is hard to guess. This frame MUST be sent in a packet that is sent to the +new address. Once a PONG frame containing the same payload is received, the +address is considered to be valid. The PONG frame can use any path on its +return. A PING frame containing 12 randomly generated {{?RFC4086}} octets is +sufficient to ensure that it is easier to receive the packet than it is to guess +the value correctly. + +If validation of the new remote address fails, after allowing enough time for +possible loss and recovery of packets carrying PING and PONG frames, the +endpoint MUST terminate the connection. When setting this timer, +implementations are cautioned that the new path could have a longer round trip +time than the original. The endpoint MUST NOT send a CONNECTION_CLOSE frame in +this case; it has to assume that the remote peer does not want to receive any +more packets. + +If the remote address is validated successfully, the endpoint MAY increase the +rate that it sends on the new path using the state from the previous path. The +capacity available on the new path might not be the same as the old path. An +endpoint MUST NOT restore its send rate unless it is reasonably sure that the +path is the same as the previous path. For instance, a change in only port +number is likely indicative of a rebinding in a middlebox and not a complete +change in path. This determination likely depends on heuristics, which could be +imperfect; if the new path capacity is significantly reduced, ultimately this +relies on the congestion controller responding to congestion signals and reduce +send rates appropriately. + +After verifying an address, the endpoint SHOULD update any address validation +tokens ({{address-validation}}) that it has issued to its peer if those are no +longer valid based on the changed address. + +Address validation using the PING frame MAY be used at any time by either peer. +For instance, an endpoint might check that a peer is still in possession of its +address after a period of quiescence. ## Connection Termination {#termination} From a0480aae3f12a5d584c932321a1201e6c13a5759 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 23 Aug 2017 11:42:25 +1000 Subject: [PATCH 3/7] Avoid attack on address validation during connection migration The attack here is that an attacker might duplicate a legitimate packet and send that packet from an invalid address such that it arrives before the real copy. That causes the recipient to think that there was a connection migration. They will attempt to validate that address and this will fail. The connection is then closed. The fix is to cause a migration back to the original, legitimate address. For this to work, you need two things: 1. when a migration happens, abandon any validation on the old address on the expectation that it will fail 2. when a migration happens, make sure that you try to trigger packets from the old address first For the second point, I decided to mandate address validation, rather than an ordinary PING. The reason being that you have to retransmit the packet on that path and I doubt that implementations will want to have two sets of special machinery for transmiting - and retransmitting - frames on a specific path. Maybe this is too much of a constraint on implementations, so I'd like to hear from people about whether they would prefer a more generic requirement (send any packet that demands acknowledgment would work, it doesn't even have to be the same packet every time, though the usual situation will be that the packet will be lost, so you probably don't want to send anything important). --- draft-ietf-quic-transport.md | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 2a50c4078d..c0158d3808 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1532,6 +1532,10 @@ return. A PING frame containing 12 randomly generated {{?RFC4086}} octets is sufficient to ensure that it is easier to receive the packet than it is to guess the value correctly. +Note: + +: Retransmissions of the PING frame MUST also use the same remote address. + If validation of the new remote address fails, after allowing enough time for possible loss and recovery of packets carrying PING and PONG frames, the endpoint MUST terminate the connection. When setting this timer, @@ -1559,6 +1563,49 @@ Address validation using the PING frame MAY be used at any time by either peer. For instance, an endpoint might check that a peer is still in possession of its address after a period of quiescence. +Upon seeing a connection migration, an endpoint that sees a new address MUST +abandon any address validation it is performing with other addresses on the +expectation that the validation is likely to fail. Abandoning address +validation primarily means not closing the connection when a PONG frame is not +received, but it could also mean ceasing retransmissions of the PING frame. An +endpoint that doesn't retransmit a PING frame might receive a PONG frame, which +it MUST ignore. + + +## Spurious Connection Migrations + +A connection migration could be triggered by an attacker that is able to capture +and forward a packet such that it arrives before the legitimate copy of that +packet. Such a packet will appear to be a legitimate connection migration and +the legitimate copy will be dropped as a duplicate. + +After a spurious migration, validation of the source address will fail because +the entity at the source address does not have the necessary cryptographic keys +to read or respond to the PING frame that is sent to it, even if it wanted to. +Such a spurious connection migration could result in the connection being +dropped when the source address validation fails. This grants an attacker the +ability to terminate the connection. + +Receipt of packets with higher packet numbers from the legitimate address will +trigger another connection migration. This will cause the validation of the +address of the spurious migration to be abandoned. + +To ensure that a peer sends packets from the legitimate address before the +validation of the new address can fail, an endpoint SHOULD attempt to validate +the old remote address before attempting to validate the new address. If the +connection migration is spurious, then the legitimate address will be used to +respond and the connection will migrate back to the old address. + +As with any address validation, packets containing retransmissions of the PING +frame validating an address MUST be sent to the address being validated. +Consequently, during a migration of a peer, an endpoint could be sending to +multiple remote addresses. + +An endpoint MAY abandon address validation for an address that it considers to +be already valid. That is, if successive connection migrations occur in quick +succession with the final remote address being identical to the initial remote +address, the endpoint MAY abandon address validation for that address. + ## Connection Termination {#termination} From 854377925432d10f42ec617e6d24ec0122cfbf5f Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 16 Oct 2017 15:52:27 +1100 Subject: [PATCH 4/7] More review comments --- draft-ietf-quic-transport.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index c0158d3808..3f2513ad11 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1503,9 +1503,9 @@ as described in Section 5.6 of {{QUIC-TLS}}. ### Address Validation for Migrated Connections {#migrate-validate} -An endpoint that see a new source IP address and port (or just a new source -port) on packets from its peer is likely seeing a connection migration at the -peer. +An endpoint that receives a packet from a new remote IP address and port (or +just a new remote port) on packets from its peer is likely seeing a connection +migration at the peer. However, it is also possible that the peer is spoofing its source address in order to cause the endpoint to send excessive amounts of data to an unwilling @@ -1515,7 +1515,7 @@ generate toward a victim. Thus, when seeing a new remote transport address, an endpoint MUST verify that its peer can receive and respond to packets at that new address. By providing -copies of the frames that it receives, the peer proves that it is receiving +copies of the data that it receives, the peer proves that it is receiving packets at the new address and consents to receive data. Prior to validating the new remote address, and endpoint MUST limit the amount From 67849052344984d1e1bddf990717a48357b890be Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 16 Oct 2017 16:19:11 +1100 Subject: [PATCH 5/7] Require new PING on loss --- draft-ietf-quic-transport.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 3f2513ad11..977221ac99 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1532,9 +1532,8 @@ return. A PING frame containing 12 randomly generated {{?RFC4086}} octets is sufficient to ensure that it is easier to receive the packet than it is to guess the value correctly. -Note: - -: Retransmissions of the PING frame MUST also use the same remote address. +If the PING frame is determined to be lost, a new PING frame SHOULD be +generated. This frame MUST include a new payload that is difficult to guess. If validation of the new remote address fails, after allowing enough time for possible loss and recovery of packets carrying PING and PONG frames, the From a724bdb991bea5b4470cba4077e7f338e25baf3a Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 16 Oct 2017 16:36:27 +1100 Subject: [PATCH 6/7] Data field, not payload --- draft-ietf-quic-transport.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 977221ac99..1c0aaa023f 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1533,7 +1533,8 @@ sufficient to ensure that it is easier to receive the packet than it is to guess the value correctly. If the PING frame is determined to be lost, a new PING frame SHOULD be -generated. This frame MUST include a new payload that is difficult to guess. +generated. This PING frame MUST include a new Data field that is similarly +difficult to guess. If validation of the new remote address fails, after allowing enough time for possible loss and recovery of packets carrying PING and PONG frames, the From ca3f375a8bfceacac59ee75da527cf1941c8c7f0 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 17 Oct 2017 16:04:10 +1100 Subject: [PATCH 7/7] Remove MUST --- draft-ietf-quic-transport.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 1c0aaa023f..61897c216b 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1435,8 +1435,9 @@ recover such as outstanding requests, which might otherwise be lost with no easy way to retry them. An endpoint that receives packets that contain a source IP address and port that -has not yet been used MUST start sending new packets with those as a destination -IP address and port. Packets exchanged between endpoints now follow a new path. +has not yet been used can start sending new packets with those as a destination +IP address and port. Packets exchanged between endpoints can then follow the +new path. Due to variations in path latency or packet reordering, packets from different source addresses might be reordered. The packet with the highest packet number