113 lines
4.6 KiB
JavaScript
113 lines
4.6 KiB
JavaScript
require('dotenv').config();
|
|
const axios = require('axios').default;
|
|
const fs = require('fs');
|
|
const Discord = require('discord.js');
|
|
const API_BASE_URL = 'https://api.cloudflare.com/client/v4';
|
|
|
|
const { CF_TOKEN, CF_ZONES_BLACKLIST, WEBHOOK_ID, WEBHOOK_SECRET } = process.env;
|
|
|
|
if (!CF_TOKEN)
|
|
return console.log("Error: Env var 'CF_TOKEN' is not set");
|
|
if (!WEBHOOK_ID)
|
|
return console.log("Error: Env var 'WEBHOOK_ID' is not set");
|
|
if (!WEBHOOK_SECRET)
|
|
return console.log("Error: Env var 'WEBHOOK_SECRET' is not set");
|
|
if (CF_ZONES_BLACKLIST)
|
|
console.log("Info: 'CF_ZONES_BLACKLIST' is set");
|
|
|
|
const client = new Discord.WebhookClient(WEBHOOK_ID, WEBHOOK_SECRET);
|
|
const ZONES_BLACKLIST = CF_ZONES_BLACKLIST?.split(',') || [];
|
|
|
|
async function refresh(zone) {
|
|
if (!fs.existsSync('./last_request')) await fs.promises.writeFile('./last_request', '' + (Date.now() - (1000 * 60 * 60 * 24) + 10000));
|
|
let lowerDate = new Date();
|
|
let upperDate = new Date();
|
|
lowerDate.setTime(await fs.promises.readFile('./last_request'));
|
|
if (upperDate.getTime() - lowerDate.getTime() > 1000 * 60 * 60 * 24) lowerDate.setTime((Date.now() - (1000 * 60 * 60 * 24) + 10000));
|
|
let payload = `{ "query":
|
|
"query ListFirewallEvents($zoneTag: string, $filter: FirewallEventsAdaptiveFilter_InputObject) {
|
|
viewer {
|
|
zones(filter: { zoneTag: $zoneTag }) {
|
|
firewallEventsAdaptive(
|
|
filter: $filter
|
|
limit: 10
|
|
orderBy: [datetime_DESC]
|
|
) {
|
|
action
|
|
clientCountryName
|
|
clientIP
|
|
clientIPClass
|
|
clientRequestHTTPHost
|
|
clientRequestHTTPMethodName
|
|
clientRequestScheme
|
|
clientRequestPath
|
|
clientRequestQuery
|
|
datetime
|
|
source
|
|
userAgent
|
|
clientRefererHost
|
|
clientRefererPath
|
|
ruleId
|
|
}
|
|
}
|
|
}
|
|
}",
|
|
"variables": {
|
|
"zoneTag": "${zone.id}",
|
|
"filter": {
|
|
"datetime_geq": "${lowerDate.toISOString()}",
|
|
"datetime_leq": "${upperDate.toISOString()}"
|
|
}
|
|
}
|
|
}`.replace(/\n/g, '');
|
|
let res = await axios.post(
|
|
`${API_BASE_URL}/graphql/`,
|
|
payload,
|
|
{
|
|
headers: {
|
|
'Authorization': `Bearer ${CF_TOKEN}`
|
|
}
|
|
}
|
|
);
|
|
let eventsPerZone = res.data.data?.viewer?.zones;
|
|
if (!(eventsPerZone instanceof Array))
|
|
return console.log(res.data);
|
|
|
|
await fs.promises.writeFile('./last_request', '' + upperDate.getTime());
|
|
|
|
eventsPerZone.forEach(events => {
|
|
events.firewallEventsAdaptive.forEach(event => {
|
|
console.log(`[${zone.name}] Info: New firewall event`);
|
|
client.send(
|
|
new Discord.MessageEmbed()
|
|
.setTitle('Retard deflected')
|
|
.setColor('#f6821f')
|
|
.setAuthor(`Cloudflare - ${event.clientRequestHTTPHost || zone.name}`, 'https://pbs.twimg.com/profile_images/1313131647315910666/opulcRqc.jpg')
|
|
.setDescription(`${event.source} - ${event.ruleId}`)
|
|
.addField('Firewall Action', event.action, true)
|
|
.addField('IP Address', `${event.clientIP} (${event.clientCountryName}` +
|
|
`${event.clientIPClass != 'unknown' ? ` - ${event.clientIPClass}` : ''})`, true)
|
|
.addField('\u200b', '\u200b')
|
|
.addField('Request', `${event.clientRequestHTTPMethodName} ${event.clientRequestPath}${event.clientRequestQuery}` +
|
|
`${event.clientRefererHost ? `\nReferer: ${event.clientRefererHost}${event.clientRefererPath}` : ''}`, true)
|
|
.addField('User Agent', `${event.userAgent}`, true)
|
|
.setTimestamp(event.datetime)
|
|
)
|
|
});
|
|
});
|
|
}
|
|
|
|
(async () => {
|
|
let { data: zones } = await axios.get(`${API_BASE_URL}/zones`, { headers: { 'Authorization': 'Bearer ' + CF_TOKEN } });
|
|
if (!zones.result) return console.log(zones);
|
|
|
|
let total = 0;
|
|
zones.result.forEach(async zone => {
|
|
if (ZONES_BLACKLIST.indexOf(zone.id) == -1) {
|
|
total++;
|
|
refresh(zone);
|
|
setInterval(() => refresh(zone), 1000 * 15);
|
|
}
|
|
});
|
|
console.log(`Info: Monitoring ${total} zone${total != 1 ? 's' : ''}`);
|
|
})(); |