Files
SIEM---Wazuh/ajax/sync_alerts.php
2025-08-27 21:17:28 +02:00

342 lines
11 KiB
PHP

<?php
/*
* Plugin SIEM-Wazuh pour GLPI
* AJAX - Synchronisation des alertes Wazuh
*/
include ('../../../inc/includes.php');
header('Content-Type: application/json');
// Vérification des droits et du plugin
if (!Session::haveRight("plugin_siem_wazuh_server", UPDATE) || !Plugin::isPluginActive('siem-wazuh')) {
echo json_encode(['success' => false, 'message' => __('Access denied', 'siem-wazuh')]);
exit;
}
// Vérification CSRF pour les requêtes POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !Session::validateCSRF($_POST)) {
echo json_encode(['success' => false, 'message' => __('Invalid CSRF token', 'siem-wazuh')]);
exit;
}
$response = ['success' => false, 'message' => '', 'stats' => []];
try {
$action = $_POST['action'] ?? $_GET['action'] ?? 'sync';
switch ($action) {
case 'sync':
$server_id = intval($_POST['server_id'] ?? $_GET['server_id'] ?? 0);
if ($server_id > 0) {
// Synchronisation d'un serveur spécifique
$result = syncSingleServer($server_id);
} else {
// Synchronisation de tous les serveurs actifs
$result = syncAllServers();
}
$response = $result;
break;
case 'sync_for_item':
// Synchronisation pour un élément spécifique
$item_id = intval($_POST['item_id'] ?? 0);
$item_type = $_POST['item_type'] ?? '';
if ($item_id > 0 && !empty($item_type)) {
$result = syncForItem($item_id, $item_type);
$response = $result;
} else {
throw new Exception(__('Invalid item parameters', 'siem-wazuh'));
}
break;
case 'status':
// Statut de la synchronisation
$response = getSyncStatus();
break;
default:
throw new Exception(__('Unknown action', 'siem-wazuh'));
}
} catch (Exception $e) {
$response = [
'success' => false,
'message' => $e->getMessage(),
'error_type' => 'exception'
];
}
echo json_encode($response, JSON_UNESCAPED_UNICODE);
/**
* Synchroniser un serveur spécifique
*/
function syncSingleServer($server_id) {
$server = new PluginSiemWazuhServer();
if (!$server->getFromDB($server_id)) {
throw new Exception(__('Server not found', 'siem-wazuh'));
}
$start_time = microtime(true);
$result = $server->syncAlerts();
$sync_time = round((microtime(true) - $start_time) * 1000, 2);
if ($result['success']) {
// Extraire le nombre d'alertes du message
$processed = 0;
if (preg_match('/(\d+)/', $result['message'], $matches)) {
$processed = intval($matches[1]);
}
Event::log(
$server_id,
"PluginSiemWazuhServer",
5,
"sync",
sprintf(__('Manual sync completed for server %s: %s'), $server->fields['name'], $result['message'])
);
return [
'success' => true,
'message' => $result['message'],
'stats' => [
'processed' => $processed,
'sync_time' => $sync_time,
'server_name' => $server->fields['name']
]
];
} else {
Event::log(
$server_id,
"PluginSiemWazuhServer",
2,
"sync",
sprintf(__('Manual sync failed for server %s: %s'), $server->fields['name'], $result['message'])
);
return [
'success' => false,
'message' => $result['message'],
'server_name' => $server->fields['name']
];
}
}
/**
* Synchroniser tous les serveurs actifs
*/
function syncAllServers() {
global $DB;
$iterator = $DB->request([
'FROM' => 'glpi_plugin_siem_wazuh_servers',
'WHERE' => ['is_active' => 1]
]);
$total_processed = 0;
$successful_servers = 0;
$failed_servers = 0;
$sync_results = [];
$start_time = microtime(true);
foreach ($iterator as $server_data) {
try {
$result = syncSingleServer($server_data['id']);
if ($result['success']) {
$successful_servers++;
$total_processed += $result['stats']['processed'] ?? 0;
$sync_results[] = [
'server' => $server_data['name'],
'status' => 'success',
'processed' => $result['stats']['processed'] ?? 0
];
} else {
$failed_servers++;
$sync_results[] = [
'server' => $server_data['name'],
'status' => 'failed',
'error' => $result['message']
];
}
} catch (Exception $e) {
$failed_servers++;
$sync_results[] = [
'server' => $server_data['name'],
'status' => 'error',
'error' => $e->getMessage()
];
}
}
$total_time = round((microtime(true) - $start_time) * 1000, 2);
$message = sprintf(
__('Sync completed: %d servers processed, %d successful, %d failed, %d total alerts processed'),
count($sync_results),
$successful_servers,
$failed_servers,
$total_processed
);
return [
'success' => $failed_servers == 0,
'message' => $message,
'stats' => [
'total_servers' => count($sync_results),
'successful_servers' => $successful_servers,
'failed_servers' => $failed_servers,
'total_processed' => $total_processed,
'sync_time' => $total_time
],
'details' => $sync_results
];
}
/**
* Synchroniser pour un élément spécifique
*/
function syncForItem($item_id, $item_type) {
// Cette fonction recherche et synchronise les alertes
// pour un élément spécifique (ordinateur, équipement réseau, etc.)
$valid_types = ['Computer', 'NetworkEquipment', 'Peripheral', 'Phone', 'Printer'];
if (!in_array($item_type, $valid_types)) {
throw new Exception(__('Invalid item type', 'siem-wazuh'));
}
$item = new $item_type();
if (!$item->getFromDB($item_id)) {
throw new Exception(__('Item not found', 'siem-wazuh'));
}
// Récupérer les informations de l'élément pour le matching
$search_criteria = [];
// Recherche par nom
if (!empty($item->fields['name'])) {
$search_criteria['hostname'] = $item->fields['name'];
}
// Recherche par IP (si disponible)
$ip_addresses = [];
if (method_exists($item, 'getNetworkInterfaces')) {
// Logique pour récupérer les adresses IP de l'élément
// Cette partie nécessiterait une implémentation plus détaillée
}
// Synchroniser avec tous les serveurs actifs en filtrant par critères
global $DB;
$iterator = $DB->request([
'FROM' => 'glpi_plugin_siem_wazuh_servers',
'WHERE' => ['is_active' => 1]
]);
$total_found = 0;
foreach ($iterator as $server_data) {
$server = new PluginSiemWazuhServer();
$server->fields = $server_data;
$api = new PluginSiemWazuhAPI($server);
// Construire les paramètres de recherche pour l'API
$search_params = [];
if (!empty($search_criteria['hostname'])) {
$search_params['agent.name'] = $search_criteria['hostname'];
}
try {
$result = $api->getAlerts($search_params);
if ($result['success'] && isset($result['data']['data'])) {
$alert = new PluginSiemWazuhAlert();
$processed = $alert->processAlerts($server_data['id'], $result['data']['data']);
$total_found += $processed;
}
} catch (Exception $e) {
// Log l'erreur mais continue avec les autres serveurs
error_log("SIEM-Wazuh: Error syncing for item $item_type:$item_id on server {$server_data['name']}: " . $e->getMessage());
}
}
return [
'success' => true,
'message' => sprintf(__('%d alerts found and processed for %s'), $total_found, $item->getName()),
'stats' => [
'processed' => $total_found,
'item_name' => $item->getName(),
'item_type' => $item_type
]
];
}
/**
* Obtenir le statut de synchronisation
*/
function getSyncStatus() {
global $DB;
// Statistiques générales
$stats = [];
// Nombre total de serveurs
$stats['total_servers'] = countElementsInTable('glpi_plugin_siem_wazuh_servers');
$stats['active_servers'] = countElementsInTable('glpi_plugin_siem_wazuh_servers', ['is_active' => 1]);
// Dernière synchronisation
$last_sync = $DB->request([
'SELECT' => ['MAX' => 'last_sync AS last_sync'],
'FROM' => 'glpi_plugin_siem_wazuh_servers',
'WHERE' => ['is_active' => 1]
])->current();
$stats['last_sync'] = $last_sync['last_sync'];
// Alertes par statut
$alert_stats = [];
$statuses = ['new', 'processed', 'ignored', 'ticket_created'];
foreach ($statuses as $status) {
$alert_stats[$status] = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['status' => $status]);
}
$stats['alerts'] = $alert_stats;
// Alertes par sévérité
$severity_stats = [];
$severities = ['low', 'medium', 'high', 'critical'];
foreach ($severities as $severity) {
$severity_stats[$severity] = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['severity' => $severity]);
}
$stats['severity'] = $severity_stats;
// Alertes des dernières 24h
$stats['alerts_24h'] = countElementsInTable(
'glpi_plugin_siem_wazuh_alerts',
['date_creation' => ['>=', date('Y-m-d H:i:s', strtotime('-24 hours'))]]
);
// Tickets créés aujourd'hui
$stats['tickets_today'] = countElementsInTable(
'glpi_plugin_siem_wazuh_alerts',
[
'status' => 'ticket_created',
'date_mod' => ['>=', date('Y-m-d 00:00:00')]
]
);
// Vérifier s'il y a une synchronisation en cours
$config = new PluginSiemWazuhConfig();
$sync_in_progress = $config->getConfiguration('sync_in_progress', 0);
return [
'success' => true,
'message' => __('Status retrieved successfully', 'siem-wazuh'),
'stats' => $stats,
'sync_in_progress' => (bool)$sync_in_progress,
'timestamp' => date('Y-m-d H:i:s')
];
}