Giter VIP home page Giter VIP logo

tor-router's Introduction

Tor Router

NPM

FOSSA Status

Tor Router is a SOCKS5, DNS and HTTP proxy server for distributing traffic across multiple instances of Tor. At startup Tor Router will run an arbitrary number of instances Tor and each request will be sent to a different instance in round-robin fashion. This can be used to increase anonymity, because each request will be sent on a different circuit and will most likely use a different exit-node, and also to increase performance since outbound traffic is now split across several instances of Tor.

A list of changes can be found here.

Building and Running

The only installation requirement is node.js. Tor is bundled with the application. To use an external Tor executable use the --torPath command line switch or set the TOR_PATH environment variable.

To install run: npm install To start run: bin/tor-router

To install globally run: npm install -g tor-router

Alternatively docker can be used. The build will retrieve the latest version of Tor from the offical Tor Project repository.

To build run: docker build -t znetstar/tor-router . To start run: docker run --rm -it -p 9050:9050 znetstar/tor-router

Usage

The following command line switches and their environment variable equivalents are available for use:

If just a port number is passed in place of a host, it will bind to all interfaces.

Command line switch Environment Variable Description
-f, --config Path to a JSON configuration file to use
-c, --controlHost CONTROL_HOST Host the control server will bind to and listen for TCP traffic (see below)
-w, --websocketControlHost WEBSOCKET_CONTROL_HOST Host the control server will bind to and listen for WebSocket traffic
-j, --instances INSTANCES Number of Tor instances to spawn
-s, --socksHost SOCKS_HOST Host the SOCKS proxy will bind to
-d, --dnsHost DNS_HOST Host the DNS proxy will bind to
-h, --httpHost HTTP_HOST Host the HTTP proxy will bind to
-l, --logLevel LOG_LEVEL Log level (defaults to "info") set to "null" to disable logging. To see a log of all network traffic set logLevel to "verbose"
-p, --parentDataDirectory PARENT_DATA_DIRECTORY Parent directory that will contain the data directories for the instances
-b, --loadBalanceMethod LOAD_BALANCE_METHOD Method that will be used to sort the instances between each request. Currently supports "round_robin" and "weighted".
-t, --torPath TOR_PATH Provide the path for the Tor executable that will be used
-n, --proxyByName PROXY_BY_NAME Controls how authenticated requests will be handled. Can be set to "individual", "group" or false to disable

A full list of all available configuration options and their defaults can be found in default_config.js

For example: tor-router -j 3 -s 127.0.0.1:9050 would start the proxy with 3 tor instances and listen for SOCKS connections on localhost:9050.

Documentation

For detailed examples and insturctions on using Tor Router see the wiki.

Documentation is available in docs/. An online version of the documentation is also available here.

Testing

Tests are written in mocha and can be found under test/ and can be run with npm test

tor-router's People

Contributors

dependabot[bot] avatar jogli5er avatar knoxcard avatar znetstar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tor-router's Issues

pm2 support

Hi, I'm trying to run tor-router as PM2 process, but no matter what, the instances count remains 1, I've passed different values as -j 3 or -j 5 , Weird part is every argument parses fine till the point
234 > nconf.argv(argv_config); (launch.js)
but after that if you do nconf.get('instances'); it gives output of 1, always when running via PM2.
I'm not sure if it's a bug with pm2 or nconf coupled with pm2 , but It's kind of use case i'm trying to accomplish,

npm start failing

cat@cate-ssd:~/Projects/tor-router$ npm run start

> [email protected] start /home/cat/Projects/tor-router
> bin/tor-router -s -d -j 1

info: [control]: control server listening on tcp://:9077
/home/cat/Projects/tor-router/node_modules/multi-rpc-tcp-transport/lib/TCPTransport.js:145
                this.server.off('error', listenError);
                            ^

