Update
This commit is contained in:
parent
5860aba631
commit
c09400eb82
6 changed files with 28 additions and 62 deletions
|
|
@ -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
|
||||
|
|
|
|||
41
index.js
41
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 =====================');
|
||||
|
|
|
|||
|
|
@ -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}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -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 };
|
||||
module.exports = { logToCSV, readReportedIPs, updateSefinekAPIInCSV };
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
const extensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.svg', '.webp'];
|
||||
module.exports = loc => extensions.some(ext => loc.toLowerCase().endsWith(ext));
|
||||
|
|
@ -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 };
|
||||
module.exports = { domains, endpoints };
|
||||
Loading…
Add table
Reference in a new issue