From c09400eb8285b9f0c81cb14ea6061baf3c151472 Mon Sep 17 00:00:00 2001 From: Sefinek Date: Sun, 2 Feb 2025 03:05:21 +0100 Subject: [PATCH] Update --- config.default.js | 4 ++-- index.js | 41 ++++++++++++----------------------------- services/SefinekAPI.js | 32 ++++++++++---------------------- services/csv.js | 4 +--- utils/isImageRequest.js | 2 -- utils/whitelist.js | 7 +++---- 6 files changed, 28 insertions(+), 62 deletions(-) delete mode 100644 utils/isImageRequest.js diff --git a/config.default.js b/config.default.js index 8412e62..3fc62c7 100644 --- a/config.default.js +++ b/config.default.js @@ -28,10 +28,10 @@ exports.CONFIG = { SEFINEK_API: { // Report IP addresses to api.sefinek.net to support the development of the repository at https://github.com/sefinek/Malicious-IP-Addresses. SECRET_TOKEN is required if true. - REPORT_TO_SEFIN_API: true, + REPORT_TO_SEFIN_API: false, // Secret key for api.sefinek.net - SECRET_TOKEN: 'HKKAUZHTDAH7W87SyL6XsWkV8UeUFVA9VvvXhn6H9Wn6kfDW6ZsXCtbahmkaYcLbxZGyrAKPmSkXb3AJ6pCU3VuDyTjUSehMyDZ', + SECRET_TOKEN: '', // How often should the log (reported_ips.csv) be analyzed and sent to the Sefinek API? In hours. INTERVAL: 60 * 60 * 1000, // Frequency for analyzing and submitting logs to the Sefinek API diff --git a/index.js b/index.js index 5d2fc28..1ba99b3 100644 --- a/index.js +++ b/index.js @@ -2,13 +2,13 @@ const axios = require('./services/axios.js'); const { CONFIG, GENERATE_COMMENT } = require('./config.js'); const PAYLOAD = require('./services/payload.js'); const SefinekAPI = require('./services/SefinekAPI.js'); -const isImageRequest = require('./utils/isImageRequest.js'); const headers = require('./utils/headers.js'); -const { logToCSV, readReportedIPs, wasImageRequestLogged } = require('./services/csv.js'); +const { logToCSV, readReportedIPs } = require('./services/csv.js'); const formatDelay = require('./utils/formatDelay.js'); const fetchServerIP = require('./services/fetchServerIP.js'); const whitelist = require('./utils/whitelist.js'); const log = require('./utils/log.js'); +const imgExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.svg', '.webp']; const fetchBlockedIPs = async () => { try { @@ -17,15 +17,9 @@ const fetchBlockedIPs = async () => { if (events) { const filtered = events.filter(x => x.ip !== fetchServerIP() && - ( - x.source === 'securitylevel' || - x.source === 'badscore' || - ( - !whitelist.domains.some(subdomain => x.clientRequestHTTPHost?.includes(subdomain)) && - !whitelist.userAgents.some(ua => x.userAgent?.includes(ua)) && - !whitelist.endpoints.some(endpoint => x.clientRequestPath?.includes(endpoint)) - ) - ) + !imgExtensions.some(ext => x.clientRequestPath.endsWith(ext)) && + !whitelist.domains.some(subdomain => x.clientRequestHTTPHost?.includes(subdomain)) && + !whitelist.endpoints.some(endpoint => x.clientRequestPath?.includes(endpoint)) ); log(0, `Fetched ${events.length} (filtered ${filtered.length}) events from Cloudflare`); @@ -92,7 +86,7 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount log(0, `429 for ${event.clientIP} (${event.rayName}); Endpoint: ${endpoint}`); cycleErrorCounts.blocked++; } else { - log(2, `Error ${err.response?.status} while reporting ${event.clientIP}; URI: ${uri}; (${err.response?.data || err.message})`); + log(2, `Error ${err.response?.status} while reporting ${event.clientIP}; URI: ${uri}; ${err.response?.data?.errors[0]?.detail || JSON.stringify(err.response?.data) || err.message}`); cycleErrorCounts.otherErrors++; } @@ -104,6 +98,8 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount log(0, 'Loading data, please wait...'); // Sefinek API + await SefinekAPI(); + return; if (CONFIG.SEFINEK_API.REPORT_TO_SEFIN_API && CONFIG.SEFINEK_API.INTERVAL && CONFIG.SEFINEK_API.SECRET_TOKEN) { setInterval(SefinekAPI, CONFIG.SEFINEK_API.INTERVAL); } @@ -128,17 +124,16 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount continue; } - const userIp = fetchServerIP(); - if (!userIp) log(1, `Your IP address is missing! Received: ${userIp}`); + const serverIP = fetchServerIP(); + if (!serverIP) log(1, `Server IP address is missing! Received: ${serverIP}`); - let cycleImageSkippedCount = 0, cycleProcessedCount = 0, cycleReportedCount = 0, cycleSkippedCount = 0; + let cycleProcessedCount = 0, cycleReportedCount = 0, cycleSkippedCount = 0; const cycleErrorCounts = { blocked: 0, otherErrors: 0 }; - let imageRequestLogged = false; for (const event of blockedIPEvents) { cycleProcessedCount++; const ip = event.clientIP; - if (ip === userIp) { + if (ip === serverIP) { log(0, `The IP address ${ip} belongs to this machine. Ignoring...`); cycleSkippedCount++; continue; @@ -160,17 +155,6 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount continue; } - if (isImageRequest(event.clientRequestPath)) { - cycleImageSkippedCount++; - if (!wasImageRequestLogged(ip, reportedIPs)) { - if (imageRequestLogged) continue; - log(0, 'Skipping image requests in this cycle...'); - imageRequestLogged = true; - } - - continue; - } - const wasReported = await reportIP(event, `${event.clientRequestHTTPHost}${event.clientRequestPath}`, event.clientCountryName, event.clientRequestHTTPHost, event.clientRequestPath, cycleErrorCounts); if (wasReported) { cycleReportedCount++; @@ -181,7 +165,6 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount log(0, `- Reported IPs: ${cycleReportedCount}`); log(0, `- Total IPs processed: ${cycleProcessedCount}`); log(0, `- Skipped IPs: ${cycleSkippedCount}`); - log(0, `- Ignored image requests: ${cycleImageSkippedCount}`); log(0, `- Rate-limits: ${cycleErrorCounts.blocked}`); log(0, `- Other errors: ${cycleErrorCounts.otherErrors}`); log(0, '===================== End of Reporting Cycle ====================='); diff --git a/services/SefinekAPI.js b/services/SefinekAPI.js index 5b474a9..f3d0077 100644 --- a/services/SefinekAPI.js +++ b/services/SefinekAPI.js @@ -2,26 +2,10 @@ const axios = require('./axios.js'); const { readReportedIPs, updateSefinekAPIInCSV } = require('./csv.js'); const log = require('../utils/log.js'); const fetchServerIP = require('./fetchServerIP.js'); -const whitelist = require('../utils/whitelist.js'); -const { MAIN } = require('../config.js').CONFIG; +const { SEFINEK_API } = require('../config.js').CONFIG; module.exports = async () => { - const reportedIPs = (readReportedIPs() || []).filter(x => - x.status === 'REPORTED' && - x.ip !== fetchServerIP() && - !x.sefinekAPI && - ( - x.source === 'securitylevel' || - x.source === 'badscore' || - ( - !(/crawler|spider|bot/gi).test(x.userAgent) && - !whitelist.domains.some(subdomain => x.clientRequestHTTPHost?.includes(subdomain)) && - !whitelist.userAgents.some(ua => x.userAgent?.includes(ua)) && - !whitelist.endpoints.some(endpoint => x.clientRequestPath?.includes(endpoint)) - ) - ) - ); - + const reportedIPs = (readReportedIPs() || []).filter(x => x.status === 'REPORTED' && x.ip !== fetchServerIP() && !x.sefinekAPI); if (!reportedIPs.length) return; const seenIPs = new Set(); @@ -34,7 +18,8 @@ module.exports = async () => { if (!uniqueLogs.length) return log(0, 'No unique IPs to send to Sefinek API'); try { - const res = await axios.post('https://api.sefinek.net/api/v2/cloudflare-waf-abuseipdb/post', { + // http://127.0.0.1:4010/api/v2/cloudflare-waf-abuseipdb + const res = await axios.post('https://api.sefinek.net/api/v2/cloudflare-waf-abuseipdb', { reportedIPs: uniqueLogs.map(ip => ({ rayId: ip.rayId, ip: ip.ip, @@ -44,12 +29,15 @@ module.exports = async () => { country: ip.country, timestamp: ip.timestamp, })), - }, { headers: { 'Authorization': MAIN.SECRET_TOKEN } }); + }, { headers: { 'Authorization': SEFINEK_API.SECRET_TOKEN } }); - log(0, `Successfully sent ${uniqueLogs.length} logs to Sefinek API. Status: ${res.status}`); + log(0, `Successfully sent ${uniqueLogs.length} logs to Sefinek API! Status: ${res.status}`); uniqueLogs.forEach(ip => updateSefinekAPIInCSV(ip.rayId, true)); } catch (err) { - log(2, `Failed to send logs to Sefinek API. Status: ${err.response?.status}. Message: ${err.response?.data?.message || err.stack}`); + const msg = err.response?.data?.message ?? err.message; + if (!msg?.includes('No valid or unique')) { + log(2, `Failed to send logs to Sefinek API! Status: ${err.response?.status ?? 'Unknown'}; Message: ${msg}`); + } } }; \ No newline at end of file diff --git a/services/csv.js b/services/csv.js index 956e52b..396f549 100644 --- a/services/csv.js +++ b/services/csv.js @@ -76,6 +76,4 @@ const updateSefinekAPIInCSV = (rayId, reportedToSefinekAPI) => { fs.writeFileSync(CSV_FILE_PATH, updatedLines.join('\n')); }; -const wasImageRequestLogged = (ip, reportedIPs) => reportedIPs.some(entry => entry.ip === ip && entry.action === 'SKIPPED_IMAGE_REQUEST'); - -module.exports = { logToCSV, readReportedIPs, updateSefinekAPIInCSV, wasImageRequestLogged }; \ No newline at end of file +module.exports = { logToCSV, readReportedIPs, updateSefinekAPIInCSV }; \ No newline at end of file diff --git a/utils/isImageRequest.js b/utils/isImageRequest.js deleted file mode 100644 index 356a9c0..0000000 --- a/utils/isImageRequest.js +++ /dev/null @@ -1,2 +0,0 @@ -const extensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.svg', '.webp']; -module.exports = loc => extensions.some(ext => loc.toLowerCase().endsWith(ext)); diff --git a/utils/whitelist.js b/utils/whitelist.js index 54a7238..b61e277 100644 --- a/utils/whitelist.js +++ b/utils/whitelist.js @@ -1,5 +1,4 @@ -const domains = ['api.', 'cdn.', 'blocklist.sefinek.net', 'bucket.sefinek.net']; -const userAgents = ['Chrome/129', 'Chrome/130', 'Chrome/131', 'Chrome/132', 'StellaLauncher', 'PrepareStella']; -const endpoints = ['/api/', '//video', '//js', '//images', '//imgs', 'favicon.ico', 'sitemap.xml', 'robots.txt']; +const domains = ['blocklist.sefinek.net', 'bucket.sefinek.net']; +const endpoints = ['favicon.ico', 'favicon.png', 'sitemap.xml', 'robots.txt']; -module.exports = { domains, userAgents, endpoints }; \ No newline at end of file +module.exports = { domains, endpoints }; \ No newline at end of file