1.4.0: Added filters
This commit is contained in:
parent
5e1fb0d823
commit
443495d54b
5 changed files with 47 additions and 76 deletions
48
index.js
48
index.js
|
|
@ -6,29 +6,32 @@ const headers = require('./utils/headers.js');
|
||||||
const { logToCSV, readReportedIPs } = require('./services/csv.js');
|
const { logToCSV, readReportedIPs } = require('./services/csv.js');
|
||||||
const formatDelay = require('./utils/formatDelay.js');
|
const formatDelay = require('./utils/formatDelay.js');
|
||||||
const fetchServerIP = require('./services/fetchServerIP.js');
|
const fetchServerIP = require('./services/fetchServerIP.js');
|
||||||
const whitelist = require('./utils/whitelist.js');
|
const getFilters = require('./services/getFilters.js');
|
||||||
const log = require('./utils/log.js');
|
const log = require('./utils/log.js');
|
||||||
|
|
||||||
const fetchBlockedIPs = async () => {
|
const fetchBlockedIPs = async whitelist => {
|
||||||
try {
|
try {
|
||||||
const { data, status } = await axios.post('https://api.cloudflare.com/client/v4/graphql', PAYLOAD(), { headers: headers.CLOUDFLARE });
|
const { data, status } = await axios.post('https://api.cloudflare.com/client/v4/graphql', PAYLOAD(), { headers: headers.CLOUDFLARE });
|
||||||
const events = data?.data?.viewer?.zones[0]?.firewallEventsAdaptive;
|
const events = data?.data?.viewer?.zones?.[0]?.firewallEventsAdaptive;
|
||||||
if (events) {
|
if (!events) throw new Error(`Failed to retrieve data from Cloudflare (status ${status}): ${JSON.stringify(data?.errors)}`);
|
||||||
const filtered = events.filter(x =>
|
|
||||||
x.ip !== fetchServerIP() &&
|
|
||||||
!whitelist.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`);
|
const isWhitelisted = event =>
|
||||||
return filtered;
|
event.ip === fetchServerIP() ||
|
||||||
} else {
|
whitelist.userAgents.some(ua => event.userAgent.includes(ua)) ||
|
||||||
throw new Error(`Failed to retrieve data from Cloudflare (status ${status}); ${JSON.stringify(data?.errors)}`);
|
whitelist.imgExtensions.some(ext => event.clientRequestPath.endsWith(ext)) ||
|
||||||
}
|
whitelist.domains.some(domain => event.clientRequestHTTPHost?.includes(domain)) ||
|
||||||
|
whitelist.endpoints.some(endpoint => event.clientRequestPath?.includes(endpoint));
|
||||||
|
|
||||||
|
const filtered = events.filter(event => !isWhitelisted(event));
|
||||||
|
|
||||||
|
log(0, `Fetched ${events.length} events (filtered ${filtered.length}) from Cloudflare`);
|
||||||
|
return filtered;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log(2, err.response?.data ? `${err.response.status} HTTP ERROR Cloudflare API: ${JSON.stringify(err.response.data, null, 2)}` : `Unknown error with Cloudflare API: ${err.message}`);
|
log(2, err.response?.data
|
||||||
return null;
|
? `${err.response.status} HTTP ERROR Cloudflare API: ${JSON.stringify(err.response.data, null, 2)}`
|
||||||
|
: `Unknown error with Cloudflare API: ${err.message}`
|
||||||
|
);
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -108,9 +111,11 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount
|
||||||
// AbuseIPDB
|
// AbuseIPDB
|
||||||
let cycleId = 1;
|
let cycleId = 1;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
const whitelist = await getFilters();
|
||||||
|
|
||||||
log(0, `===================== Reporting Cycle No. ${cycleId} =====================`);
|
log(0, `===================== Reporting Cycle No. ${cycleId} =====================`);
|
||||||
|
|
||||||
const blockedIPEvents = await fetchBlockedIPs();
|
const blockedIPEvents = await fetchBlockedIPs(whitelist);
|
||||||
if (!blockedIPEvents) {
|
if (!blockedIPEvents) {
|
||||||
log(1, 'No events fetched, skipping cycle...');
|
log(1, 'No events fetched, skipping cycle...');
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -136,13 +141,6 @@ const reportIP = async (event, uri, country, hostname, endpoint, cycleErrorCount
|
||||||
const reportedIPs = readReportedIPs();
|
const reportedIPs = readReportedIPs();
|
||||||
const { recentlyReported } = isIPReportedRecently(event.rayName, ip, reportedIPs);
|
const { recentlyReported } = isIPReportedRecently(event.rayName, ip, reportedIPs);
|
||||||
if (recentlyReported) {
|
if (recentlyReported) {
|
||||||
// if (MAIN.NODE_ENV === 'development') {
|
|
||||||
// const hoursAgo = Math.floor(timeDifference / (1000 * 60 * 60));
|
|
||||||
// const minutesAgo = Math.floor((timeDifference % (1000 * 60 * 60)) / (1000 * 60));
|
|
||||||
// const secondsAgo = Math.floor((timeDifference % (1000 * 60)) / 1000);
|
|
||||||
// log(0, `${ip} was ${reason} ${hoursAgo}h ${minutesAgo}m ${secondsAgo}s ago. Skipping...`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
cycleSkippedCount++;
|
cycleSkippedCount++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
package-lock.json
generated
20
package-lock.json
generated
|
|
@ -1,26 +1,26 @@
|
||||||
{
|
{
|
||||||
"name": "cf-waf-to-abuseipdb",
|
"name": "cf-waf-to-abuseipdb",
|
||||||
"version": "1.3.1",
|
"version": "1.4.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cf-waf-to-abuseipdb",
|
"name": "cf-waf-to-abuseipdb",
|
||||||
"version": "1.3.1",
|
"version": "1.4.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"ipaddr.js": "^2.2.0"
|
"ipaddr.js": "^2.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.19.0",
|
"@eslint/js": "^9.20.0",
|
||||||
"globals": "^15.14.0"
|
"globals": "^15.15.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "9.19.0",
|
"version": "9.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz",
|
||||||
"integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==",
|
"integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -100,9 +100,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "15.14.0",
|
"version": "15.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
|
||||||
"integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==",
|
"integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
15
package.json
15
package.json
|
|
@ -1,16 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "cf-waf-to-abuseipdb",
|
"name": "cf-waf-to-abuseipdb",
|
||||||
"version": "1.3.1",
|
"version": "1.4.0",
|
||||||
"description": "Node.js script for automatically reporting incidents to AbuseIPDB using data obtained from Cloudflare WAF.",
|
"description": "Node.js script for automatically reporting incidents to AbuseIPDB using data obtained from Cloudflare WAF.",
|
||||||
"keywords": [
|
|
||||||
"abuseipdb",
|
|
||||||
"cloudflare",
|
|
||||||
"cloudflare waf",
|
|
||||||
"waf",
|
|
||||||
"reporting",
|
|
||||||
"abuseipdb reporting",
|
|
||||||
"node abuseipdb"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/sefinek/Cloudflare-WAF-To-AbuseIPDB",
|
"homepage": "https://github.com/sefinek/Cloudflare-WAF-To-AbuseIPDB",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/sefinek/Cloudflare-WAF-To-AbuseIPDB/issues"
|
"url": "https://github.com/sefinek/Cloudflare-WAF-To-AbuseIPDB/issues"
|
||||||
|
|
@ -32,7 +23,7 @@
|
||||||
"ipaddr.js": "^2.2.0"
|
"ipaddr.js": "^2.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.19.0",
|
"@eslint/js": "^9.20.0",
|
||||||
"globals": "^15.14.0"
|
"globals": "^15.15.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
services/getFilters.js
Normal file
11
services/getFilters.js
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
const axios = require('./axios.js');
|
||||||
|
|
||||||
|
module.exports = async () => {
|
||||||
|
try {
|
||||||
|
const res = await axios.get('https://api.sefinek.net/api/v2/filter-rules');
|
||||||
|
if (!res.data.success) throw new Error('Sefinek API Error');
|
||||||
|
return { userAgents: res.data.userAgents, domains: res.data.domains, endpoints: res.data.endpoints, imgExtensions: res.data.imgExtensions };
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
const domains = [
|
|
||||||
'api.',
|
|
||||||
'cdn.',
|
|
||||||
'static.',
|
|
||||||
'assets.',
|
|
||||||
'media.',
|
|
||||||
'auth.',
|
|
||||||
'files.',
|
|
||||||
'blocklist.sefinek.net',
|
|
||||||
'bucket.sefinek.net',
|
|
||||||
];
|
|
||||||
|
|
||||||
const endpoints = [
|
|
||||||
'favicon.ico',
|
|
||||||
'favicon.png',
|
|
||||||
'sitemap.xml',
|
|
||||||
'robots.txt',
|
|
||||||
'ads.txt',
|
|
||||||
'security.txt',
|
|
||||||
'humans.txt',
|
|
||||||
'manifest.json',
|
|
||||||
'apple-touch-icon.png',
|
|
||||||
'crossdomain.xml',
|
|
||||||
'site.webmanifest',
|
|
||||||
];
|
|
||||||
|
|
||||||
const imgExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.svg', '.webp'];
|
|
||||||
|
|
||||||
module.exports = { domains, endpoints, imgExtensions };
|
|
||||||
Loading…
Add table
Reference in a new issue