TypeError: this.server.off is not a function
    at Server.listenSuccess (/home/cat/Projects/tor-router/node_modules/multi-rpc-tcp-transport/lib/TCPTransport.js:145:29)
    at Object.onceWrapper (events.js:272:13)
    at Server.emit (events.js:180:13)
    at emitListeningNT (net.js:1373:10)
    at process._tickCallback (internal/process/next_tick.js:178:19)
    at Function.Module.runMain (internal/modules/cjs/loader.js:697:11)
    at startup (internal/bootstrap/node.js:201:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `bin/tor-router -s -d -j 1`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/cat/.npm/_logs/2019-01-15T14_21_05_715Z-debug.log

Minimize IP overlap?

I want a separate instance or ip for several "users" and I want to avoid the ips overlapping for each set of requests as much as possible... however I read requests using this router are sent in a "round robin" fashion?

Is this possible using this library?

Browser Support

I am looking to use tor in my website for certain api request. I was wondering if this library can be used in browser via webpack like libraries. If not do you know of any other tor library that comes bundled with tor that can be used as such.

socket hang up

Hi, I'm running the Docker image and sending a request via nodejs
this is my code

import * as request from 'request';

request.get('http://example.com/', {
    proxy:'http://localhost:1637',    
},(e,r,b)=>{
    console.log(e)
    console.log(b)
    console.log(r)
})

this is my output of the code:

{ Error: socket hang up
    at createHangUpError (_http_client.js:323:15)
    at Socket.socketOnEnd (_http_client.js:426:23)
    at Socket.emit (events.js:203:15)
    at endReadableNT (_stream_readable.js:1145:12)
    at process._tickCallback (internal/process/next_tick.js:63:19) code: 'ECONNRESET' }

and these are my logs from Docker run:

>> docker run --rm -it -p 1637:9050 znetstar/tor-router -j 3 -h 127.0.0.1:9050

info: [control]: control server listening on tcp://:9077
info: [tor]: starting 3 tor instance(s)...
info: [tor-mXwaXKrDTKhS]: DNS PORT = 33353
info: [tor-mXwaXKrDTKhS]: SOCKS PORT = 46205
info: [tor-mXwaXKrDTKhS]: CONTROL PORT = 35985
info: [tor-ThoNeFBBQbV4]: DNS PORT = 42767
info: [tor-ThoNeFBBQbV4]: SOCKS PORT = 35143
info: [tor-ThoNeFBBQbV4]: CONTROL PORT = 40665
info: [tor-PL7fQWJDejLo]: DNS PORT = 34869
info: [tor-PL7fQWJDejLo]: SOCKS PORT = 37579
info: [tor-PL7fQWJDejLo]: CONTROL PORT = 44301
info: [http]: listening on http://127.0.0.1:9050
info: [tor-mXwaXKrDTKhS]: tor is ready
warn: [tor-PL7fQWJDejLo]: Unparseable microdescriptor

warn: [tor-PL7fQWJDejLo]: Illegal nickname "$B771AA877687F88E6F1CA5354756DF6C8A7B6B2" in family line

info: [tor-PL7fQWJDejLo]: tor is ready
info: [tor-ThoNeFBBQbV4]: tor is ready
info: [tor]: tor started

Not able to run tor-router with instances

when I am trying to run tor-router -j 3 -s 127.0.0.1:16379 with node v10.17.0 and npm 6.13.0

`info: [control]: control server listening on tcp://:9077
info: [tor]: starting 3 tor instance(s)...
info: [socks]: listening on socks5://127.0.0.1:16379
events.js:174
throw er; // Unhandled 'error' event
^

Error: spawn /home/shibu/Downloads/node_modules/granax/bin/tor-browser_en-US/Browser/TorBrowser/Tor/tor ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at Process.ChildProcess._handle.onexit (internal/child_process.js:246:12)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
`

Also, granax dependencies are changes to @deadcanaries/granax. Can you please help me fixing the issue.

@deadcanaries/granax module used to download Tor is AGPL but tor-router is Apache 2.0

tor-router links to a module, @deadcanaries/granax, which downloads and installs tor locally within the application, among other things. This module carries the AGPL 3.0 license, and my understanding of this license is that any works using it would also need to be licensed as AGPL 3.0.

I see tor-router is licensed as Apache 2.0. Is this license valid, considering it is using an AGPL 3.0 component?

Thank you,

Race Condition when getting Ports for instances in TorPool

When populating TorPool with a larger number of TorProcesses, a race condition appears when getting the ports. This is a known problem of the get-port package (Compare sindresorhus/get-port#23), but as there is no better solution so far I suggest that we shift getting the default ports outside of the TorProcess into the creation function of the TorPool and protect the execution of the getPort function, such that no race conditions should appear.
A suggested fix can be found in pull request #14

Possible EventEmitter memory leak detected

Hi,
I've run into the following issue and did not yet find a workaround.
Setup information: I run tor-router within a Docker container and on docker start, only the Control Server is initialized.
Afterward, a Tor pool, a socket server and ten Tor instances are created in code (see below), which seems to work as expected, since the logs show

[control]: Control Server listening on 9077
[socks]: listening on 9050
[tor-19]: tor is ready
[tor-22]: tor is ready
... [more output omitted]

Creation of Tor pool/socket server & Tor instances:

    async createTorPool() {
        let rpcId = this.currentRPCId;
        this.currentRPCId += 1;
        let createTorRequest = {
            "method": "createTorPool",
            "params": [],
            "jsonrpc": "2.0",
            "id": rpcId,
        };
        this.client.write(JSON.stringify(createTorRequest));
        return new Promise( (resolve, reject) => {
            this.client.on("data", (chunk) => {
                let rawResponse = chunk.toString("utf8");
                let rpcResponse = JSON.parse( rawResponse );
                if (rpcResponse.id === rpcId) {
                    resolve(rpcResponse);
                }
            });
            setTimeout(() => {
                reject("createTorPool request timed out.");
            }, this.timeout);
        });
    }
    async createSocksServer(socksPort) {
        // Set torPort to 9050 (Tor standard), if undefined
        if (socksPort) {
            this.socksPort = socksPort;
        }
        if (!this.socksPort) {
            this.socksPort = 9050;
        }
        let rpcId = this.currentRPCId;
        this.currentRPCId += 1;
        let createSocksRequest = {
            "method": "createSOCKSServer",
            "params": [socksPort],
            "jsonrpc": "2.0",
            "id": rpcId,
        };
        this.client.write(JSON.stringify(createSocksRequest));
        return new Promise( (resolve, reject) => {
            this.client.on("data", (chunk) => {
                let rawResponse = chunk.toString("utf8");
                let rpcResponse = JSON.parse( rawResponse );
                if (rpcResponse.id === rpcId) {
                    resolve(rpcResponse);
                }
            });
            setTimeout(() => {
                reject("createSocksServer request timed out.");
            }, this.timeout);
        });
    }
    async createTorInstances(numOfInstances) {
        let rpcId = this.currentRPCId;
        this.currentRPCId += 1;
        let createTorInstancesRequest = {
            "method": "createInstances",
            "params": [numOfInstances],
            "jsonrpc": "2.0",
            "id": rpcId,
        };
        this.client.write(JSON.stringify(createTorInstancesRequest));
        return new Promise( (resolve, reject) => {
            this.client.on( "data", (chunk) => {
                let rawResponse = chunk.toString("utf8");
                let rpcResponse = JSON.parse( rawResponse );
                if (rpcResponse.id == rpcId) {
                    resolve(rpcResponse);
                }
            });
            setTimeout(() => {
                reject("createTorInstances timed out.");
            }, this.timeout);
        });
    }

However, if I send a request to the socks proxy (See code section below), the logs say

    (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use 
    emitter.setMaxListeners() to increase limit.
    Trace
        at TorPool.logPossibleMemoryLeak (/app/node_modules/eventemitter2/lib/eventemitter2.js:53:15)
        at TorPool.EventEmitter.on (/app/node_modules/eventemitter2/lib/eventemitter2.js:517:31)
        at TorPool.EventEmitter.many (/app/node_modules/eventemitter2/lib/eventemitter2.js:269:10)
        at TorPool.EventEmitter.once (/app/node_modules/eventemitter2/lib/eventemitter2.js:249:10)
        at SOCKSServer.handleConnection (/app/src/SOCKSServer.js:75:14)
        at emitThree (events.js:136:13)
        at SOCKSServer.emit (events.js:217:7)
        at Parser.<anonymous> (/app/node_modules/socksv5/lib/server.js:130:12)
        at emitOne (events.js:116:13)
        at Parser.emit (events.js:211:7)

Code for sending the request over the SOCKS proxy:

     let headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0",
            "Accept-Language": "en-US,en;q=0.5",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Encoding": "identity",
            "Connection": "keep-alive",
        };

        let request = {
            method: "GET",
            hostname: url,
            path: path,
            agent: new ProxyAgent("socks://127.0.0.1:9050"),
            headers: headers,
        };
        let startTime = (new Date).getTime();
        let request = http.get(request);

The same appears if I set the SOCKS proxy as the proxy of my browser and try to connect to a website.

So my question is: Is this an issue in my code and if yes: how should a request over this proxy be structured?

Thank you for your response!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.