From 504fbd4496d60552b8c98a8f0b6193b06fc650eb Mon Sep 17 00:00:00 2001 From: fatchan Date: Tue, 4 Feb 2020 11:18:48 +1100 Subject: [PATCH] dnsbl --- configs/main.js.example | 8 ++++++++ controllers/forms.js | 3 ++- helpers/checks/dnsbl.js | 29 +++++++++++++++++++++++++++++ helpers/dnsbl.js | 29 +++++++++++++++++++++++++++++ package-lock.json | 21 +++++++++++++++++++-- package.json | 1 + 6 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 helpers/checks/dnsbl.js create mode 100644 helpers/dnsbl.js diff --git a/configs/main.js.example b/configs/main.js.example index e3c81aea..fd682f2b 100644 --- a/configs/main.js.example +++ b/configs/main.js.example @@ -42,6 +42,14 @@ module.exports = { paintAmount: 2 }, + /* dnsbl, will add a small delay for uncached requests. You could also install some + kind of dns cache e.g. unbound to improve performance. DNSBL only checked for posting */ + dnsbl: { + enabled: false, + blacklists: ['tor.dan.me.uk', 'zen.spamhaus.org'], + cacheTime: 3600 //in seconds, idk whats a good value + }, + //cache templates in memory. disable only if editing templates and doing dev work cacheTemplates: true, diff --git a/controllers/forms.js b/controllers/forms.js index 1a18ab5e..69c5f102 100644 --- a/controllers/forms.js +++ b/controllers/forms.js @@ -14,6 +14,7 @@ const express = require('express') , verifyCaptcha = require(__dirname+'/../helpers/captcha/captchaverify.js') , csrf = require(__dirname+'/../helpers/checks/csrfmiddleware.js') , sessionRefresh = require(__dirname+'/../helpers/sessionrefresh.js') + , dnsblCheck = require(__dirname+'/../helpers/checks/dnsbl.js') , dynamicResponse = require(__dirname+'/../helpers/dynamic.js') , uploadLimitFunction = (req, res, next) => { return dynamicResponse(req, res, 413, 'message', { @@ -73,7 +74,7 @@ const express = require('express') , newcaptcha = require(__dirname+'/../models/forms/newcaptcha.js') //make new post -router.post('/board/:board/post', sessionRefresh, Boards.exists, calcPerms, banCheck, postFiles, paramConverter, verifyCaptcha, numFiles, makePostController); +router.post('/board/:board/post', dnsblCheck, sessionRefresh, Boards.exists, calcPerms, banCheck, postFiles, paramConverter, verifyCaptcha, numFiles, makePostController); //post actions router.post('/board/:board/actions', sessionRefresh, Boards.exists, calcPerms, banCheck, paramConverter, verifyCaptcha, actionController); //public, with captcha diff --git a/helpers/checks/dnsbl.js b/helpers/checks/dnsbl.js new file mode 100644 index 00000000..9fa5c987 --- /dev/null +++ b/helpers/checks/dnsbl.js @@ -0,0 +1,29 @@ +'use strict'; + +const cache = require(__dirname+'/../../redis.js') + , dynamicResponse = require(__dirname+'/../dynamic.js') + , { dnsbl } = require(__dirname+'/../../configs/main.js') + , { batch } = require('dnsbl'); + +module.exports = async (req, res, next) => { + + if (dnsbl.enabled && dnsbl.blacklists.length > 0) { + const ip = req.headers['x-real-ip'] || req.connection.remoteAddress; + let isBlacklisted = await cache.get(`blacklisted:${ip}`); + if (isBlacklisted === null) { //not cached + const dnsblResp = await batch(ip, dnsbl.blacklists); + isBlacklisted = dnsblResp.some(r => r.listed === true); + await cache.set(`blacklisted:${ip}`, isBlacklisted, dnsbl.cacheTime); + } + if (isBlacklisted) { + return dynamicResponse(req, res, 403, 'message', { + 'title': 'Forbidden', + 'message': 'Your IP address is listed on a blacklist', + 'redirect': req.headers.referer || '/' + }); + } + } + return next(); + +} + diff --git a/helpers/dnsbl.js b/helpers/dnsbl.js new file mode 100644 index 00000000..b525a96a --- /dev/null +++ b/helpers/dnsbl.js @@ -0,0 +1,29 @@ +'use strict'; + +const cache = require(__dirname+'/../redis.js') + , dynamicResponse = require(__dirname+'/dynamic.js') + , { dnsbl } = require(__dirname+'/../configs/main.js') + , { batch } = require('dnsbl'); + +module.exports = async (req, res, next) => { + + if (dnsbl.enabled) { + const ip = req.headers['x-real-ip'] || req.connection.remoteAddress; + let isBlacklisted = await cache.get(`blacklisted:${ip}`); + if (isBlacklisted === null) { //not cached + const dnsblResp = await batch(ip, dnsbl.blacklists); + isBlacklisted = dnsblResp.some(r => r.listed === true); + await cache.set(`blacklisted:${ip}`, isBlacklisted, dnsbl.cacheTime); + } + if (isBlacklisted) { + return dynamicResponse(req, res, 403, 'message', { + 'title': 'Forbidden', + 'message': 'Your IP address is listed on a blacklist', + 'redirect': req.headers.referer || '/' + }); + } + } + return next(); + +} + diff --git a/package-lock.json b/package-lock.json index e8422878..1ac1cf2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -226,7 +226,7 @@ } }, "@tohru/gm": { - "version": "github:fatchan/gm#07df8fbf131b6b18c32fa010a84e67964e132955", + "version": "github:fatchan/gm#c2ffb2ce0db3f64fbf4082462601429985b6dca6", "from": "github:fatchan/gm", "requires": { "array-parallel": "^0.1.3", @@ -1906,6 +1906,15 @@ } } }, + "dnsbl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/dnsbl/-/dnsbl-3.2.0.tgz", + "integrity": "sha512-Fv0ExY6F0cZeVD9JWhApFedUny220lJdEFSvwG0vh/SjLr8QL/V4MgW7vHk1cnLjv8UX2kxOabJVIKKTstPPYA==", + "requires": { + "ip-ptr": "^3.0.0", + "p-map": "^3.0.0" + } + }, "doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -2406,7 +2415,7 @@ } }, "express-fileupload": { - "version": "github:fatchan/express-fileupload#f72901fd27b615664ca30fc4c4148b62c5c77fe9", + "version": "github:fatchan/express-fileupload#fd713ae7a3c7f381638d6479faa142d366304329", "from": "github:fatchan/express-fileupload", "requires": { "busboy": "^0.3.1" @@ -4139,6 +4148,14 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, + "ip-ptr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ip-ptr/-/ip-ptr-3.0.0.tgz", + "integrity": "sha512-ll3eQQ2aIQ2Wd+RZR0HIuQcAyccXeLdn7Q1tLltKKiIi/QDvHE1oj3tXg2Z5l4CxLWZ2OhI7x1juuqy33U8W6Q==", + "requires": { + "ipaddr.js": "^1.8.1" + } + }, "ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", diff --git a/package.json b/package.json index fb2a0cf4..1e5aa302 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "cookie-parser": "^1.4.4", "csurf": "^1.11.0", "del": "^5.1.0", + "dnsbl": "^3.2.0", "express": "^4.17.1", "express-fileupload": "github:fatchan/express-fileupload", "express-session": "^1.17.0",