From a81105f62a25f1825c0bf83e495f551c2068ba86 Mon Sep 17 00:00:00 2001 From: Sefinek Date: Sun, 10 Nov 2024 01:22:01 +0100 Subject: [PATCH] Quality fixes --- .env.default | 8 ++++---- index.js | 27 +++++++++------------------ scripts/config.js | 2 +- scripts/sefinekAPI.js | 2 +- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/.env.default b/.env.default index 4ab271b..bc6f6ce 100644 --- a/.env.default +++ b/.env.default @@ -9,9 +9,6 @@ CLOUDFLARE_API_KEY=0000000000000000000000000000000000000000 # AbuseIPDB (https://www.abuseipdb.com/account/api) ABUSEIPDB_API_KEY=00000000000000000000000000000000000000000000000000000000000000000000000000000000 -# API key for api.sefinek.net. Contact me at contact@sefinek.net to obtain it and contribute to the sefinek/Malicious-IP-Addresses. Leave empty if you don't have a token. -SEFINEK_API_SECRET= - ############################### CYCLES ############################### # Main interval (in minutes) of each cycle. For production 2h; development 8s. CYCLE_INTERVAL=120 @@ -25,13 +22,16 @@ REPORTED_IP_COOLDOWN_MS=7 MAX_URL_LENGTH=920 # Additional delay (in miliseconds) after each successful IP report to avoid overloading the AbuseIPDB API. -SUCCESS_COOLDOWN=500 +SUCCESS_COOLDOWN=80 # Interval for refreshing your IP address (in minutes). # This ensures that WAF violations originating from your IP address are not reported to AbuseIPDB. IP_REFRESH_INTERVAL=80 ############################### SEFINEK API ############################### +# Secret key for api.sefinek.net +SEFINEK_API_SECRET= + # Report IP addresses to api.sefinek.net to support the development of the repository at https://github.com/sefinek/Malicious-IP-Addresses. SEFINEK_API_SECRET is required if true. REPORT_TO_SEFINEK_API=false diff --git a/index.js b/index.js index 7fa8cfe..d7418f3 100644 --- a/index.js +++ b/index.js @@ -21,30 +21,22 @@ const fetchBlockedIPs = async () => { log('log', `Fetched ${events.length} events from Cloudflare`); return events; } else { - log('error', `Failed to retrieve data from Cloudflare (status ${status}); ${JSON.stringify(data?.errors)}`); - return null; + throw new Error(`Failed to retrieve data from Cloudflare (status ${status}); ${JSON.stringify(data?.errors)}`); } } catch (err) { - log('error', err.response?.data ? `${err.response.status} HTTP ERROR (Cloudflare API)\n${JSON.stringify(err.response.data, null, 2)}` : `Unknown error with Cloudflare API: ${err.message}`); + log('error', err.response?.data ? `${err.response.status} HTTP ERROR Cloudflare API: ${JSON.stringify(err.response.data, null, 2)}` : `Unknown error with Cloudflare API: ${err.message}`); return null; } }; const isIPReportedRecently = (rayId, ip, reportedIPs) => { - const lastReport = reportedIPs.reduce((latest, entry) => { - if ( - (entry.rayId === rayId || entry.ip === ip) && - (entry.status === 'TOO_MANY_REQUESTS' || entry.status === 'REPORTED') && - (!latest || entry.timestamp > latest.timestamp) - ) return entry; - return latest; - }, null); + const lastReport = reportedIPs.find(entry => + (entry.rayId === rayId || entry.ip === ip) && + (entry.status === 'TOO_MANY_REQUESTS' || entry.status === 'REPORTED') + ); - if (lastReport) { - const timeDifference = Date.now() - lastReport.timestamp; - if (timeDifference < REPORTED_IP_COOLDOWN_MS) { - return { recentlyReported: true, timeDifference, reason: lastReport.status === 'TOO_MANY_REQUESTS' ? 'RATE-LIMITED' : 'REPORTED' }; - } + if (lastReport && (Date.now() - lastReport.timestamp) < REPORTED_IP_COOLDOWN_MS) { + return { recentlyReported: true, timeDifference: Date.now() - lastReport.timestamp, reason: lastReport.status === 'TOO_MANY_REQUESTS' ? 'RATE-LIMITED' : 'REPORTED' }; } return { recentlyReported: false }; @@ -127,7 +119,7 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount if (!userIp) log('warn', `Your IP address is missing! Received: ${userIp}`); let cycleImageSkippedCount = 0, cycleProcessedCount = 0, cycleReportedCount = 0, cycleSkippedCount = 0; - const cycleErrorCounts = { blocked: 0, noResponse: 0, otherErrors: 0 }; + const cycleErrorCounts = { blocked: 0, otherErrors: 0 }; let imageRequestLogged = false; for (const event of blockedIPEvents) { @@ -176,7 +168,6 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount log('log', `- Skipped IPs: ${cycleSkippedCount}`); log('log', `- Skipped due to Image Requests: ${cycleImageSkippedCount}`); log('log', `- 429 Too Many Requests: ${cycleErrorCounts.blocked}`); - log('log', `- No response errors: ${cycleErrorCounts.noResponse}`); log('log', `- Other errors: ${cycleErrorCounts.otherErrors}`); log('log', '===================== End of Reporting Cycle ====================='); diff --git a/scripts/config.js b/scripts/config.js index 96dbd51..ef9bc46 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -5,7 +5,7 @@ const REPORTED_IP_COOLDOWN_MS = parseInt(process.env.REPORTED_IP_COOLDOWN_MS || const MAX_URL_LENGTH = parseInt(process.env.MAX_URL_LENGTH || '920'); -const SUCCESS_COOLDOWN = parseInt(process.env.SUCCESS_COOLDOWN || '1000'); +const SUCCESS_COOLDOWN = parseInt(process.env.SUCCESS_COOLDOWN || '200'); const IP_REFRESH_INTERVAL = parseInt(process.env.IP_REFRESH_INTERVAL || '80') * 60 * 1000; diff --git a/scripts/sefinekAPI.js b/scripts/sefinekAPI.js index 96c4c56..3d463a2 100644 --- a/scripts/sefinekAPI.js +++ b/scripts/sefinekAPI.js @@ -13,7 +13,7 @@ module.exports = async () => { !['//video', '//js', '//images', '//imgs', 'favicon.ico'].some(endpoint => x.endpoint.includes(endpoint)) && // Endpoints ['api.', 'cdn.'].some(prefix => x.hostname.startsWith(prefix)) && // Domains x.hostname !== 'blocklist.sefinek.net' && // Domain - !['Chrome/129', 'Chrome/130', 'Chrome/131', 'Chrome/132'].some(agent => x.useragent.includes(agent)) && // User-agents + !['Chrome/129', 'Chrome/130', 'Chrome/131', 'Chrome/132', 'Chrome/133', 'StellaLauncher'].some(agent => x.useragent.includes(agent)) && // User-agents !(/crawler|spider|bot/gi).test(x.useragent) && // Bots !x.sefinekAPI );