Opened 3 months ago

Last modified 11 days ago

#29430 new enhancement

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, TorBrowserTeam201905
Cc: mcs, brade, yawning Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

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

Attachments (4)

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

Download all attachments as: .zip

Change History (21)

comment:1 Changed 3 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 3 months ago by dcf

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

Changed 3 months ago by dcf

Attachment: meek-client-utls_2.pcap added

comment:2 Changed 3 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 3 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 3 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 3 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 3 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 3 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 3 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 3 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 3 months ago by gk (previous) (diff)

comment:10 Changed 3 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 3 months ago by mcs

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

comment:12 in reply to:  7 ; Changed 3 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 3 months ago by dcf

comment:13 Changed 3 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 2 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 11 days 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 11 days 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 11 days ago by gk

Keywords: TorBrowserTeam201905 added

Thanks.

Note: See TracTickets for help on using tickets.