Search code examples
androidkotlinnetworkingproxytor

Android: Connecting to Tor SOCKS proxy at port 9150 throws a `SocketException`; only works if I install Tor Android app


I'm creating an Android Jsoup web scraper app which connects to Tor via a SOCKS proxy at port 9150, (I want the requests to be completely anonymous):

    private const val TOR_PORT = 9040

    private fun establishJsoupConnection(url: String): Connection {
        return if (!useTor) {
            Jsoup.connect(url)
        } else {
            val socketAddress = InetSocketAddress("127.0.0.1", TOR_PORT)
            val proxy = Proxy(Proxy.Type.SOCKS, socketAddress)
            Jsoup.connect(url).proxy(proxy)
        }
    }

I am not using any special library to establish the connection, just the ones provided by the JDK. There are Tor libraries for Android out there, although I was told that they were not needed.

The issue is that whenever I run the code, I get the following exception:

java.net.SocketException: failed to connect to /127.0.0.1 (port 9150) from /127.0.0.1 (port 47806) after 30000ms: isConnected failed: ECONNREFUSED (Connection refused)

The first thing I tried was to change the port number from 9040 to the many other Tor ports that you can connect to, this did not work. I had a similar issue in which changing the port did help, though in this case it didn't. Please note that the issue is only recreatable on Android, if I run the code on my desktop it works fine -- although I do have Tor installed on my desktop so it may also be why.

I tried other things as well, such as replacing 127.0.0.1 with localhost -- this did nothing to fix this. I have also tried looking online for other solutions as well but to no avail. I also tried to completely disable my firewall but that didn't fix things.

There was one thing that did 'temporarily' solve the issue, which was installing the Tor Android app from F-Droid.

For some reason, the proxy only works if I install the Tor Android app and then re-run the app, but if I uninstall the Tor Android app the exception comes back again.

What I'm guessing is that the Tor Android app is doing something in the background to allow a connection.

The Tor Android app (Tor) is complex, and I'll most likely never find out what it's 'doing' in the background to establish a connection, which is why I am asking for assistance.

I'm honestly surprised, I do not really have any idea in my head of what the app even could be doing to establish a connection. I thought that it could be something to do with firewall, although I've disabled firewall for my app and it's not doing a difference. It doesn't help as well that I'm new to networking in itself.


Solution

  • In order to connect to Tor via a SOCKS proxy, your device must be connected to the Tor network and configured to open the SOCKS port for proxying over Tor.

    The reason the proxy only works when you install and run the Tor Browser app is because that app connects to the Tor network and listens on port 9150 for SOCKS connections and sends them over Tor.

    If you want your app to be able to make anonymous connections through Tor, then something on the device, or your app, needs to handle connecting to the network and relaying connections.

    One simple way that you found is to run the Tor Browser app and configure your SOCKS client to use 127.0.0.1:9150. One advantage to this method is that Tor related updates are handled by the Tor Browser app. Orbot is another app that could be used in the same way.

    In the comments you pointed out a library that embeds a Tor executable used for connecting to Tor and facilitating connections. This is a good option if you don't want to depend on running another app to connect and run the Tor SOCKS proxy. The drawback is, you might need to update your app more frequently to include critical updates to the Tor binaries.

    In summary, for the proxy to work, there has to be some software on the device that handles the Tor connection and provides the SOCKS port for you to use in your app.