[tor-bugs] #29077 [Obfuscation/meek]: uTLS for meek-client camouflage

Tor Bug Tracker & Wiki blackhole at torproject.org
Sat Jan 12 20:08:40 UTC 2019


#29077: uTLS for meek-client camouflage
------------------------------+---------------------
 Reporter:  dcf               |          Owner:  dcf
     Type:  enhancement       |         Status:  new
 Priority:  Medium            |      Milestone:
Component:  Obfuscation/meek  |        Version:
 Severity:  Normal            |     Resolution:
 Keywords:  moat utls         |  Actual Points:
Parent ID:                    |         Points:
 Reviewer:                    |        Sponsor:
------------------------------+---------------------

Comment (by dcf):

 I started trying this out in
  * meek branch [https://gitweb.torproject.org/pluggable-
 transports/meek.git/log/?h=utls&id=90d82c205c0269b87de5a6956e485225f8a9a2cb
 utls]
  * tor-browser-build branch [https://gitweb.torproject.org/user/dcf/tor-
 browser-build.git/log/?h=meek-client-
 utls&id=1758a67bc2f366a8af2730d924b80a5c4133eec4 meek-client-utls]

 I built a browser with these changes. It works, but not well. It hangs and
 stalls frequently, and Moat often throws errors. There are two primary
 causes for these problems.

  1. utls's interaction with Go's built-in HTTPS is awkward. In meek-client
 we use an [https://golang.org/pkg/net/http/#Transport http.Transport] to
 enable connection reuse, manage idle timeouts, etc. To hook into utls, I'm
 [https://gitweb.torproject.org/pluggable-
 transports/meek.git/commit/?h=utls&id=5a98c4447e8d3cb14e53b9ef15d6faa812aed226
 setting the DialTLS callback]--but setting DialTLS has the side effect of
 disabling automatic HTTP/2 support on the client. This wouldn't be a
 problem, except for the fact that with e.g. the `HelloFirefox_63` and
 `HelloChrome_70` fingerprint, utls sends a Client Hello with an ALPN that
 negotiates HTTP/2. The server starts speaking HTTP/2 while the net/http
 client, oblivious to what utls has done, continues speaking HTTP/1.1, and
 you get an error. There are more details on this problem on
 [https://github.com/refraction-networking/utls/issues/16 GitHub ticket
 #16].

 As a workaround for the ALPN mismatch issue, I tried specifying the
 `HelloRandomizedNoALPN` client. Randomized means it picks fingerprint
 features randomly, and NoALPN means it won't negotiate HTTP/2. The loss of
 HTTP/2 is a bummer, but the bigger problem is

  2. The randomized fingerprint is re-randomized for every new TLS
 connection, and occasionally it generates a Client Hello that either (a)
 the server rejects or (b) causes the server to select a feature that the
 client advertised in its fake fingerprint but doesn't actually support.
 When this happens, you get an error in the meek-client log like
     {{{
 error in handling request: tls: server selected unsupported group
     }}}
     At the tor level, you get a stall until tor decides to try the bridge
 again. With Moat, you get an error dialog like "Unable to obtain a bridge
 from BridgeDB. NS_ERROR_NET_INTERRUPT", unless you are lucky that none of
 the TLS connections for the duration of the Moat session had the
 randomization error. The re-randomization of fingerprints normally
 wouldn't a severe problem because of connection reuse, but the combination
 of DialTLS and the lack of HTTP/2 means that connections are reused less
 than normal.

 In summary: the static fingerprints fail completely because of an ALPN
 mismatch; the randomized fingerprints fail sometimes because of server
 feature mismatches.

 There is a partial workaround. Using
 [https://godoc.org/golang.org/x/net/http2#Transport http2.Transport] in
 place of http.Transport seemingly solves all the above problems--with the
 caveat that it doesn't work with servers that don't support HTTP/2.
 [https://github.com/refraction-
 networking/utls/issues/16#issuecomment-453697993 Details here.] So what
 I'm planning to do next is add `utls` and `http2` controls to the PT
 configuration. `utls` would allow you to choose a utls fingerprint (with
 knowledge of the errors described above). `http2` would let meek-client
 assume that the front server always supports HTTP/2, solving the errors
 described above as long as the server actually does support HTTP/2.

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/29077#comment:1>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list