Search code examples
javaandroidsecurityprivacytor

Using Meek Transport


I am trying to integrate Meek in an Android application. There is a sample here that shows how to instantiate the transport:

https://github.com/guardianproject/AndroidPluggableTransports/blob/master/sample/src/main/java/info/pluggeabletransports/sample/SampleClientActivity.java

The question is what do I do from there. Assuming I have an application that uses OkHttp3. Is there a way to reconcile both and use OkHttp3 as underlying transport mechanism while the app only interacts with Okhttp3?

I am also quite conflicted on how to instantiate the transport and what each option means. In the link provided above, the transport is instantiate as follows:

private void initMeekTransport() {
    new MeekTransport().register();

    Properties options = new Properties();
    String remoteAddress = "185.152.65.180:9001";// a public Tor guard to test

    options.put(MeekTransport.OPTION_URL,"https://meek.azureedge.net/"); //the public Tor Meek endpoint
    options.put(MeekTransport.OPTION_FRONT, "ajax.aspnetcdn.com"); //the domain fronting address to use
    options.put(MeekTransport.OPTION_KEY, "97700DFE9F483596DDA6264C4D7DF7641E1E39CE"); //the key that is needed for this endpoint

    init(DispatchConstants.PT_TRANSPORTS_MEEK, remoteAddress, options);
}

However, in the README (https://github.com/guardianproject/AndroidPluggableTransports), the suggested approach is:

Properties options = new Properties();
String bridgeAddress = "https://meek.actualdomain.com";
options.put(MeekTransport.OPTION_FRONT,"www.somefrontabledomain.com");
options.put(MeekTransport.OPTION_KEY,"18800CFE9F483596DDA6264C4D7DF7331E1E39CE");
init("meek", bridgeAddress, options);
Transport transport = Dispatcher.get().getTransport(this, PT_TRANSPORTS_MEEK, options);
if (transport != null)
{
        Connection conn = transport.connect(bridgeAddress);
        //now use the connection, either as a proxy, or to read and write bytes directly
        if (conn.getLocalAddress() != null && conn.getLocalPort() != -1)
            setSocksProxy (conn.getLocalAddress(), conn.getLocalPort());


        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write("GET https://somewebsite.org/TheProject.html HTTP/1.0".getBytes());
        conn.write(baos.toByteArray());

        byte[] buffer = new byte[1024*64];
        int read = conn.read(buffer,0,buffer.length);
        String response = new String(buffer);
}

In the latter approach, the bridge address is passed to the init() method. In the first approach it is the remote address that is passed to the init() method while the bridge address is passed as option. Which one of these approaches is the right one?

Furthermore, I would appreciate some comments on OPTION_URL, OPTION_FRONT, and OPTION_KEY. Where does each of these pieces of information come from? If I do not want to use these default information, how do i go about setting up a "Meek endpoint" for instance to not use the default Tor one? Anything particular needs to be done on the CDN? How would I use Amazon or Google instead of aspnetcdn?

As you can see, I am fairly confused.


Solution

  • Thanks for your interest in this library. Unfortunately, we haven't made a formal release yet, and it is still quite early in its development.

    However, we think that we can help still.

    First, it should be made clear that the major cloud providers (Google, Amazon, Azure) that support domain fronting, are now very much against it. Thus, you might find some limitation in using any of those platforms, especially with a fronted domain that you do not control.

    You can read about Tor and Signal's own struggle with this here: https://signal.org/blog/looking-back-on-the-front/ and https://blog.torproject.org/domain-fronting-critical-open-web

    Now, that said, if you still want to proceed with domain fronting, and all you are using is HTTP/S, then you can do so, without using Meek at all. You simple need to set the "Host" header on your request to the actual domain you want to access, while the request itself using the fronted domain. It is actually quite simple.

    You can read more here: https://www.bamsoftware.com/papers/fronting/#sec:introduction