2018-10-29 21:43:15 +01:00
|
|
|
const fs = require('fs');
|
|
|
|
|
|
|
|
const logger = require('winston');
|
2019-03-18 04:13:00 +01:00
|
|
|
const {
|
|
|
|
publishing: { publishingChannelWhitelist },
|
|
|
|
} = require('@config/siteConfig');
|
2018-11-12 21:12:31 +01:00
|
|
|
const ipBanFile = './site/config/ipBan.txt';
|
2019-07-03 23:21:58 +02:00
|
|
|
const ipWhitelist = './site/config/ipWhitelist.txt';
|
2019-03-18 04:13:00 +01:00
|
|
|
const forbiddenMessage =
|
|
|
|
'<h1>Forbidden</h1>If you are seeing this by mistake, please contact us using <a href="https://chat.lbry.com/">https://chat.lbry.com/</a>';
|
2019-06-21 20:40:07 +02:00
|
|
|
const maxPublishesInTenMinutes = 20;
|
2018-10-29 21:43:15 +01:00
|
|
|
let ipCounts = {};
|
|
|
|
let blockedAddresses = [];
|
2019-07-03 23:21:58 +02:00
|
|
|
let whitelistedAddresses = [];
|
2018-10-29 21:43:15 +01:00
|
|
|
|
2018-11-11 01:11:12 +01:00
|
|
|
if (fs.existsSync(ipBanFile)) {
|
2018-10-29 21:43:15 +01:00
|
|
|
const lineReader = require('readline').createInterface({
|
|
|
|
input: require('fs').createReadStream(ipBanFile),
|
|
|
|
});
|
|
|
|
|
2019-03-18 04:13:00 +01:00
|
|
|
lineReader.on('line', line => {
|
2018-11-11 01:11:12 +01:00
|
|
|
if (line && line !== '') {
|
2018-10-29 21:43:15 +01:00
|
|
|
blockedAddresses.push(line);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-03 23:21:58 +02:00
|
|
|
// If a file called ipWhitelist.txt exists
|
|
|
|
// Please comment above each whitelisted IP why/who/when etc
|
|
|
|
// # Jim because he's awesome - January 2018
|
|
|
|
if (fs.existsSync(ipWhitelist)) {
|
|
|
|
const lineReader = require('readline').createInterface({
|
|
|
|
input: require('fs').createReadStream(ipWhitelist),
|
|
|
|
});
|
|
|
|
|
|
|
|
lineReader.on('line', line => {
|
|
|
|
if (line && line !== '' && line[0] !== '#') {
|
|
|
|
whitelistedAddresses.push(line);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-10-29 21:43:15 +01:00
|
|
|
const autoblockPublishMiddleware = (req, res, next) => {
|
|
|
|
let ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress).split(/,\s?/)[0];
|
|
|
|
|
2019-07-03 23:21:58 +02:00
|
|
|
if (whitelistedAddresses.indexOf(ip) !== -1) {
|
|
|
|
next();
|
|
|
|
return;
|
|
|
|
}
|
2018-11-11 01:11:12 +01:00
|
|
|
if (blockedAddresses.indexOf(ip) !== -1) {
|
2018-10-29 21:43:15 +01:00
|
|
|
res.status(403).send(forbiddenMessage);
|
|
|
|
res.end();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-18 04:13:00 +01:00
|
|
|
let count = (ipCounts[ip] = (ipCounts[ip] || 0) + 1);
|
2018-10-29 21:43:15 +01:00
|
|
|
|
|
|
|
setTimeout(() => {
|
2018-11-11 01:11:12 +01:00
|
|
|
if (ipCounts[ip]) {
|
2018-10-29 21:43:15 +01:00
|
|
|
ipCounts[ip]--;
|
2018-11-11 01:11:12 +01:00
|
|
|
if (ipCounts[ip] === 0) {
|
2018-10-29 21:43:15 +01:00
|
|
|
delete ipCounts[ip];
|
|
|
|
}
|
|
|
|
}
|
2018-11-11 01:11:12 +01:00
|
|
|
}, 600000 /* 10 minute retainer */);
|
2018-10-29 21:43:15 +01:00
|
|
|
|
2019-06-21 20:40:07 +02:00
|
|
|
if (count === maxPublishesInTenMinutes) {
|
2018-10-29 21:43:15 +01:00
|
|
|
logger.error(`Banning IP: ${ip}`);
|
|
|
|
blockedAddresses.push(ip);
|
|
|
|
res.status(403).send(forbiddenMessage);
|
|
|
|
res.end();
|
|
|
|
|
|
|
|
fs.appendFile(ipBanFile, ip + '\n', () => {});
|
|
|
|
} else {
|
|
|
|
next();
|
|
|
|
}
|
2018-11-11 01:11:12 +01:00
|
|
|
};
|
2018-10-29 21:43:15 +01:00
|
|
|
|
|
|
|
const autoblockPublishBodyMiddleware = (req, res, next) => {
|
2018-11-11 01:11:12 +01:00
|
|
|
if (req.body && publishingChannelWhitelist) {
|
2018-10-29 21:43:15 +01:00
|
|
|
let ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress).split(/,\s?/)[0];
|
|
|
|
const { channelName } = req.body;
|
|
|
|
|
2018-11-12 21:21:07 +01:00
|
|
|
if (channelName && publishingChannelWhitelist.indexOf(channelName.toLowerCase()) !== -1) {
|
2018-10-29 21:43:15 +01:00
|
|
|
delete ipCounts[ip];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
next();
|
2018-11-11 01:11:12 +01:00
|
|
|
};
|
2018-10-29 21:43:15 +01:00
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
autoblockPublishMiddleware,
|
|
|
|
autoblockPublishBodyMiddleware,
|
|
|
|
};
|