From f95073d196d27f3616027e2926a6604366310605 Mon Sep 17 00:00:00 2001 From: Sefinek Date: Thu, 19 Dec 2024 15:19:30 +0100 Subject: [PATCH] Some fixes --- default.config.js | 35 ++++++++++++++++++++++++++++++++--- index.js | 39 +++++++++++++++++++-------------------- utils/cache.js | 6 +++--- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/default.config.js b/default.config.js index 1c88b22..e68f7e6 100644 --- a/default.config.js +++ b/default.config.js @@ -1,11 +1,11 @@ exports.MAIN = { - LOG_FILE: 'D:\\test\\ufw.log', - CACHE_FILE: 'D:\\test\\ufw-abuseipdb-reporter.cache', + LOG_FILE: '/var/log/ufw.log', + CACHE_FILE: '/tmp/ufw-abuseipdb-reporter.cache', ABUSEIPDB_API_KEY: '', GITHUB_REPO: 'https://github.com/sefinek/UFW-AbuseIPDB-Reporter', - REPORT_INTERVAL: 43200, + REPORT_INTERVAL: 12 * 60 * 60 * 1000, // 12h }; exports.REPORT_COMMENT = (timestamp, srcIp, dstIp, proto, spt, dpt, ttl, len, tos) => { @@ -17,4 +17,33 @@ TOS: ${tos || 'N/A'} This report (for ${srcIp}) was generated by: https://github.com/sefinek/UFW-AbuseIPDB-Reporter`; // Please do not remove the URL to the repository of this script. I would be really grateful. 💙 +}; + +// See: https://www.abuseipdb.com/categories +exports.DETERMINE_CATEGORIES = (proto, dpt) => { + const categories = { + TCP: { + 22: '14,22,18', // Port Scan | SSH | Brute-Force + 80: '14,21', // Port Scan | Web App Attack + 443: '14,21', // Port Scan | Web App Attack + 8080: '14,21', // Port Scan | Web App Attack + 25: '14,11', // Port Scan | Email Spam + 21: '14,5,18', // Port Scan | FTP Brute-Force | Brute-Force + 53: '14,1,2', // Port Scan | DNS Compromise | DNS Poisoning + 23: '14,15,18', // Port Scan | Hacking | Brute-Force + 3389: '14,15,18', // Port Scan | Hacking | Brute-Force + 3306: '14,16', // Port Scan | SQL Injection + 6666: '14,8', // Port Scan | Fraud VoIP + 6667: '14,8', // Port Scan | Fraud VoIP + 6668: '14,8', // Port Scan | Fraud VoIP + 6669: '14,8', // Port Scan | Fraud VoIP + 9999: '14,6', // Port Scan | Ping of Death + }, + UDP: { + 53: '14,1,2', // Port Scan | DNS Compromise | DNS Poisoning + 123: '14,17', // Port Scan | Spoofing + }, + }; + + return categories[proto]?.[dpt] || '14'; // Port Scan }; \ No newline at end of file diff --git a/index.js b/index.js index 53b165d..75bd1d9 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ const fs = require('node:fs'); const chokidar = require('chokidar'); const isLocalIP = require('./utils/isLocalIP.js'); -const { loadReportedIps, saveReportedIps, isIpReportedRecently, markIpAsReported } = require('./utils/cache.js'); +const { reportedIps, loadReportedIps, saveReportedIps, isIpReportedRecently, markIpAsReported } = require('./utils/cache.js'); const log = require('./utils/log.js'); const axios = require('./services/axios.js'); const config = require('./config.js'); @@ -15,7 +15,7 @@ const reportToAbuseIpDb = async (ip, categories, comment) => { headers: { 'Key': ABUSEIPDB_API_KEY }, }); - log(0, `Successfully reported IP ${ip} (score: ${data.data.abuseConfidenceScore})`); + log(0, `Successfully reported IP ${ip} (abuse: ${data.data.abuseConfidenceScore}%)`); return true; } catch (err) { log(2, `${err.message}\n${JSON.stringify(err.response.data)}`); @@ -23,22 +23,6 @@ const reportToAbuseIpDb = async (ip, categories, comment) => { } }; -const determineCategories = (proto, dpt) => { - const categories = { - TCP: { - 22: '14,22,18', 80: '14,21', 443: '14,21', 8080: '14,21', - 25: '14,11', 21: '14,5,18', 53: '14,1,2', 23: '14,15,18', - 3389: '14,15,18', 3306: '14,16', 6666: '14,8', - 6667: '14,8', 6668: '14,8', 6669: '14,8', 9999: '14,6', - }, - UDP: { - 53: '14,1,2', 123: '14,17', - }, - }; - - return categories[proto]?.[dpt] || '14'; -}; - const processLogLine = async line => { if (!line.includes('[UFW BLOCK]')) return log(1, `Ignoring line: ${line}`); @@ -66,11 +50,26 @@ const processLogLine = async line => { } if (isIpReportedRecently(srcIp)) { - log(0, `IP ${srcIp} reported recently`); + const lastReportedTime = reportedIps.get(srcIp); + const elapsedTime = Math.floor(Date.now() / 1000 - lastReportedTime); + + const days = Math.floor(elapsedTime / 86400); + const hours = Math.floor((elapsedTime % 86400) / 3600); + const minutes = Math.floor((elapsedTime % 3600) / 60); + const seconds = elapsedTime % 60; + + const timeAgo = [ + days && `${days}d`, + hours && `${hours}h`, + minutes && `${minutes}m`, + (seconds || !days && !hours && !minutes) && `${seconds}s`, + ].filter(Boolean).join(' '); + + log(0, `IP ${srcIp} was last reported on ${new Date(lastReportedTime * 1000).toLocaleString()} (${timeAgo} ago)`); return; } - const categories = determineCategories(proto, dpt); + const categories = config.DETERMINE_CATEGORIES(proto, dpt); const comment = config.REPORT_COMMENT(match.timestamp, srcIp, match.dstIp, proto, match.spt, dpt, match.ttl, match.len, match.tos); log(0, `Reporting IP ${srcIp} (${proto} ${dpt}) with categories ${categories}`); diff --git a/utils/cache.js b/utils/cache.js index 50b2b64..42a5ac7 100644 --- a/utils/cache.js +++ b/utils/cache.js @@ -21,10 +21,10 @@ const loadReportedIps = () => { const saveReportedIps = () => fs.writeFileSync(CACHE_FILE, Array.from(reportedIps).map(([ip, time]) => `${ip} ${time}`).join('\n'), 'utf8'); const isIpReportedRecently = ip => { - const now = Math.floor(Date.now() / 1000); - return reportedIps.has(ip) && (now - reportedIps.get(ip) < REPORT_INTERVAL); + const reportedTime = reportedIps.get(ip); + return reportedTime && (Date.now() / 1000 - reportedTime < REPORT_INTERVAL / 1000); }; const markIpAsReported = ip => reportedIps.set(ip, Math.floor(Date.now() / 1000)); -module.exports = { loadReportedIps, saveReportedIps, isIpReportedRecently, markIpAsReported }; \ No newline at end of file +module.exports = { reportedIps, loadReportedIps, saveReportedIps, isIpReportedRecently, markIpAsReported }; \ No newline at end of file