mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: #7743 meta/blacklist
This commit is contained in:
@@ -1,73 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
var ipaddr = require('ipaddr.js');
|
||||
var winston = require('winston');
|
||||
var async = require('async');
|
||||
var _ = require('lodash');
|
||||
const ipaddr = require('ipaddr.js');
|
||||
const winston = require('winston');
|
||||
const _ = require('lodash');
|
||||
|
||||
var db = require('../database');
|
||||
var pubsub = require('../pubsub');
|
||||
var plugins = require('../plugins');
|
||||
var analytics = require('../analytics');
|
||||
const db = require('../database');
|
||||
const pubsub = require('../pubsub');
|
||||
const plugins = require('../plugins');
|
||||
const analytics = require('../analytics');
|
||||
|
||||
var Blacklist = module.exports;
|
||||
Blacklist._rules = [];
|
||||
const Blacklist = module.exports;
|
||||
Blacklist._rules = {};
|
||||
|
||||
Blacklist.load = function (callback) {
|
||||
callback = callback || function () {};
|
||||
Blacklist.load = async function () {
|
||||
let rules = await Blacklist.get();
|
||||
rules = Blacklist.validate(rules);
|
||||
|
||||
async.waterfall([
|
||||
Blacklist.get,
|
||||
Blacklist.validate,
|
||||
function (rules, next) {
|
||||
winston.verbose('[meta/blacklist] Loading ' + rules.valid.length + ' blacklist rule(s)' + (rules.duplicateCount > 0 ? ', ignored ' + rules.duplicateCount + ' duplicate(s)' : ''));
|
||||
if (rules.invalid.length) {
|
||||
winston.warn('[meta/blacklist] ' + rules.invalid.length + ' invalid blacklist rule(s) were ignored.');
|
||||
}
|
||||
winston.verbose('[meta/blacklist] Loading ' + rules.valid.length + ' blacklist rule(s)' + (rules.duplicateCount > 0 ? ', ignored ' + rules.duplicateCount + ' duplicate(s)' : ''));
|
||||
if (rules.invalid.length) {
|
||||
winston.warn('[meta/blacklist] ' + rules.invalid.length + ' invalid blacklist rule(s) were ignored.');
|
||||
}
|
||||
|
||||
Blacklist._rules = {
|
||||
ipv4: rules.ipv4,
|
||||
ipv6: rules.ipv6,
|
||||
cidr: rules.cidr,
|
||||
cidr6: rules.cidr6,
|
||||
};
|
||||
next();
|
||||
},
|
||||
], callback);
|
||||
Blacklist._rules = {
|
||||
ipv4: rules.ipv4,
|
||||
ipv6: rules.ipv6,
|
||||
cidr: rules.cidr,
|
||||
cidr6: rules.cidr6,
|
||||
};
|
||||
};
|
||||
|
||||
pubsub.on('blacklist:reload', Blacklist.load);
|
||||
|
||||
Blacklist.save = function (rules, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.setObject('ip-blacklist-rules', { rules: rules }, next);
|
||||
},
|
||||
function (next) {
|
||||
Blacklist.load(next);
|
||||
pubsub.publish('blacklist:reload');
|
||||
},
|
||||
], callback);
|
||||
Blacklist.save = async function (rules) {
|
||||
await db.setObject('ip-blacklist-rules', { rules: rules });
|
||||
await Blacklist.load();
|
||||
pubsub.publish('blacklist:reload');
|
||||
};
|
||||
|
||||
Blacklist.get = function (callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.getObject('ip-blacklist-rules', next);
|
||||
},
|
||||
function (data, next) {
|
||||
next(null, data && data.rules);
|
||||
},
|
||||
], callback);
|
||||
Blacklist.get = async function () {
|
||||
const data = await db.getObject('ip-blacklist-rules');
|
||||
return data && data.rules;
|
||||
};
|
||||
|
||||
Blacklist.test = function (clientIp, callback) {
|
||||
Blacklist.test = async function (clientIp) {
|
||||
// Some handy test addresses
|
||||
// clientIp = '2001:db8:85a3:0:0:8a2e:370:7334'; // IPv6
|
||||
// clientIp = '127.0.15.1'; // IPv4
|
||||
// clientIp = '127.0.15.1:3443'; // IPv4 with port strip port to not fail
|
||||
if (!clientIp) {
|
||||
return setImmediate(callback);
|
||||
return;
|
||||
}
|
||||
clientIp = clientIp.split(':').length === 2 ? clientIp.split(':')[0] : clientIp;
|
||||
|
||||
@@ -76,7 +57,7 @@ Blacklist.test = function (clientIp, callback) {
|
||||
addr = ipaddr.parse(clientIp);
|
||||
} catch (err) {
|
||||
winston.error('[meta/blacklist] Error parsing client IP : ' + clientIp);
|
||||
return callback(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -90,26 +71,23 @@ Blacklist.test = function (clientIp, callback) {
|
||||
return addr.match(cidr);
|
||||
}) // not in a blacklisted IPv4 or IPv6 cidr range
|
||||
) {
|
||||
plugins.fireHook('filter:blacklist.test', { // To return test failure, pass back an error in callback
|
||||
ip: clientIp,
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
analytics.increment('blacklist');
|
||||
}
|
||||
|
||||
callback(err);
|
||||
});
|
||||
try {
|
||||
// To return test failure, pass back an error in callback
|
||||
await plugins.fireHook('filter:blacklist.test', { ip: clientIp });
|
||||
} catch (err) {
|
||||
analytics.increment('blacklist');
|
||||
throw err;
|
||||
}
|
||||
} else {
|
||||
var err = new Error('[[error:blacklisted-ip]]');
|
||||
err.code = 'blacklisted-ip';
|
||||
|
||||
analytics.increment('blacklist');
|
||||
|
||||
setImmediate(callback, err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
Blacklist.validate = function (rules, callback) {
|
||||
Blacklist.validate = function (rules) {
|
||||
rules = (rules || '').split('\n');
|
||||
var ipv4 = [];
|
||||
var ipv6 = [];
|
||||
@@ -170,7 +148,7 @@ Blacklist.validate = function (rules, callback) {
|
||||
return false;
|
||||
});
|
||||
|
||||
callback(null, {
|
||||
return {
|
||||
numRules: rules.length + invalid.length,
|
||||
ipv4: ipv4,
|
||||
ipv6: ipv6,
|
||||
@@ -178,25 +156,17 @@ Blacklist.validate = function (rules, callback) {
|
||||
valid: rules,
|
||||
invalid: invalid,
|
||||
duplicateCount: duplicateCount,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
Blacklist.addRule = function (rule, callback) {
|
||||
Blacklist.addRule = async function (rule) {
|
||||
var valid;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Blacklist.validate(rule, next);
|
||||
},
|
||||
function (result, next) {
|
||||
valid = result.valid;
|
||||
if (!valid.length) {
|
||||
return next(new Error('[[error:invalid-rule]]'));
|
||||
}
|
||||
Blacklist.get(next);
|
||||
},
|
||||
function (rules, next) {
|
||||
rules = rules + '\n' + valid[0];
|
||||
Blacklist.save(rules, next);
|
||||
},
|
||||
], callback);
|
||||
const result = Blacklist.validate(rule);
|
||||
valid = result.valid;
|
||||
if (!valid.length) {
|
||||
throw new Error('[[error:invalid-rule]]');
|
||||
}
|
||||
let rules = await Blacklist.get();
|
||||
rules = rules + '\n' + valid[0];
|
||||
await Blacklist.save(rules);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,8 @@ var events = require('../events');
|
||||
var SocketBlacklist = module.exports;
|
||||
|
||||
SocketBlacklist.validate = function (socket, data, callback) {
|
||||
meta.blacklist.validate(data.rules, callback);
|
||||
const rules = meta.blacklist.validate(data.rules);
|
||||
callback(null, rules);
|
||||
};
|
||||
|
||||
SocketBlacklist.save = function (socket, rules, callback) {
|
||||
|
||||
@@ -123,8 +123,12 @@ function initializeNodeBB(callback) {
|
||||
routes(app, middleware, next);
|
||||
},
|
||||
meta.sounds.addUploads,
|
||||
meta.blacklist.load,
|
||||
flags.init,
|
||||
function (next) {
|
||||
meta.blacklist.load(next);
|
||||
},
|
||||
function (next) {
|
||||
flags.init(next);
|
||||
},
|
||||
], function (err) {
|
||||
callback(err);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user