Change Tor exit list

Use the endpoint suggested in #688 to avoid unnecessarilly banning
relays.
This commit is contained in:
Calvin Montgomery 2017-06-17 10:12:15 -07:00
parent 6161f4ad44
commit a96f7976d8
2 changed files with 70 additions and 70 deletions

View File

@ -2,7 +2,7 @@
"author": "Calvin Montgomery", "author": "Calvin Montgomery",
"name": "CyTube", "name": "CyTube",
"description": "Online media synchronizer and chat", "description": "Online media synchronizer and chat",
"version": "3.38.2", "version": "3.38.3",
"repository": { "repository": {
"url": "http://github.com/calzoneman/sync" "url": "http://github.com/calzoneman/sync"
}, },

View File

@ -1,87 +1,87 @@
var https = require("https"); import https from 'https';
var path = require("path"); import path from 'path';
var fs = require("fs"); import fs from 'fs';
var domain = require("domain");
import { LoggerFactory } from '@calzoneman/jsli'; import { LoggerFactory } from '@calzoneman/jsli';
import Promise from 'bluebird';
const LOGGER = LoggerFactory.getLogger('tor'); Promise.promisifyAll(fs);
function retrieveIPs(cb) { const LOGGER = LoggerFactory.getLogger('torlist');
var options = { const TOR_EXIT_LIST_URL = 'https://check.torproject.org/exit-addresses';
host: "www.dan.me.uk", const TOR_EXIT_LIST_FILE = path.join(__dirname, '..', 'tor-exit-list.json');
port: 443, const ONE_DAY = 24 * 3600 * 1000;
path: "/torlist/", const TOR_EXIT_IPS = new Set();
method: "GET"
};
var finish = function (status, data) { function loadTorList() {
if (status !== 200) { return fs.statAsync(TOR_EXIT_LIST_FILE).then(stats => {
cb(new Error("Failed to retrieve Tor IP list (HTTP " + status + ")"), null); if (new Date() - stats.mtime > ONE_DAY) {
return; LOGGER.info('Tor exit node list is older than 24h, re-downloading from %s',
TOR_EXIT_LIST_URL);
return loadTorListFromWebsite();
} else {
return loadTorListFromFile();
}
}).catch(error => {
if (error.code === 'ENOENT') {
LOGGER.info('File %s not found, downloading from %s',
TOR_EXIT_LIST_FILE,
TOR_EXIT_LIST_URL);
return loadTorListFromWebsite();
} else {
throw error;
} }
var ips = data.split("\n");
cb(false, ips);
};
var d = domain.create();
d.on("error", function (err) {
if (err.stack)
LOGGER.error(err.stack);
else
LOGGER.error(err);
});
d.run(function () {
var req = https.request(options, function (res) {
var buffer = "";
res.setEncoding("utf-8");
res.on("data", function (data) { buffer += data; });
res.on("end", function () { finish(res.statusCode, buffer); });
});
req.end();
}); });
} }
function getTorIPs(cb) { function loadTorListFromWebsite() {
retrieveIPs(function (err, ips) { return new Promise((resolve, reject) => {
if (!err) { https.get(TOR_EXIT_LIST_URL, res => {
cb(false, ips); if (res.statusCode !== 200) {
const destination = path.join(__dirname, "..", "torlist"); reject(new Error(`${res.statusCode} ${res.statusMessage}`));
fs.writeFile(destination,
ips.join("\n"),
error => {
if (error) {
LOGGER.error("Failed to write to %s: %s", destination, error);
}
});
return;
}
fs.readFile(path.join(__dirname, "..", "torlist"), function (err, data) {
if (err) {
cb(err, null);
return; return;
} }
data = (""+data).split("\n"); let buffer = '';
cb(false, data); res.on('data', data => buffer += data);
}); res.on('end', () => {
const exitNodes = buffer.split('\n').filter(line => {
return /^ExitAddress/.test(line);
}).map(line => {
return line.split(' ')[1];
});
fs.writeFileAsync(TOR_EXIT_LIST_FILE, JSON.stringify(exitNodes))
.then(() => {
LOGGER.info('Saved %s', TOR_EXIT_LIST_FILE);
}).catch(error => {
LOGGER.error('Unable to save %s: %s',
TOR_EXIT_LIST_FILE,
error.message);
});
resolve(exitNodes);
});
}).on('error', error => {
reject(error);
})
}); });
} }
var _ipList = []; function loadTorListFromFile() {
getTorIPs(function (err, ips) { LOGGER.info('Loading Tor exit list from %s', TOR_EXIT_LIST_FILE);
if (err) { return fs.readFileAsync(TOR_EXIT_LIST_FILE).then(contents => {
LOGGER.error(err); return JSON.parse(String(contents));
return; });
} }
LOGGER.info("Loaded Tor IP list"); loadTorList().then(exits => {
_ipList = ips; TOR_EXIT_IPS.clear();
exits.forEach(exit => {
TOR_EXIT_IPS.add(exit);
});
}).catch(error => {
LOGGER.error('Unable to load Tor exit list: %s', error.stack);
}); });
exports.isTorExit = function (ip) { export function isTorExit(ip) {
return _ipList.indexOf(ip) >= 0; return TOR_EXIT_IPS.has(ip);
}; };