// Initialize output items array
const outputItems = [];
// Create a temporary storage for VPN Tunnel alerts
const vpnTunnels = {};
// Define a delay in milliseconds for waiting for a "Tunnel Up" alert
const waitDelay = 10000; // 10 seconds
// Helper function to process the "Tunnel Up" alert
function processTunnelUp(alert, rule, agent, description, artifacts) {
const sourceRef = Math.random().toString(36).substr(2, 6);
const alertPayload = {
title: rule.description || "No title available",
tlp: 2,
tags: [
"wazuh",
`rule=${rule.id || "unknown"}`,
`agent_name=${agent.name || "unknown"}`,
`agent_id=${agent.id || "unknown"}`,
`agent_ip=${agent.ip || "unknown"}`,
],
description: description,
type: "wazuh_alert",
source: "wazuh",
sourceRef: sourceRef,
artifacts: artifacts,
raw: alert, // Include all fields from the Wazuh alert
vpn_status: "up", // Indicate the VPN tunnel status
};
console.log("Processed Tunnel Up:", alertPayload); // Debugging log
outputItems.push({ json: alertPayload });
}
// Helper function to process the "Tunnel Down" alert
function processTunnelDown(alert, rule, agent, description, artifacts) {
const sourceRef = Math.random().toString(36).substr(2, 6);
const alertPayload = {
title: rule.description || "No title available",
tlp: 2,
tags: [
"wazuh",
`rule=${rule.id || "unknown"}`,
`agent_name=${agent.name || "unknown"}`,
`agent_id=${agent.id || "unknown"}`,
`agent_ip=${agent.ip || "unknown"}`,
],
description: description,
type: "wazuh_alert",
source: "wazuh",
sourceRef: sourceRef,
artifacts: artifacts,
raw: alert, // Include all fields from the Wazuh alert
vpn_status: "down", // Indicate the VPN tunnel status
};
console.log("Processed Tunnel Down:", alertPayload); // Debugging log
outputItems.push({ json: alertPayload });
}
// Function to process the alerts synchronously
async function processAlerts(items) {
console.log("Processing Alerts:", items.length); // Debugging log
for (const item of items) {
// Extract the alert data from the input item
const alert = item.json.body.all_fields;
if (!alert) {
console.log("No alert data found in item:", item); // Debugging log
continue;
}
// Ensure alert has required fields
const rule = alert.rule || {};
const agent = alert.agent || {};
const data = alert.data || {};
const vpntunnel = data.vpntunnel || "unknown"; // Use the vpntunnel field as the identifier
const description = alert.full_log || "No description available";
// Extract IPs, URLs, and domains from the description
const ipAddresses = description.match(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g) || [];
const urls = description.match(/http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+/g) || [];
const domains = urls.map((url) => url.split("//")[1].split("/")[0]);
// Prepare artifacts for The Hive
const artifacts = [
...ipAddresses.map((ip) => ({ dataType: "ip", data: ip })),
...urls.map((url) => ({ dataType: "url", data: url })),
...domains.map((domain) => ({ dataType: "domain", data: domain })),
];
const timestamp = new Date(alert.timestamp).getTime();
// Process the alert based on the rule description
if (rule.description === "Fortigate: VPN Tunnel Down") {
console.log(`Tunnel Down detected for ${vpntunnel} at ${timestamp}`); // Debugging log
// Store the "Tunnel Down" alert with its timestamp and set a timeout
vpnTunnels[vpntunnel] = {
status: "Down",
timestamp,
alert,
artifacts,
rule,
agent,
description,
timeoutId: setTimeout(() => {
// If no "Tunnel Up" alert arrives within the delay, process the "Tunnel Down"
processTunnelDown(alert, rule, agent, description, artifacts);
delete vpnTunnels[vpntunnel];
}, waitDelay),
};
} else if (rule.description === "Fortigate: VPN Tunnel Up") {
console.log(`Tunnel Up detected for ${vpntunnel} at ${timestamp}`); // Debugging log
// Check if there's a pending "Tunnel Down" alert
if (vpnTunnels[vpntunnel] && vpnTunnels[vpntunnel].status === "Down") {
// Calculate the time difference
const timeDiff = timestamp - vpnTunnels[vpntunnel].timestamp;
if (timeDiff <= waitDelay) {
// Clear the timeout for the "Tunnel Down" alert
clearTimeout(vpnTunnels[vpntunnel].timeoutId);
// Send the "Tunnel Up" alert
processTunnelUp(alert, rule, agent, description, artifacts);
}
// Remove the "Tunnel Down" alert from the storage
delete vpnTunnels[vpntunnel];
} else {
// Directly process the "Tunnel Up" alert if no "Down" was pending
processTunnelUp(alert, rule, agent, description, artifacts);
}
}
}
}
// Execute the function to process alerts
await processAlerts(items);
// Output the processed alerts
console.log("Output Items:", outputItems.length); // Debugging log
return outputItems;
this is my javascript FYI
let me know if theres anything else i should add