[tor-bugs] #24432 [Obfuscation/BridgeDB]: The meek<->moat tunneling isn't set up correctly

Tor Bug Tracker & Wiki blackhole at torproject.org
Mon Jan 29 09:26:40 UTC 2018


#24432: The meek<->moat tunneling isn't set up correctly
----------------------------------+--------------------------
 Reporter:  isis                  |          Owner:  isis
     Type:  defect                |         Status:  reopened
 Priority:  High                  |      Milestone:
Component:  Obfuscation/BridgeDB  |        Version:
 Severity:  Normal                |     Resolution:
 Keywords:  moat bridgedb-dist    |  Actual Points:
Parent ID:  #24689                |         Points:  2
 Reviewer:                        |        Sponsor:  SponsorM
----------------------------------+--------------------------

Comment (by dcf):

 Replying to [comment:10 mcs]:
 > '''Problem 1:''' The meek tunnel does not work reliably for us.
 Specifically, if we use curl as the SOCKS client it seems to always work
 and if we use Tor Browser it does not. When we test with our own meek-
 server + BridgeDB, things also work fine. I am having trouble debugging
 the meek-client code, probably due to my lack of golang knowledge, but I
 wonder if there is an incompatibility between the meek-client we are
 running and the meek-server that you are running. What version of meek-
 server are you using at tor-bridges-hyphae-channel.appspot.com? Kathy and
 I are using a meek-client that was built from dcf's bug24642 branch (and I
 don't know of any recent changes to meek that would cause this kind of
 communication problem).
 >
 > Another data point: if I insert an socat pipe between the meek-client
 SOCKS port and Tor Browser, it started working. Maybe there is a data
 buffering issue at work here. All of our client side testing so far has
 been on macOS.

 I was debugging this problem today and I traced the cause to Tor Browser's
 [https://gitweb.torproject.org/tor-browser.git/commit/?h=tor-
 browser-52.6.0esr-8.0-2&id=6d594cc227f153364b91e8310d59a07d7d6ce5f6
 optimistic SOCKS data patch] (#3875), which allows the browser to start
 sending application data right after sending its SOCKS request, before the
 proxy has sent back a reply saying that the connection was successful.
 There are two ways that optimistic data causes problem when using meek-
 client as a SOCKS proxy.

  1. The first is that the SOCKS code in goptlib expects not to get any
 optimistic data: [https://gitweb.torproject.org/pluggable-
 transports/goptlib.git/tree/socks.go?id=a3ad5df6c9e7dc8117f55958b4ce99bf1e0fe291#n363
 socksReadCommand] finishes by calling [https://gitweb.torproject.org
 /pluggable-
 transports/goptlib.git/tree/socks.go?id=a3ad5df6c9e7dc8117f55958b4ce99bf1e0fe291#n472
 socksFlushBuffers], which raises an error if there is any data left in the
 read buffer (because otherwise the data would be silently lost when the
 SOCKS code passes the unbuffered socket back to the application). This
 doesn't happen always; it depends on the timing of how fast Firefox sends
 its application data. This issue doesn't seem very serious: we can modify
 the SOCKS code not to use an internal buffer and be tolerant of optimistic
 data. But on its own that is not enough, because
  2. Tor Browser has a race condition when the SOCKS proxy sends back its
 its reply immediately after receiving a request, as meek-client does. The
 SOCKS reply looks like `"\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00"`; when
 it comes back too soon, Tor Browser reads the SOCKS response as if it were
 application data. Trying to parse SOCKS as TLS is what results in the
 connection failure. You can see this by going to
 [https://developer.mozilla.org/en-
 US/docs/Mozilla/Debugging/HTTP_logging#Using_aboutnetworking
 about:networking] and setting the Log Modules
 `timestamp,nsSocketTransport:5,SOCKS:5`. Follow the instructions in
 comment:11, and you will see this in the log:
     {{{
 D/SOCKS socks: DoHandshake(), state = 7
 D/SOCKS socks: ReadFromSocket(), have 2 bytes total
 D/SOCKS socks5: checking auth method reply
 D/SOCKS socks5: server allows connection without authentication
 D/SOCKS socks5: sending connection request (socks5 resolve? yes)
 D/SOCKS socks: DoHandshake(), state = 10
 D/nsSocketTransport   advancing to STATE_TRANSFERRING
 ...
 D/nsSocketTransport nsSocketTransport::OnSocketReady [this=7f2d4c2cbc00
 outFlags=1]
 D/SOCKS socks: DoHandshake(), state = 11
 D/SOCKS socks: ReadFromSocket(), have 5 bytes total
 D/SOCKS socks5: checking connection reply
 E/SOCKS socks5: unexpected version in the reply
     }}}
 "unexpected version in the reply" comes from
 [https://gitweb.torproject.org/tor-
 browser.git/tree/netwerk/socket/nsSOCKSIOLayer.cpp?h=tor-
 browser-52.6.0esr-8.0-2&id=5e2ac8aed83692c340c8ce219eaa116cf1da2654#n988
 ReadV5ConnectResponseTop]. It's because the application layer and the
 SOCKS layer are fighting over who gets to read data from the socket.
 `state = 10` is [https://gitweb.torproject.org/tor-
 browser.git/tree/netwerk/socket/nsSOCKSIOLayer.cpp?h=tor-
 browser-52.6.0esr-8.0-2&id=5e2ac8aed83692c340c8ce219eaa116cf1da2654#n55
 SOCKS5_WRITE_CONNECT_REQUEST] and `state = 11` is
 [https://gitweb.torproject.org/tor-
 browser.git/tree/netwerk/socket/nsSOCKSIOLayer.cpp?h=tor-
 browser-52.6.0esr-8.0-2&id=5e2ac8aed83692c340c8ce219eaa116cf1da2654#n56
 SOCKS5_READ_CONNECT_RESPONSE_TOP], which are constants used in
 [https://gitweb.torproject.org/tor-
 browser.git/tree/netwerk/socket/nsSOCKSIOLayer.cpp?h=tor-
 browser-52.6.0esr-8.0-2&id=5e2ac8aed83692c340c8ce219eaa116cf1da2654#n1098
 DoHandshake]. The optimistic data patch [https://gitweb.torproject.org
 /tor-browser.git/tree/netwerk/socket/nsSOCKSIOLayer.cpp?h=tor-
 browser-52.6.0esr-8.0-2&id=5e2ac8aed83692c340c8ce219eaa116cf1da2654#n85
 modifies isConnected] to be true during SOCKS5_READ_CONNECT_RESPONSE_TOP,
 when there is still potentially SOCKS data pending on the socket.

 attachment:demo-socks5.go demonstrates that the problem exists separate
 from meek. It's just a SOCKS5 proxy that returns the SOCKS response
 immediately. Run
 {{{
 ./demo-socks5
 }}}
 and follow comment:11 and set `network.proxy.socks.port=3128`; you'll see
 the same failure to connect. It works fine with ordinary Firefox, which
 lacks the optimistic data patch. Adding an artificial delay resolves the
 race condition and it starts working again:
 {{{
 ./demo-socks5 -sleep 100ms
 }}}

 So a short-term workaround is to add an artificial delay into meek-client
 to prevent it from sending back the SOCKS response immediately. The delay
 has to go [https://gitweb.torproject.org/pluggable-
 transports/meek.git/tree/meek-client/meek-
 client.go?h=bug24642&id=8c0e2c8601e87687a2f147a875753ac298b52a2e#n278 just
 before conn.Grant] in meek-client.go. I think that's the reason why it
 worked with a socat shim--the extra process tweaked the timing just
 enough.

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


More information about the tor-bugs mailing list