migrate blocklist to a txt file

this allows easy copy/pasting of existing deny lists which contain
comments and blank lines
This commit is contained in:
Girish Ramakrishnan
2020-09-14 10:29:48 -07:00
parent 467fa59023
commit 20e206fa43
10 changed files with 78 additions and 29 deletions

View File

@@ -7,6 +7,7 @@ exports = module.exports = {
const assert = require('assert'),
BoxError = require('./boxerror.js'),
ipaddr = require('ipaddr.js'),
path = require('path'),
paths = require('./paths.js'),
safe = require('safetydance'),
@@ -19,27 +20,33 @@ const SET_BLOCKLIST_CMD = path.join(__dirname, 'scripts/setblocklist.sh');
function getBlocklist(callback) {
assert.strictEqual(typeof callback, 'function');
const data = safe.fs.readFileSync(paths.FIREWALL_CONFIG_FILE, 'utf8');
const config = safe.JSON.parse(data);
const blocklist = config && config.blocklist ? config.blocklist : [];
callback(null, blocklist);
const data = safe.fs.readFileSync(paths.FIREWALL_BLOCKLIST_FILE, 'utf8');
callback(null, data);
}
function setBlocklist(blocklist, callback) {
assert(Array.isArray(blocklist));
function setBlocklist(blocklist, auditSource, callback) {
assert.strictEqual(typeof blocklist, 'string');
assert.strictEqual(typeof auditSource, 'object');
assert.strictEqual(typeof callback, 'function');
if (!blocklist.every(x => validator.isIP(x) || validator.isIPRange(x))) return callback(new BoxError(BoxError.BAD_FIELD, 'blocklist must contain IP or IP range'));
const parsedIp = ipaddr.process(auditSource.ip);
for (const line of blocklist.split('\n')) {
if (!line || line.startsWith('#')) continue;
const rangeOrIP = line.trim();
if (!validator.isIP(rangeOrIP) && !validator.isIPRange(rangeOrIP)) return callback(new BoxError(BoxError.BAD_FIELD, `${rangeOrIP} is not a valid IP or range`));
if (rangeOrIP.indexOf('/') === -1) {
if (auditSource.ip === rangeOrIP) return callback(new BoxError(BoxError.BAD_FIELD, `${rangeOrIP} includes client IP. Cannot block yourself`));
} else {
const parsedRange = ipaddr.parseCIDR(rangeOrIP);
if (parsedIp.match(parsedRange)) return callback(new BoxError(BoxError.BAD_FIELD, `${rangeOrIP} includes client IP. Cannot block yourself`));
}
}
if (settings.isDemo()) return callback(new BoxError(BoxError.CONFLICT, 'Not allowed in demo mode'));
const data = safe.fs.readFileSync(paths.FIREWALL_CONFIG_FILE, 'utf8');
const config = safe.JSON.parse(data) || {};
config.blocklist = blocklist;
if (!safe.fs.writeFileSync(paths.FIREWALL_CONFIG_FILE, JSON.stringify(config, null, 4), 'utf8')) return callback(new BoxError(BoxError.FS_ERROR, safe.error.message));
if (!safe.fs.writeFileSync(paths.FIREWALL_BLOCKLIST_FILE, blocklist, 'utf8')) return callback(new BoxError(BoxError.FS_ERROR, safe.error.message));
shell.sudo('setBlocklist', [ SET_BLOCKLIST_CMD ], {}, function (error) {
if (error) return callback(new BoxError(BoxError.IPTABLES_ERROR, `Error setting blocklist: ${error.message}`));