REPORT_SCHEDULE

This commit is contained in:
Sefinek 2025-03-10 20:31:56 +01:00
parent 5da993d6a6
commit 8f6dfc03d9
4 changed files with 91 additions and 60 deletions

View file

@ -7,8 +7,8 @@ exports.CONFIG = {
},
CYCLES: {
// Main interval (in minutes) of each cycle
CYCLE_INTERVAL: 120 * 60 * 1000,
// Schedule for running cron jobs for reporting to AbuseIPDB.
REPORT_SCHEDULE: '0 */2 * * *',
// The minimum time (in hours) that must pass after reporting an IP address before it can be reported again.
// The required time is >= 15 minutes, according to AbuseIPDB API limits.
@ -19,7 +19,7 @@ exports.CONFIG = {
MAX_URL_LENGTH: 780,
// Additional delay (in milliseconds) after each successful IP report to avoid overloading the AbuseIPDB API.
SUCCESS_COOLDOWN: 30,
SUCCESS_COOLDOWN: 20,
// Interval for refreshing your IP address (in minutes).
// This ensures that WAF violations originating from your IP address are not reported to AbuseIPDB.

115
index.js
View file

@ -1,3 +1,4 @@
const { CronJob } = require('cron');
const axios = require('./services/axios.js');
const { CONFIG, GENERATE_COMMENT } = require('./config.js');
const PAYLOAD = require('./services/payload.js');
@ -100,6 +101,61 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount
}
};
let cycleId = 1;
const cron = async () => {
const whitelist = await getFilters();
log(0, `===================== Reporting Cycle No. ${cycleId} =====================`);
const blockedIPEvents = await fetchBlockedIPs(whitelist);
if (!blockedIPEvents) return log(1, 'No events fetched, skipping cycle...');
const serverIP = fetchServerIP();
if (!serverIP) log(1, `Server IP address is missing! Received: ${serverIP}`);
let cycleProcessedCount = 0, cycleReportedCount = 0, cycleSkippedCount = 0;
const cycleErrorCounts = { blocked: 0, otherErrors: 0 };
for (const event of blockedIPEvents) {
cycleProcessedCount++;
const ip = event.clientIP;
if (ip === serverIP) {
log(0, `The IP address ${ip} belongs to this machine. Ignoring...`);
cycleSkippedCount++;
continue;
}
if (whitelist.endpoints.includes(event.clientRequestPath)) {
log(0, `Skipping ${event.clientRequestPath}...`);
continue;
}
const reportedIPs = readReportedIPs();
const { recentlyReported } = isIPReportedRecently(event.rayName, ip, reportedIPs);
if (recentlyReported) {
cycleSkippedCount++;
continue;
}
const wasReported = await reportIP(event, `${event.clientRequestHTTPHost}${event.clientRequestPath}`, event.clientCountryName, event.clientRequestHTTPHost, event.clientRequestPath, cycleErrorCounts);
if (wasReported) {
cycleReportedCount++;
await new Promise(resolve => setTimeout(resolve, CONFIG.CYCLES.SUCCESS_COOLDOWN));
}
}
log(0, `- Reported IPs: ${cycleReportedCount}`);
log(0, `- Total IPs processed: ${cycleProcessedCount}`);
log(0, `- Skipped IPs: ${cycleSkippedCount}`);
log(0, `- Rate-limits: ${cycleErrorCounts.blocked}`);
log(0, `- Other errors: ${cycleErrorCounts.otherErrors}`);
log(0, '===================== End of Reporting Cycle =====================');
cycleId++;
await new Promise(resolve => setTimeout(resolve));
};
(async () => {
log(0, 'Loading data, please wait...');
@ -113,61 +169,6 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount
process.send && process.send('ready');
// AbuseIPDB
let cycleId = 1;
while (true) {
const whitelist = await getFilters();
log(0, `===================== Reporting Cycle No. ${cycleId} =====================`);
const blockedIPEvents = await fetchBlockedIPs(whitelist);
if (!blockedIPEvents) {
log(1, 'No events fetched, skipping cycle...');
continue;
}
const serverIP = fetchServerIP();
if (!serverIP) log(1, `Server IP address is missing! Received: ${serverIP}`);
let cycleProcessedCount = 0, cycleReportedCount = 0, cycleSkippedCount = 0;
const cycleErrorCounts = { blocked: 0, otherErrors: 0 };
for (const event of blockedIPEvents) {
cycleProcessedCount++;
const ip = event.clientIP;
if (ip === serverIP) {
log(0, `The IP address ${ip} belongs to this machine. Ignoring...`);
cycleSkippedCount++;
continue;
}
if (whitelist.endpoints.includes(event.clientRequestPath)) {
log(0, `Skipping ${event.clientRequestPath}...`);
continue;
}
const reportedIPs = readReportedIPs();
const { recentlyReported } = isIPReportedRecently(event.rayName, ip, reportedIPs);
if (recentlyReported) {
cycleSkippedCount++;
continue;
}
const wasReported = await reportIP(event, `${event.clientRequestHTTPHost}${event.clientRequestPath}`, event.clientCountryName, event.clientRequestHTTPHost, event.clientRequestPath, cycleErrorCounts);
if (wasReported) {
cycleReportedCount++;
await new Promise(resolve => setTimeout(resolve, CONFIG.CYCLES.SUCCESS_COOLDOWN));
}
}
log(0, `- Reported IPs: ${cycleReportedCount}`);
log(0, `- Total IPs processed: ${cycleProcessedCount}`);
log(0, `- Skipped IPs: ${cycleSkippedCount}`);
log(0, `- Rate-limits: ${cycleErrorCounts.blocked}`);
log(0, `- Other errors: ${cycleErrorCounts.otherErrors}`);
log(0, '===================== End of Reporting Cycle =====================');
log(0, `Waiting ${formatDelay(CONFIG.CYCLES.CYCLE_INTERVAL)} (${CONFIG.CYCLES.CYCLE_INTERVAL} ms)...`);
cycleId++;
await new Promise(resolve => setTimeout(resolve, CONFIG.CYCLES.CYCLE_INTERVAL));
}
new CronJob(CONFIG.CYCLES.REPORT_SCHEDULE, cron, null, true, 'UTC');
await cron();
})();

29
package-lock.json generated
View file

@ -10,6 +10,7 @@
"license": "MIT",
"dependencies": {
"axios": "^1.8.2",
"cron": "^4.1.0",
"ipaddr.js": "^2.2.0"
},
"devDependencies": {
@ -27,6 +28,12 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@types/luxon": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz",
"integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==",
"license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@ -69,6 +76,19 @@
"node": ">= 0.8"
}
},
"node_modules/cron": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cron/-/cron-4.1.0.tgz",
"integrity": "sha512-wmcuXr2qP0UZStYgwruG6jC2AYSO9n5VMm2t93hmcEXEjWY3S2bsXe3sfGUrTs/uQ1AvRCrZ0Pp9Q032L/V9tw==",
"license": "MIT",
"dependencies": {
"@types/luxon": "~3.4.0",
"luxon": "~3.5.0"
},
"engines": {
"node": ">=18.x"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -291,6 +311,15 @@
"node": ">= 10"
}
},
"node_modules/luxon": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz",
"integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==",
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",

View file

@ -20,6 +20,7 @@
},
"dependencies": {
"axios": "^1.8.2",
"cron": "^4.1.0",
"ipaddr.js": "^2.2.0"
},
"devDependencies": {