206 lines
6.8 KiB
JavaScript
206 lines
6.8 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Configuration dependencies.
|
|
*/
|
|
|
|
var config = require('../config/production/config');
|
|
Object.keys(config).length === 0 &&
|
|
(config = require('../config/production/config.backup'));
|
|
var config_md5 = require('md5')(JSON.stringify(config));
|
|
|
|
setInterval(function() {
|
|
if (
|
|
config_md5 &&
|
|
process.env['CP_CONFIG_MD5'] &&
|
|
config_md5 !== process.env['CP_CONFIG_MD5']
|
|
) {
|
|
config = require('../config/production/config');
|
|
Object.keys(config).length === 0 &&
|
|
(config = require('../config/production/config.backup'));
|
|
config_md5 = process.env['CP_CONFIG_MD5'];
|
|
}
|
|
}, 3333);
|
|
|
|
/**
|
|
* Node dependencies.
|
|
*/
|
|
|
|
var crypto = require('crypto').createHash;
|
|
var url = require('url');
|
|
var LRU = require('lru-cache');
|
|
var defense_domain = new LRU({ maxAge: 3600000, max: 10000 });
|
|
var defense_agent = new LRU({ maxAge: 3600000, max: 10000 });
|
|
|
|
module.exports = function() {
|
|
return function(req, res, next) {
|
|
var host = req.get('host');
|
|
var host_domain = url.parse('http://' + host).hostname;
|
|
var ua = req.get('user-agent') ? req.get('user-agent').toLowerCase() : '';
|
|
|
|
if (
|
|
(!config.defense.domain && !config.defense.agent) ||
|
|
req.userinfo.bot.main
|
|
) {
|
|
return next();
|
|
}
|
|
|
|
var hash = crypto('sha1')
|
|
.update(
|
|
config.defense.domain_key === 1
|
|
? req.userinfo.ip
|
|
: req.userinfo.ip + '' + ua
|
|
)
|
|
.digest('base64');
|
|
|
|
var get_defense_domain = defense_domain.get(hash);
|
|
var get_defense_agent = defense_agent.get(req.userinfo.ip);
|
|
var captcha_1 = Math.floor(Math.random() * 9) + 1;
|
|
var captcha_2 = Math.floor(Math.random() * 9) + 1;
|
|
|
|
if (req.query && req.query.captcha) {
|
|
var c1 = req.query.captcha.toString().trim();
|
|
if (get_defense_domain && get_defense_domain.captcha) {
|
|
var c2 = get_defense_domain.captcha.toString();
|
|
if (c1 === c2) {
|
|
defense_domain.del(hash);
|
|
get_defense_domain = undefined;
|
|
console.log(
|
|
'BAD BOT DETECTED [CAPTCHA TRUE]',
|
|
req.userinfo.ip,
|
|
c1 + ' = ' + c2
|
|
);
|
|
} else {
|
|
console.log(
|
|
'BAD BOT DETECTED [CAPTCHA FALSE]',
|
|
req.userinfo.ip,
|
|
c1 + ' != ' + c2
|
|
);
|
|
}
|
|
}
|
|
if (get_defense_agent && get_defense_agent.captcha) {
|
|
var c3 = get_defense_agent.captcha.toString();
|
|
if (c1 === c3) {
|
|
defense_agent.del(hash);
|
|
get_defense_agent = undefined;
|
|
console.log(
|
|
'BAD BOT DETECTED [CAPTCHA TRUE]',
|
|
req.userinfo.ip,
|
|
c1 + ' = ' + c3
|
|
);
|
|
} else {
|
|
console.log(
|
|
'BAD BOT DETECTED [CAPTCHA FALSE]',
|
|
req.userinfo.ip,
|
|
c1 + ' != ' + c3
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (
|
|
config.defense.domain_ex &&
|
|
config.defense.domain_ex.length &&
|
|
config.defense.domain_ex
|
|
.map(function(d) {
|
|
switch (d) {
|
|
case 'domain.for.people':
|
|
return config.subdomain + config.domain;
|
|
case 'domain.for.bots':
|
|
return config.botdomain + config.bomain;
|
|
case 'domain2.for.bots':
|
|
return config.alt.botdomain + config.alt.bomain;
|
|
case 'domain.for.ru.people':
|
|
return config.ru.subdomain + config.ru.domain;
|
|
case 'domain.for.ru.bots':
|
|
return config.ru.botdomain + config.ru.bomain;
|
|
case 'domain.for.app':
|
|
return 'app.' + config.domain;
|
|
case 'domain.for.mobile':
|
|
return 'm.' + config.domain;
|
|
case 'domain.for.tv':
|
|
return 'tv.' + config.domain;
|
|
case 'domain.for.ftp':
|
|
return 'ftp.' + config.domain;
|
|
case 'domain.for.www':
|
|
return 'www.' + config.domain;
|
|
default:
|
|
return d;
|
|
}
|
|
})
|
|
.filter(Boolean)
|
|
.indexOf(host_domain) + 1
|
|
) {
|
|
host_domain = '';
|
|
}
|
|
|
|
if (get_defense_domain && config.defense.domain) {
|
|
if (
|
|
host_domain &&
|
|
get_defense_domain.domains.indexOf(host_domain) === -1
|
|
) {
|
|
get_defense_domain.domains.push(host_domain);
|
|
defense_domain.set(hash, get_defense_domain);
|
|
if (get_defense_domain.domains.length > config.defense.domain) {
|
|
console.log(
|
|
'BAD BOT DETECTED [DOMAIN]',
|
|
req.userinfo.ip,
|
|
'[' + get_defense_domain.domains.join('] » [') + ']'
|
|
);
|
|
}
|
|
}
|
|
if (get_defense_domain.domains.length > config.defense.domain) {
|
|
get_defense_domain.captcha = captcha_1 + captcha_2;
|
|
defense_domain.set(hash, get_defense_domain);
|
|
return next({
|
|
status: 404,
|
|
message:
|
|
config.defense.message +
|
|
'<br><br><form method="get" autocomplete="off"><div class="input-group input-group-lg"><span class="input-group-addon">' +
|
|
captcha_1 +
|
|
' + ' +
|
|
captcha_2 +
|
|
' =</span><input class="form-control" placeholder="__" type="text" name="captcha"><span class="input-group-btn"><button class="btn btn-default" type="submit">OK</button></span></div></form>'
|
|
});
|
|
}
|
|
} else if (host_domain) {
|
|
defense_domain.set(hash, {
|
|
domains: [host_domain]
|
|
});
|
|
}
|
|
|
|
if (get_defense_agent && config.defense.agent) {
|
|
if (get_defense_agent.agents.indexOf(ua) === -1) {
|
|
get_defense_agent.agents.push(ua);
|
|
defense_agent.set(req.userinfo.ip, get_defense_agent);
|
|
if (get_defense_agent.agents.length > config.defense.agent) {
|
|
console.log(
|
|
'BAD BOT DETECTED [AGENT]',
|
|
req.userinfo.ip,
|
|
'[' + get_defense_agent.agents.join('] » [') + ']'
|
|
);
|
|
}
|
|
}
|
|
if (get_defense_agent.agents.length > config.defense.agent) {
|
|
get_defense_agent.captcha = captcha_1 + captcha_2;
|
|
defense_agent.set(req.userinfo.ip, get_defense_agent);
|
|
return next({
|
|
status: 404,
|
|
message:
|
|
config.defense.message +
|
|
'<br><br><form method="get" autocomplete="off"><div class="input-group input-group-lg"><span class="input-group-addon">' +
|
|
captcha_1 +
|
|
' + ' +
|
|
captcha_2 +
|
|
' =</span><input class="form-control" placeholder="__" type="text" name="captcha"><span class="input-group-btn"><button class="btn btn-default" type="submit">OK</button></span></div></form>'
|
|
});
|
|
}
|
|
} else {
|
|
defense_agent.set(req.userinfo.ip, {
|
|
agents: [ua]
|
|
});
|
|
}
|
|
|
|
return next();
|
|
};
|
|
};
|