Opened 8 months ago

Closed 3 weeks ago

#29430 closed enhancement (fixed)

Use uTLS for meek TLS camouflage in Tor Browser

Reported by: dcf Owned by: tbb-team
Priority: Medium Milestone:
Component: Applications/Tor Browser Version:
Severity: Normal Keywords: meek, utls, ff68-esr, TorBrowserTeam201909
Cc: mcs, brade, yawning, boklm, intrigeri Actual Points:
Parent ID: Points:
Reviewer: Sponsor: Sponsor44-can

Description

Now that meek and meek_lite have or will soon have support for TLS camouflage using uTLS (#29077), we have the option of using that instead of the meek-http-helper headless Firefox extension.

The torrc line:

ClientTransportPlugin meek exec ./TorBrowser/Tor/PluggableTransports/meek-client-torbrowser -- ./TorBrowser/Tor/PluggableTransports/meek-client

will lose the meek-client-torbrowser to become just

ClientTransportPlugin meek exec ./TorBrowser/Tor/PluggableTransports/meek-client

In bridge_prefs.js, the bridge line will get an additional utls parameter:

meek 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com utls=HelloIOS_Auto

There's the option of continuing to use the same meek repo as we do now; or of removing that code and using obfs4proxy instead, since they both have uTLS support. Using obfs4proxy will have the advantage of smaller packaging, because there will be one binary instead of two.

There's one more complication, which is tor-launcher and Moat. tor-launcher has its own meek configuration separate from Tor Browser's. It gets the path to the meek-client executable from the control port (ultimately from torrc-defaults), but it has its own version of the url= and front= parameters, and it passes those to the executable to the executable as -url and -front command line arguments, not as SOCKS args. meek-client with uTLS has a -utls command line arg, so that's easy to adapt; but since obfs4proxy doesn't understand those command line args, either obfs4proxy would have to add them, or tor-launcher would have to start passing them as SOCKS args.

Child Tickets

TicketTypeStatusOwnerSummary
#29627defectclosedbradeMoat: add support for obfsproxy's meek_lite
#31488defectclosedmcsmoat: support a comma-separated list of transports in Tor config
#31491defectclosedmcsclean up the old meek http helper browser profiles

Attachments (4)

0001-Make-uTLS-aware.patch (2.0 KB) - added by dcf 8 months ago.
meek-client-utls_2.pcap (202.1 KB) - added by dcf 8 months ago.
tor-launcher-Make-uTLS-aware.helloretry.patch (2.2 KB) - added by dcf 8 months ago.
torbrowser-utls-helloretry.pcap.gz (228.9 KB) - added by dcf 8 months ago.

Download all attachments as: .zip

Change History (46)

comment:1 Changed 8 months ago by dcf

Here is a sample branch that uses the same meek repo.

It's pretty straightforward; I think the noteworthy changes are:

  • It only activates uTLS on alpha. I feel this is the kind of thing that should be tested on alpha before going into stable.
  • meek-client uses the mainline utls repo, not the fork that obfs4proxy uses, so I moved the goutls project to goutls-yawning and re-added a goutls project pointing to the original repo. I'm not sure what's best to do here :/
  • It requires a small tor-launcher patch: attachment:0001-Make-uTLS-aware.patch, which I didn't upload to a branch anywhere.

There are a few additional changes that could happen, namely deleting the meek-client-torbrowser executable and the meek-http-helper browser profile.

It works; I'm using it to post this comment. I ran a packet capture of me using Moat and then starting to bootstrap using meek-azure. There are 5 Client Hellos in the packet capture, all with TLS fingerprint 71a81bafd58e1301, which uTLS calls HelloIOS_11_1. The first 4 are me struggling with the Moat captcha (lol) and the 5th is starting the bootstrap itself.

I'm not marking this needs_review because I'm not necessarily proposing this branch for merge, just using it as an example of what integration could look like. I don't want to exclude the possibility of using obfs4proxy. I think it's more like needs_discussion at this point.

Changed 8 months ago by dcf

Attachment: 0001-Make-uTLS-aware.patch added

Changed 8 months ago by dcf

Attachment: meek-client-utls_2.pcap added

comment:2 Changed 8 months ago by gk

Cc: mcs brade added

The option of having one binary less to build and ship seems to me a big pro of that meek_lite approach. meek-*lite* sounds like something is missing from meek. What is it and should we care about that?

Adding mcs and brade for the moat considerations.

comment:3 in reply to:  2 ; Changed 8 months ago by yawning

either obfs4proxy would have to add them, or tor-launcher would have to start passing them as SOCKS args.

From my perspective, the latter.

Replying to gk:

meek-*lite* sounds like something is missing from meek. What is it and should we care about that?

It is named that way, because support for using a "real" browser as a helper is missing, and I wanted that to be explicitly clear.

comment:4 in reply to:  3 ; Changed 8 months ago by mcs

Replying to yawning:

either obfs4proxy would have to add them, or tor-launcher would have to start passing them as SOCKS args.

From my perspective, the latter.

Kathy and I agree: if we are planning to switch to obfs4proxy's meek client implementation (which seems like a good option to us), we should change Tor Launcher to use SOCKS args with the meek PT that it spins up for Moat.

Georg, is it worthwhile for us to do that work in Tor Launcher soon, or should we first resolve the "meek-client or obfs4proxy?" question?

comment:5 in reply to:  4 ; Changed 8 months ago by yawning

Cc: yawning added

Replying to mcs:

Kathy and I agree: if we are planning to switch to obfs4proxy's meek client implementation (which seems like a good option to us), we should change Tor Launcher to use SOCKS args with the meek PT that it spins up for Moat.

Georg, is it worthwhile for us to do that work in Tor Launcher soon, or should we first resolve the "meek-client or obfs4proxy?" question?

For what it's worth, I also think that changing Tor Launcher to do so is orthogonal from which meek implementation is being used, since the new code will work with both implementations (unless meek-client is doing something extremely surprising under the hood).

I aim to keep the bridge lines between meek-client and meek_lite as compatible as possible.

Currently the differences between the two implementations are as follows:

  • (config) meek_lite's utls option understands HelloChrome_71.
  • (config) meek_lite will use HelloFirefox_Auto if no utls option is specified.
  • (config) meek_lite has a (misnamed according to some) option disableHPKP.

So, all meek-client bridge lines will work with meek_lite (though the TLS fingerprint may differ).

comment:6 in reply to:  5 Changed 8 months ago by gk

Replying to yawning:

Replying to mcs:

Kathy and I agree: if we are planning to switch to obfs4proxy's meek client implementation (which seems like a good option to us), we should change Tor Launcher to use SOCKS args with the meek PT that it spins up for Moat.

Georg, is it worthwhile for us to do that work in Tor Launcher soon, or should we first resolve the "meek-client or obfs4proxy?" question?

For what it's worth, I also think that changing Tor Launcher to do so is orthogonal from which meek implementation is being used, since the new code will work with both implementations (unless meek-client is doing something extremely surprising under the hood).

Yep, that's what occurred to me as well. mcs/brade: aiming for the SOCKS args work to be ready for 9.0a1 seems like a good idea to me. Could you open a child ticket to this bug for that? We can then start shipping Tor Browser with uTLS support in the alphas shaking out bugs and have this ready for 9.0 later this year. However, we should have #28044 done first if possible.

This is quite exciting as it gets rid of the additional browser profiles we ship, too, and brings us a step closer to a Tor Browser without extensions that need a signature requirement exception.

So far I see no drawback of using meek_lite, so let's aim for that one. We can think a bit more about it, though, before we make a final decision in a couple of weeks.

comment:7 Changed 8 months ago by dcf

Heads up, upstream utls fixed a distinguishability bug recently. A second ClientHello (which the client sends after the server sends a HelloRetryRequest) was not being camouflaged correctly. I confirmed that the bug existed with HelloChrome_70 against ajax.aspnetcdn.com, but I haven't personally tested yet that the fix actually fixes it. When I do, I'll update the branch.
https://github.com/refraction-networking/utls/pull/21

comment:8 Changed 8 months ago by yawning

FWIW, I'm > 95% sure that there's another distinguisher.

At some point I'll finish tracking it down/fixing it and update my fork (I rebased/cherry-picked for the HelloRetryRequerst fix already. though I have yet to tag a new version).

comment:9 Changed 8 months ago by gk

Answering here the relevant part of comment:17:ticket:29347 is it seems to fit better:

For my reference when should I have a new tag of utls and obfs4proxy by?
There's a number of fixes I feel are required in the former, but my free
time over the next few weeks will be even tighter than it usually is.

Given that 9.0a1 won't ship before end of March and assuming we want to have the work in this tickets ready for 9.0a1 earliest, then I think within the next 4 weeks would be neat. Alternatively, we could postpone the changes in this bug to 9.0a2 and have the nightly phase longer (assuming the necessary commits are on the respective master branches earlier but no tagged release is available by then).

Last edited 8 months ago by gk (previous) (diff)

comment:10 Changed 8 months ago by yawning

Given that 9.0a1 won't ship before end of March and assuming we want to have the work in this tickets ready for 9.0a1 earliest, then I think within the next 4 weeks would be neat.

I'll see how inspired I feel, and how much "free" time I actually end up having. No promises.

comment:11 Changed 8 months ago by mcs

I filed #29627 for the Tor Launcher work necessary to use meek_lite.

comment:12 in reply to:  7 ; Changed 8 months ago by dcf

Replying to dcf:

Heads up, upstream utls fixed a distinguishability bug recently. A second ClientHello (which the client sends after the server sends a HelloRetryRequest) was not being camouflaged correctly. I confirmed that the bug existed with HelloChrome_70 against ajax.aspnetcdn.com, but I haven't personally tested yet that the fix actually fixes it. When I do, I'll update the branch.
https://github.com/refraction-networking/utls/pull/21

Here's an updated branch with the aforementioned uTLS fix. It also requires a patch, attachment:tor-launcher-Make-uTLS-aware.helloretry.patch, that makes tor-launcher pass the utls= SOCKS arg (applies on top of comment:4:ticket:29627).

Here is a packet capture: attachment:torbrowser-utls-helloretry.pcap.gz. And below are the fingerprints. The first one looks like Chrome, as expected. The second one (sent in response to HelloRetryRequest) seems to be very uncommon, but possibly I am misinterpreting the results. I've asked Sergey to look at it.

Changed 8 months ago by dcf

comment:13 Changed 8 months ago by mcs

The Tor Launcher utls patch looks OK, except there is no need to use this.mMeekUTLS (we can just use a local variable there).

comment:14 in reply to:  12 Changed 8 months ago by dcf

Replying to dcf:

And below are the fingerprints. The first one looks like Chrome, as expected. The second one (sent in response to HelloRetryRequest) seems to be very uncommon, but possibly I am misinterpreting the results. I've asked Sergey to look at it.

Sergey says that the reason the second fingerprint appears uncommon, is that their collection framework currently only captures the first ClientHello on a connection. So they don't have stats for what a ClientHello should look like after HelloRetryRequest.

comment:15 in reply to:  10 ; Changed 5 months ago by gk

Replying to yawning:

Given that 9.0a1 won't ship before end of March and assuming we want to have the work in this tickets ready for 9.0a1 earliest, then I think within the next 4 weeks would be neat.

I'll see how inspired I feel, and how much "free" time I actually end up having. No promises.

Yawning: now that #29627 is merged do you think we are good here to test the meek_lite plan or are there things missing from the obsf4proxy side?

comment:16 in reply to:  15 Changed 5 months ago by yawning

Replying to gk:

I'll see how inspired I feel, and how much "free" time I actually end up having. No promises.

Yawning: now that #29627 is merged do you think we are good here to test the meek_lite plan or are there things missing from the obsf4proxy side?

As long as you use 0.0.10 (and probably af3a8e1682a542b90a4118869befd7a853972d54 from my utls fork), it should be "fine". The reason for the newer utls commit is to pull in an upstream fix that post-dates the obfs4proxy 0.0.10 release.

comment:17 Changed 5 months ago by gk

Keywords: TorBrowserTeam201905 added

Thanks.

comment:18 Changed 4 months ago by gk

Keywords: TorBrowserTeam201906 added; TorBrowserTeam201905 removed

Moving tickets to June

comment:19 Changed 3 months ago by gk

Keywords: TorBrowserTeam201907 added; TorBrowserTeam201906 removed

Moving tickets to July

comment:20 Changed 3 months ago by mcs

Keywords: ff68-esr tbb-9.0-must-nightly TorBrowserTeam201908 added; TorBrowserTeam201907 removed

Since things are broken in an ESR68-based Tor Browser without this (or #29430), I added our ff68-esr and tbb-9.0-must-nightly keywords to this ticket.

comment:21 Changed 3 months ago by pili

Sponsor: Sponsor44-can

Adding Sponsor 44 to ESR68 tickets

comment:22 in reply to:  20 Changed 2 months ago by gk

Replying to mcs:

Since things are broken in an ESR68-based Tor Browser without this (or #29430), I added our ff68-esr and tbb-9.0-must-nightly keywords to this ticket.

mcs/brade: after the updater patch rebasing, if you could pick up this ticket that would be neat.

comment:23 in reply to:  20 ; Changed 2 months ago by mcs

Replying to mcs:

Since things are broken in an ESR68-based Tor Browser without this (or #29430), I added our ff68-esr and tbb-9.0-must-nightly keywords to this ticket.

I think I meant to refer to #29347 in the above comment.
Regardless, our approach for the ESR68-based Tor Browser is to switch to obfs4proxy's meek_lite.

comment:24 Changed 2 months ago by yawning

Assuming you're building obfs4proxy with my utls fork, until 0.0.12 happens, you may want to cherry-pick
https://gitlab.com/yawning/utls/commit/4da67951864128358459681399dd208c49d5d001

ps: Having a spam-prevention regex that triggers off git commit hashes, is sufficiently obnoxious that I will stop replying with that sort of information.

comment:25 in reply to:  24 Changed 2 months ago by mcs

Replying to yawning:

Assuming you're building obfs4proxy with my utls fork, until 0.0.12 happens, you may want to cherry-pick
https://gitlab.com/yawning/utls/commit/4da67951864128358459681399dd208c49d5d001

ps: Having a spam-prevention regex that triggers off git commit hashes, is sufficiently obnoxious that I will stop replying with that sort of information.

Yeah, that is really annoying. Thanks for making the extra effort in this case to tell us about the fix.

Kathy and I don't know how to make the utls cherry pick happen within rbm/tor-browser-build. Maybe boklm can help.

comment:26 Changed 2 months ago by mcs

Cc: boklm added
Keywords: TorBrowserTeam201908R added; TorBrowserTeam201908 removed
Status: newneeds_review

Here is a patch for review:
https://gitweb.torproject.org/user/brade/tor-browser-build.git/commit/?h=bug29430-01&id=03c164be46b4bd2779e9816d24209b3f40ad668e

It does not address comment:24.
Also, there is an additional loose end: the old meek and moat "http helper" browser profiles are not removed. I will file a new ticket to cover that task, since it is OK to wait until after our first ESR68-based alpha for that work.

The above patch requires two Tor Launcher fixes: #31487 and #31488.

comment:27 in reply to:  26 Changed 2 months ago by mcs

Replying to mcs:

Also, there is an additional loose end: the old meek and moat "http helper" browser profiles are not removed. I will file a new ticket to cover that task, since it is OK to wait until after our first ESR68-based alpha for that work.

I created #31491 to track this issue.

comment:28 in reply to:  26 Changed 2 months ago by gk

Keywords: TorBrowserTeam201908 added; TorBrowserTeam201908R removed
Status: needs_reviewneeds_revision

Replying to mcs:

Here is a patch for review:
https://gitweb.torproject.org/user/brade/tor-browser-build.git/commit/?h=bug29430-01&id=03c164be46b4bd2779e9816d24209b3f40ad668e

We should make sure the updated code works for alpha as well. I think the

[% IF c("var/nightly") -%]

blocks need to get amended so that alphas are using the same code path (there is a corresponding var/alpha available) as well.

It does not address comment:24.

If you look at the mingw-w64 project you get a sense of how you can handle it. The config file has something like:

  - filename: libtool-sort.patch
  - filename: 27503.patch

and then the build script are picking those up on top of the actual source code used by using patch:

patch -p1 -d gcc-[% c("var/gcc_version") %] < $rootdir/libtool-sort.patch

and

patch -p1 -d /var/tmp/build/[% project %]-[% c("version") %] < $rootdir/27503.patch

I think a similar approach would work here until we have a proper tag.

comment:29 Changed 2 months ago by mcs

Keywords: TorBrowserTeam201908R added; TorBrowserTeam201908 removed
Status: needs_revisionneeds_review

Here is a second attempt:
https://gitweb.torproject.org/user/brade/tor-browser-build.git/commit/?h=bug29430-02&id=f022ea694df867a6bd06c44cb50c78d674bea9ed

Because the build_go_lib template includes patch support, it is sufficient to just add the .patch file to the goutls project.

Hopefully Kathy and I made the other changes correctly; the rbm template syntax is somewhat dark and murky to us. For example, do the following both have the same effect, or is the extra hyphen significant?

[% IF c("var/nightly") || c("var/alpha") -%]
[% IF c("var/nightly") || c("var/alpha") %]

comment:30 in reply to:  29 Changed 2 months ago by boklm

Replying to mcs:

Hopefully Kathy and I made the other changes correctly; the rbm template syntax is somewhat dark and murky to us. For example, do the following both have the same effect, or is the extra hyphen significant?

[% IF c("var/nightly") || c("var/alpha") -%]
[% IF c("var/nightly") || c("var/alpha") %]

The extra hyphen is removing the trailing newline:
http://www.template-toolkit.org/docs/manual/Syntax.html#section_Chomping_Whitespace

comment:31 Changed 8 weeks ago by gk

Keywords: TorBrowserTeam201908 added; TorBrowserTeam201908R removed
Status: needs_reviewneeds_revision

Alright, this looks mostly good to me. However, it seems selecting meek breaks the circuit display now:

nodeData[i].ip is undefined tor-circuit-display.js:298
    updateCircuitDisplay chrome://torbutton/content/tor-circuit-display.js:298
    onLocationChange chrome://torbutton/content/tor-circuit-display.js:327
    callListeners chrome://browser/content/tabbrowser.js:841
    _callProgressListeners chrome://browser/content/tabbrowser.js:861
    _callProgressListeners chrome://browser/content/tabbrowser.js:5499
    onLocationChange chrome://browser/content/tabbrowser.js:5919
    _callProgressListeners resource://gre/modules/RemoteWebProgress.jsm:119
    onLocationChange resource://gre/modules/RemoteWebProgress.jsm:161
    receiveMessage resource://gre/modules/RemoteWebProgress.jsm:286

comment:32 in reply to:  23 ; Changed 8 weeks ago by dcf

Replying to mcs:

Replying to mcs:

Since things are broken in an ESR68-based Tor Browser without this (or #29430), I added our ff68-esr and tbb-9.0-must-nightly keywords to this ticket.

I think I meant to refer to #29347 in the above comment.
Regardless, our approach for the ESR68-based Tor Browser is to switch to obfs4proxy's meek_lite.

I'll go ahead and merge #29347 (port to WebExtension) then, since Tor Browser no longer depends on the the legacy add-on.

comment:33 in reply to:  31 Changed 8 weeks ago by mcs

Keywords: TorBrowserTeam201908R added; TorBrowserTeam201908 removed
Status: needs_revisionneeds_review

Replying to gk:

Alright, this looks mostly good to me. However, it seems selecting meek breaks the circuit display now:

nodeData[i].ip is undefined tor-circuit-display.js:298
    ...

Thanks for catching that bug. It turns out that we also need a small patch to Torbutton:
https://gitweb.torproject.org/user/brade/torbutton.git/commit/?h=bug29430-01&id=844693481ce92bb34536113a318211cbaedde4bd

This will fix the immediate problem. In the long run, the control port response parser and circuit display code should be more robust and not completely fail when it sees a bridge type that it does not recognize.

comment:34 Changed 8 weeks ago by gk

Keywords: tbb-9.0-must-nightly removed
Status: needs_reviewnew

Alright, we are done here. \o/ I merged the patch for Torbutton with commit 605decfd4ddc81eb37da17172f48f92fd7f7e451 into master and the one for tor-browse-build with commit 0a7bef243d182fb3df3d9f6ebfd74ce632ad95d1 into master.

Moving this ticket into a pure parent one for #31491.

comment:35 in reply to:  32 Changed 8 weeks ago by gk

Replying to dcf:

Replying to mcs:

Replying to mcs:

Since things are broken in an ESR68-based Tor Browser without this (or #29430), I added our ff68-esr and tbb-9.0-must-nightly keywords to this ticket.

I think I meant to refer to #29347 in the above comment.
Regardless, our approach for the ESR68-based Tor Browser is to switch to obfs4proxy's meek_lite.

I'll go ahead and merge #29347 (port to WebExtension) then, since Tor Browser no longer depends on the the legacy add-on.

Sounds good.

comment:36 Changed 8 weeks ago by cypherpunks

TorBrowserTeam201908R->TorBrowserTeam201908

comment:37 in reply to:  36 Changed 8 weeks ago by brade

Keywords: TorBrowserTeam201908 added; TorBrowserTeam201908R removed

Replying to cypherpunks:

TorBrowserTeam201908R->TorBrowserTeam201908

Thanks. Fixed.

comment:38 Changed 7 weeks ago by gk

Keywords: TorBrowserTeam201909 added; TorBrowserTeam201908 removed

Moving tickets to September

comment:39 Changed 7 weeks ago by intrigeri

Cc: intrigeri added

comment:40 Changed 4 weeks ago by gk

Resolution: fixed
Status: newclosed

We are done here, woo!

comment:41 Changed 3 weeks ago by mcs

Resolution: fixed
Status: closedreopened

Reopening temporarily so I can add Actual Points to #31491

comment:42 Changed 3 weeks ago by mcs

Resolution: fixed
Status: reopenedclosed
Note: See TracTickets for help on using tickets.