0.5.0
This commit is contained in:
1 parent
3b4492ffc6
commit
580ba4d41a
3 files changed
+43
-114
No files matched your search
@@ -1,11 +1,12 @@
|
|||||||
// Copyright 2024-2026 © by Sefinek. All Rights Reserved.
|
// Copyright 2024-2026 © by Sefinek. All Rights Reserved.
|
||||||
// https://sefinek.net
|
// https://sefinek.net
|
||||||
|
|
||||||
const fs = require('node:fs');
|
|
||||||
const chokidar = require('chokidar');
|
|
||||||
const { parseUfwLog } = require('ufw-log-parser');
|
const { parseUfwLog } = require('ufw-log-parser');
|
||||||
|
const config = require('./config.js');
|
||||||
|
require('./scripts/validations/index.js')(config.MAIN);
|
||||||
const banner = require('./scripts/banners/ufw.js');
|
const banner = require('./scripts/banners/ufw.js');
|
||||||
const { axiosService } = require('./scripts/services/axios.js');
|
const { axiosService } = require('./scripts/services/axios.js');
|
||||||
|
const tailFile = require('./scripts/services/tailFile.js');
|
||||||
const { saveBufferToFile, loadBufferFromFile, sendBulkReport, BULK_REPORT_BUFFER } = require('./scripts/services/bulk.js');
|
const { saveBufferToFile, loadBufferFromFile, sendBulkReport, BULK_REPORT_BUFFER } = require('./scripts/services/bulk.js');
|
||||||
const { reportedIPs, loadReportedIPs, saveReportedIPs, isIPReportedRecently, markIPAsReported } = require('./scripts/services/cache.js');
|
const { reportedIPs, loadReportedIPs, saveReportedIPs, isIPReportedRecently, markIPAsReported } = require('./scripts/services/cache.js');
|
||||||
const ABUSE_STATE = require('./scripts/services/state.js');
|
const ABUSE_STATE = require('./scripts/services/state.js');
|
||||||
@@ -13,7 +14,6 @@ const { refreshServerIPs, getServerIPs } = require('./scripts/services/ipFetcher
|
|||||||
const { repoSlug, repoUrl } = require('./scripts/repo.js');
|
const { repoSlug, repoUrl } = require('./scripts/repo.js');
|
||||||
const isSpecialPurposeIP = require('./scripts/isSpecialPurposeIP.js');
|
const isSpecialPurposeIP = require('./scripts/isSpecialPurposeIP.js');
|
||||||
const logger = require('./scripts/logger.js');
|
const logger = require('./scripts/logger.js');
|
||||||
const config = require('./config.js');
|
|
||||||
const { UFW_LOG_FILE, SERVER_ID, EXTENDED_LOGS, AUTO_UPDATE_ENABLED, AUTO_UPDATE_SCHEDULE, DISCORD_WEBHOOK_ENABLED, DISCORD_WEBHOOK_URL } = config.MAIN;
|
const { UFW_LOG_FILE, SERVER_ID, EXTENDED_LOGS, AUTO_UPDATE_ENABLED, AUTO_UPDATE_SCHEDULE, DISCORD_WEBHOOK_ENABLED, DISCORD_WEBHOOK_URL } = config.MAIN;
|
||||||
|
|
||||||
const RATE_LIMIT_LOG_INTERVAL = 10 * 60 * 1000;
|
const RATE_LIMIT_LOG_INTERVAL = 10 * 60 * 1000;
|
||||||
@@ -25,7 +25,7 @@ const nextRateLimitReset = () => {
|
|||||||
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1, 0, 1));
|
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1, 0, 1));
|
||||||
};
|
};
|
||||||
|
|
||||||
let LAST_RATELIMIT_LOG = 0, LAST_STATS_LOG = 0, RATELIMIT_RESET = nextRateLimitReset(), fileOffset = 0;
|
let LAST_RATELIMIT_LOG = 0, LAST_STATS_LOG = 0, RATELIMIT_RESET = nextRateLimitReset();
|
||||||
|
|
||||||
const checkRateLimit = async () => {
|
const checkRateLimit = async () => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@@ -100,9 +100,15 @@ const reportIp = async ({ srcIp, dpt = 'N/A', proto = 'N/A', timestamp }, catego
|
|||||||
};
|
};
|
||||||
|
|
||||||
const processLogLine = async (line, test = false) => {
|
const processLogLine = async (line, test = false) => {
|
||||||
if (!line.includes('[UFW BLOCK]')) return logger.warn(`Ignoring invalid line: ${line}`);
|
if (!line || !line.includes('[UFW BLOCK]')) return;
|
||||||
|
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
data = parseUfwLog(line);
|
||||||
|
} catch (err) {
|
||||||
|
return logger.error(`Failed to parse UFW log line: ${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
const data = parseUfwLog(line);
|
|
||||||
const { srcIp, proto, dpt } = data;
|
const { srcIp, proto, dpt } = data;
|
||||||
if (!srcIp) return logger.error(`Missing SRC in the log line: ${line}`, { ping: true });
|
if (!srcIp) return logger.error(`Missing SRC in the log line: ${line}`, { ping: true });
|
||||||
|
|
||||||
@@ -178,57 +184,8 @@ const processLogLine = async (line, test = false) => {
|
|||||||
await sendBulkReport();
|
await sendBulkReport();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check UFW_LOG_FILE
|
// Tail file
|
||||||
if (!fs.existsSync(UFW_LOG_FILE)) {
|
await tailFile(UFW_LOG_FILE, processLogLine);
|
||||||
logger.error(`Log file ${UFW_LOG_FILE} does not exist`, { ping: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch
|
|
||||||
let incompleteLine = '';
|
|
||||||
let processing = Promise.resolve();
|
|
||||||
|
|
||||||
fileOffset = fs.statSync(UFW_LOG_FILE).size;
|
|
||||||
chokidar.watch(UFW_LOG_FILE, { persistent: true, ignoreInitial: true })
|
|
||||||
.on('change', filePath => {
|
|
||||||
const stats = fs.statSync(filePath);
|
|
||||||
if (stats.size < fileOffset) {
|
|
||||||
incompleteLine = '';
|
|
||||||
fileOffset = 0;
|
|
||||||
logger.info('The file has been truncated, and the offset has been reset');
|
|
||||||
}
|
|
||||||
|
|
||||||
const start = fileOffset;
|
|
||||||
fileOffset = stats.size;
|
|
||||||
|
|
||||||
processing = processing.then(async () => {
|
|
||||||
let data = '';
|
|
||||||
try {
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
fs.createReadStream(filePath, { start, encoding: 'utf8' })
|
|
||||||
.on('data', chunk => { data += chunk; })
|
|
||||||
.on('end', resolve)
|
|
||||||
.on('error', reject);
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(`Failed to read log chunk: ${err.message}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const text = incompleteLine + data;
|
|
||||||
const lines = text.split('\n');
|
|
||||||
incompleteLine = lines.pop();
|
|
||||||
|
|
||||||
for (const line of lines) {
|
|
||||||
if (!line.trim()) continue;
|
|
||||||
try {
|
|
||||||
await processLogLine(line);
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(`Failed to process log line: ${err.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Summaries
|
// Summaries
|
||||||
if (DISCORD_WEBHOOK_ENABLED && DISCORD_WEBHOOK_URL) await require('./scripts/services/summaries.js')();
|
if (DISCORD_WEBHOOK_ENABLED && DISCORD_WEBHOOK_URL) await require('./scripts/services/summaries.js')();
|
||||||
|
|||||||
Generated
+23
-54
@@ -9,9 +9,8 @@
|
|||||||
"version": "0.4.7",
|
"version": "0.4.7",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@logdna/tail-file": "^4.0.2",
|
||||||
"axios": "^1.13.6",
|
"axios": "^1.13.6",
|
||||||
"axios-retry": "^4.5.0",
|
|
||||||
"chokidar": "^5.0.0",
|
|
||||||
"cron": "^4.4.0",
|
"cron": "^4.4.0",
|
||||||
"csv-parse": "^6.1.0",
|
"csv-parse": "^6.1.0",
|
||||||
"csv-stringify": "^6.6.0",
|
"csv-stringify": "^6.6.0",
|
||||||
@@ -19,11 +18,15 @@
|
|||||||
"ipaddr.js": "^2.3.0",
|
"ipaddr.js": "^2.3.0",
|
||||||
"semver": "^7.7.4",
|
"semver": "^7.7.4",
|
||||||
"simple-git": "^3.32.3",
|
"simple-git": "^3.32.3",
|
||||||
|
"split2": "^4.2.0",
|
||||||
"ufw-log-parser": "^0.1.3"
|
"ufw-log-parser": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"globals": "^17.3.0"
|
"globals": "^17.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
@@ -62,6 +65,15 @@
|
|||||||
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
|
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@logdna/tail-file": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@logdna/tail-file/-/tail-file-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-aEZF3LanJoewsQ9J1CRk5wvOqvQvw4lhxitSMXz3sQPgfezamzwW+pGvKXxvht7EvJEYSlYPxfSjL6T2bDSEkg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/luxon": {
|
"node_modules/@types/luxon": {
|
||||||
"version": "3.7.1",
|
"version": "3.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz",
|
||||||
@@ -85,18 +97,6 @@
|
|||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios-retry": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"is-retry-allowed": "^2.2.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"axios": "0.x || 1.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/call-bind-apply-helpers": {
|
"node_modules/call-bind-apply-helpers": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
@@ -110,21 +110,6 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chokidar": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"readdirp": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 20.19.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@@ -406,18 +391,6 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-retry-allowed": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/luxon": {
|
"node_modules/luxon": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
|
||||||
@@ -469,19 +442,6 @@
|
|||||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/readdirp": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 20.19.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.4",
|
"version": "7.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||||
@@ -509,6 +469,15 @@
|
|||||||
"url": "https://github.com/steveukx/git-js?sponsor=1"
|
"url": "https://github.com/steveukx/git-js?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/split2": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ufw-log-parser": {
|
"node_modules/ufw-log-parser": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ufw-log-parser/-/ufw-log-parser-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ufw-log-parser/-/ufw-log-parser-0.1.3.tgz",
|
||||||
|
|||||||
+6
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ufw-abuseipdb-reporter",
|
"name": "ufw-abuseipdb-reporter",
|
||||||
"version": "0.4.7",
|
"version": "0.5.0",
|
||||||
"homepage": "https://github.com/sefinek/UFW-AbuseIPDB-Reporter#readme",
|
"homepage": "https://github.com/sefinek/UFW-AbuseIPDB-Reporter#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/sefinek/UFW-AbuseIPDB-Reporter/issues"
|
"url": "https://github.com/sefinek/UFW-AbuseIPDB-Reporter/issues"
|
||||||
@@ -20,9 +20,8 @@
|
|||||||
"update": "npm run pull && npm ci --omit=dev && pm2 restart ufw-abuseipdb"
|
"update": "npm run pull && npm ci --omit=dev && pm2 restart ufw-abuseipdb"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@logdna/tail-file": "^4.0.2",
|
||||||
"axios": "^1.13.6",
|
"axios": "^1.13.6",
|
||||||
"axios-retry": "^4.5.0",
|
|
||||||
"chokidar": "^5.0.0",
|
|
||||||
"cron": "^4.4.0",
|
"cron": "^4.4.0",
|
||||||
"csv-parse": "^6.1.0",
|
"csv-parse": "^6.1.0",
|
||||||
"csv-stringify": "^6.6.0",
|
"csv-stringify": "^6.6.0",
|
||||||
@@ -30,10 +29,14 @@
|
|||||||
"ipaddr.js": "^2.3.0",
|
"ipaddr.js": "^2.3.0",
|
||||||
"semver": "^7.7.4",
|
"semver": "^7.7.4",
|
||||||
"simple-git": "^3.32.3",
|
"simple-git": "^3.32.3",
|
||||||
|
"split2": "^4.2.0",
|
||||||
"ufw-log-parser": "^0.1.3"
|
"ufw-log-parser": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"globals": "^17.3.0"
|
"globals": "^17.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user