Connects to the Tor instance via the control port when the instance starts
This commit is contained in:
parent
b3700e0202
commit
4bc4c15dd7
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -770,6 +770,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||||
},
|
},
|
||||||
|
"interpret": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ="
|
||||||
|
},
|
||||||
"invert-kv": {
|
"invert-kv": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||||
|
@ -5825,6 +5830,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||||
},
|
},
|
||||||
|
"path-parse": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
|
||||||
|
},
|
||||||
"performance-now": {
|
"performance-now": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
|
@ -5890,6 +5900,14 @@
|
||||||
"util-deprecate": "1.0.2"
|
"util-deprecate": "1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rechoir": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
|
||||||
|
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
|
||||||
|
"requires": {
|
||||||
|
"resolve": "1.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"version": "2.85.0",
|
"version": "2.85.0",
|
||||||
"resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
|
"resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
|
||||||
|
@ -5930,6 +5948,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
||||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
||||||
},
|
},
|
||||||
|
"resolve": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
|
||||||
|
"requires": {
|
||||||
|
"path-parse": "1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.2.8",
|
"version": "2.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
|
||||||
|
@ -5968,6 +5994,16 @@
|
||||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
||||||
},
|
},
|
||||||
|
"shelljs": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz",
|
||||||
|
"integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==",
|
||||||
|
"requires": {
|
||||||
|
"glob": "7.1.2",
|
||||||
|
"interpret": "1.1.0",
|
||||||
|
"rechoir": "0.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
"nanoid": "^1.0.2",
|
"nanoid": "^1.0.2",
|
||||||
"native-dns": "git+https://github.com/znetstar/node-dns.git",
|
"native-dns": "git+https://github.com/znetstar/node-dns.git",
|
||||||
"nconf": "^0.10.0",
|
"nconf": "^0.10.0",
|
||||||
|
"shelljs": "^0.8.2",
|
||||||
"socks-proxy-agent": "^3.0.1",
|
"socks-proxy-agent": "^3.0.1",
|
||||||
"socksv5": "git+https://github.com/lee-elenbaas/socksv5.git",
|
"socksv5": "git+https://github.com/lee-elenbaas/socksv5.git",
|
||||||
"temp": "^0.8.3",
|
"temp": "^0.8.3",
|
||||||
|
|
|
@ -6,15 +6,21 @@ const getPort = require('get-port');
|
||||||
const del = require('del');
|
const del = require('del');
|
||||||
const EventEmitter = require('eventemitter2').EventEmitter2;
|
const EventEmitter = require('eventemitter2').EventEmitter2;
|
||||||
const temp = require('temp');
|
const temp = require('temp');
|
||||||
|
const { TorController } = require('granax');
|
||||||
|
const { connect } = require('net');
|
||||||
|
const shell = require('shelljs');
|
||||||
|
const crypto = require('crypto');
|
||||||
temp.track();
|
temp.track();
|
||||||
|
|
||||||
class TorProcess extends EventEmitter {
|
class TorProcess extends EventEmitter {
|
||||||
constructor(tor_path, config, logger, nconf) {
|
constructor(tor_path, config, logger, nconf, granax_options) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.tor_path = tor_path || nconf.get('torPath');
|
this.tor_path = tor_path || nconf.get('torPath');
|
||||||
this.nconf = nconf;
|
this.nconf = nconf;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
this.granax_options = granax_options || nconf.get('granaxOptions');
|
||||||
|
this.control_password = crypto.randomBytes(128).toString('base64');
|
||||||
|
|
||||||
config.DataDirectory = config.DataDirectory || temp.mkdirSync();
|
config.DataDirectory = config.DataDirectory || temp.mkdirSync();
|
||||||
|
|
||||||
|
@ -45,14 +51,25 @@ class TorProcess extends EventEmitter {
|
||||||
return this._socks_port || null;
|
return this._socks_port || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get control_port() {
|
||||||
|
return this._control_port || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get controller() {
|
||||||
|
return this._controller;
|
||||||
|
}
|
||||||
|
|
||||||
create(callback) {
|
create(callback) {
|
||||||
async.auto({
|
async.auto({
|
||||||
dnsPort: (callback) => getPort().then(port => callback(null, port)),
|
dnsPort: (callback) => getPort().then(port => callback(null, port)),
|
||||||
socksPort: (callback) => getPort().then(port => callback(null, port)),
|
socksPort: (callback) => getPort().then(port => callback(null, port)),
|
||||||
configPath: ['dnsPort', 'socksPort', (context, callback) => {
|
controlPort: (callback) => getPort().then(port => callback(null, port)),
|
||||||
|
configPath: ['dnsPort', 'socksPort', 'controlPort', (context, callback) => {
|
||||||
let options = {
|
let options = {
|
||||||
DNSPort: `127.0.0.1:${context.dnsPort}`,
|
DNSPort: `127.0.0.1:${context.dnsPort}`,
|
||||||
SocksPort: `127.0.0.1:${context.socksPort}`,
|
SocksPort: `127.0.0.1:${context.socksPort}`,
|
||||||
|
ControlPort: `127.0.0.1:${context.controlPort}`,
|
||||||
|
HashedControlPassword: shell.exec(`${this.tor_path} --hash-password "${this.control_password}"`, { async: false, silent: true }).stdout.trim()
|
||||||
};
|
};
|
||||||
let config = _.extend(_.extend({}, this.tor_config), options);
|
let config = _.extend(_.extend({}, this.tor_config), options);
|
||||||
let text = Object.keys(config).map((key) => `${key} ${config[key]}`).join("\n");
|
let text = Object.keys(config).map((key) => `${key} ${config[key]}`).join("\n");
|
||||||
|
@ -70,13 +87,14 @@ class TorProcess extends EventEmitter {
|
||||||
|
|
||||||
this._dns_port = context.dnsPort;
|
this._dns_port = context.dnsPort;
|
||||||
this._socks_port = context.socksPort;
|
this._socks_port = context.socksPort;
|
||||||
|
this._control_port = context.controlPort;
|
||||||
|
|
||||||
let tor = spawn(this.tor_path, ['-f', context.configPath], {
|
let tor = spawn(this.tor_path, ['-f', context.configPath], {
|
||||||
stdio: ['ignore', 'pipe', 'pipe'],
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
detached: false,
|
detached: false
|
||||||
shell: '/bin/bash'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
tor.on('close', (code) => {
|
tor.on('close', (code) => {
|
||||||
this.emit('process_exit', code);
|
this.emit('process_exit', code);
|
||||||
if (this.definition && !this.definition.Name) {
|
if (this.definition && !this.definition.Name) {
|
||||||
|
@ -95,6 +113,22 @@ class TorProcess extends EventEmitter {
|
||||||
this.logger && this.logger.info(`[tor-${this.instance_name}]: tor is ready`);
|
this.logger && this.logger.info(`[tor-${this.instance_name}]: tor is ready`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.on('control_listen', () => {
|
||||||
|
this._controller = new TorController(connect(this._control_port), _.extend({ authOnConnect: false }, this.granax_options));
|
||||||
|
this.controller.on('ready', () => {
|
||||||
|
this.logger && this.logger.debug(`[tor-${this.instance_name}]: connected to tor control port`);
|
||||||
|
this.controller.authenticate(`"${this.control_password}"`, (err) => {
|
||||||
|
if (err) {
|
||||||
|
this.logger && this.logger.error(`[tor-${this.instance_name}]: ${err.stack}`);
|
||||||
|
this.emit('error', err);
|
||||||
|
} else {
|
||||||
|
this.logger && this.logger.debug(`[tor-${this.instance_name}]: authenticated with tor instance via the control port`);
|
||||||
|
this.emit('controller_ready');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
tor.stdout.on('data', (data) => {
|
tor.stdout.on('data', (data) => {
|
||||||
let text = Buffer.from(data).toString('utf8');
|
let text = Buffer.from(data).toString('utf8');
|
||||||
let msg = text.split('] ').pop();
|
let msg = text.split('] ').pop();
|
||||||
|
@ -102,17 +136,29 @@ class TorProcess extends EventEmitter {
|
||||||
this.emit('ready');
|
this.emit('ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (text.indexOf('Opening Control listener on') !== -1) {
|
||||||
|
this.emit('control_listen');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.indexOf('Opening Socks listener on') !== -1) {
|
||||||
|
this.emit('socks_listen');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.indexOf('Opening DNS listener on') !== -1) {
|
||||||
|
this.emit('dns_listen');
|
||||||
|
}
|
||||||
|
|
||||||
if (text.indexOf('[err]') !== -1) {
|
if (text.indexOf('[err]') !== -1) {
|
||||||
this.emit('error', new Error(msg));
|
this.emit('error', new Error(msg));
|
||||||
this.logger && this.logger.error(`[tor-${tor.pid}]: ${msg}`);
|
this.logger && this.logger.error(`[tor-${this.instance_name}]: ${msg}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (text.indexOf('[notice]') !== -1) {
|
else if (text.indexOf('[notice]') !== -1) {
|
||||||
this.logger && this.logger.debug(`[tor-${tor.pid}]: ${msg}`);
|
this.logger && this.logger.debug(`[tor-${this.instance_name}]: ${msg}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (text.indexOf('[warn]') !== -1) {
|
else if (text.indexOf('[warn]') !== -1) {
|
||||||
this.logger && this.logger.warn(`[tor-${tor.pid}]: ${msg}`);
|
this.logger && this.logger.warn(`[tor-${this.instance_name}]: ${msg}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -40,4 +40,5 @@ module.exports = {
|
||||||
"options": {},
|
"options": {},
|
||||||
"timeout": null
|
"timeout": null
|
||||||
},
|
},
|
||||||
|
"granaxOptions": null
|
||||||
};
|
};
|
Loading…
Reference in a new issue