Hi Ben,
I've added my comments inline.
On 12/10/19 7:12 PM, Ben Schwartz wrote:
I have a few notes on the SOCKS 6 draft, related to UDP.
1. I would like to require servers to share resumption between TLS and
DTLS. This would allow clients to keep a single resumption cache,
instead of two.
This is the first time I hear about TLS and DTLS sharing sessions.
It is a nice performance improvement that, as far as I can tell, doesn't
have any drawbacks. However, I wouldn't require it (as in MUST, REQUIRE
or SHOULD) since it puts extra burden on the implementers. All that
should be required is a functional TLS layer. (Session resumption might
not be supported by the library, it becomes complicated if you're using
an L4 load-balancer etc. etc.)
It's definitely a MAY, though.
2. I think the protocol should support sending UDP datagrams over the
TCP socket being used for UDP ASSOCIATE. If the client sends a
datagram on this channel, it would become the mapped channel for the
association. (Alternatively, it could serve as a "fallback channel"
when there is no UDP-based channel available.) This would be faster
for short-lived UDP transactions, because the client could include the
first upstream packet in the first flight, without needing to wait for
a reply containing the Association ID. It would also help in cases
where the client-proxy path is UDP-intolerant.
Yes, we could do that.
3. The 64-bit Association ID seems like a potential security
vulnerability when using DTLS. Suppose an attacker observes a DTLS
connection attempt from a client. If the attacker can block the true
client's DTLS, they can start enumerating Association IDs until they
find the one that works. Enumerating a 64-bit space is not easy, but
it is too small to be considered cryptographically strong.
Yes, guessing the Association ID is indeed a concern. We are planning to
write something about it in the security considerations section.
The main idea is to narrow the attacker's window down to a few minutes.
This is achieved in 3 ways (which aren't mutually exclusive):
(A) A hard timeout (on the order of minutes) at the proxy. If no first
datagram is received, the association is killed.
(B) The client kills the association if it doesn't receive an
Association Confirmation message after a timeout. It can keep resending
empty datagrams in the meanwhile. The attacker might blackhole the TCP
connection to counter this.
(C) The proxy keeps sending TCP keepalives or TLS heartbeats. Blackholed
connections are detected and their associations are killed.
Assuming a 100Gbps link, bruteforcing 2^64 values would take 3700 years
(or "just" 37 for a 1% chance of success). The attack can also be
detected, unless done stealthily (and slowly).
I don't know what the standard is for deeming something "secure". Maybe
we should also ask SAAG to take a look at this.
Putting a very large Association ID at the beginning of every packet
is not appealing, but with DTLS there may be a more secure and more
efficient solution. For example, the client could include a longer
Association ID only until it gets an acknowledgement from the server,
at which point both sides know that the UDP association is mapped to
this DTLS connection. Alternatively, the client could send some
information about its DTLS ClientHello in the TLS channel that sent
the UDP ASSOCIATE, creating a secure binding.
Unfortunately, we can't ditch the Association ID entirely, because
multiple UDP associations can be multiplexed over the same DTLS connection.
Your idea about having two different Association IDs is interesting. In
essence, one would be "signed", and the other "unsigned". The only issue
is that the ID eats into the maximum payload size, and clients would see
the equivalent of a varying MTU.
Your second idea with the ClientHello seems promissing. We could include
the session ID, connection ID or ticket in the SOCKS Request. (I'm not
sure what to do if the DTLS connection has neither.)
Further, it can't be an attack if the TLS and DTLS connections share the
same session or client credentials (but we can't always count on having
these features available, especially the latter).
4. SOCKS6-UDP is not compatible with PLPMTUD
(https://tools.ietf.org/html/draft-ietf-tsvwg-datagram-plpmtud),
because the client cannot control fragmentation at the proxy. I think
we should add a "Don't Fragment" bit to the SOCKS 6 datagram header to
support PLPMTUD.
The path of least resistance would be a "don't fragment" stack option.
However, that would apply to the whole UDP association and there would
be no way to change it.
Of course, the client can create an association specifically for probing
purposes.
(I would love it if SOCKS 6 could pass ICMP messages for classical
PMTUD (and ping! and traceroute!) but I don't expect that to happen.)
--Ben
Yes, I don't think there's an elegant way to support ICMP.
Cheers,
Vlad
_______________________________________________
Int-area mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/int-area