423 lines
15 KiB
PHP
423 lines
15 KiB
PHP
<?php
|
|
/*
|
|
* Plugin SIEM-Wazuh pour GLPI
|
|
* Classe de gestion de la configuration
|
|
*/
|
|
|
|
if (!defined('GLPI_ROOT')) {
|
|
die("Sorry. You can't access this file directly");
|
|
}
|
|
|
|
class PluginSiemWazuhConfig extends CommonDBTM {
|
|
|
|
public $dohistory = true;
|
|
|
|
static $rightname = 'plugin_siem_wazuh_config';
|
|
|
|
const MATRIX_FIELD = '';
|
|
const SEARCHOPTIONS_INHERITANCE = true;
|
|
|
|
/**
|
|
* Return the localized name of the current Type
|
|
*/
|
|
static function getTypeName($nb = 0) {
|
|
return __('SIEM Wazuh Configuration', 'siem-wazuh');
|
|
}
|
|
|
|
/**
|
|
* Get configuration value
|
|
*/
|
|
function getConfiguration($name, $default = null, $context = 'global') {
|
|
global $DB;
|
|
|
|
$iterator = $DB->request([
|
|
'FROM' => $this->getTable(),
|
|
'WHERE' => [
|
|
'name' => $name,
|
|
'context' => $context
|
|
],
|
|
'LIMIT' => 1
|
|
]);
|
|
|
|
if (count($iterator) > 0) {
|
|
$row = $iterator->current();
|
|
return $row['value'];
|
|
}
|
|
|
|
return $default;
|
|
}
|
|
|
|
/**
|
|
* Set configuration value
|
|
*/
|
|
function setConfiguration($name, $value, $context = 'global') {
|
|
global $DB;
|
|
|
|
// Vérifier si la configuration existe
|
|
$iterator = $DB->request([
|
|
'FROM' => $this->getTable(),
|
|
'WHERE' => [
|
|
'name' => $name,
|
|
'context' => $context
|
|
],
|
|
'LIMIT' => 1
|
|
]);
|
|
|
|
if (count($iterator) > 0) {
|
|
// Mettre à jour
|
|
$row = $iterator->current();
|
|
return $this->update([
|
|
'id' => $row['id'],
|
|
'value' => $value
|
|
]);
|
|
} else {
|
|
// Créer
|
|
return $this->add([
|
|
'name' => $name,
|
|
'value' => $value,
|
|
'context' => $context
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Display configuration form
|
|
*/
|
|
function showConfigForm() {
|
|
global $CFG_GLPI;
|
|
|
|
echo "<form name='form' method='post' action='" . Toolbox::getItemTypeFormURL(__CLASS__) . "'>";
|
|
echo "<div class='spaced' id='tabsbody'>";
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
|
|
echo "<tr><th colspan='4'>" . __('General Configuration', 'siem-wazuh') . "</th></tr>";
|
|
|
|
// Configuration générale
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td width='30%'>" . __('Enable synchronization', 'siem-wazuh') . "</td>";
|
|
echo "<td width='20%'>";
|
|
Dropdown::showYesNo("sync_enabled", $this->getConfiguration('sync_enabled', 1));
|
|
echo "</td>";
|
|
echo "<td width='30%'>" . __('Auto-create tickets', 'siem-wazuh') . "</td>";
|
|
echo "<td width='20%'>";
|
|
Dropdown::showYesNo("auto_create_ticket", $this->getConfiguration('auto_create_ticket', 1));
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Maximum alerts per sync', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showNumber("max_alerts_per_sync", [
|
|
'value' => $this->getConfiguration('max_alerts_per_sync', 100),
|
|
'min' => 10,
|
|
'max' => 1000,
|
|
'step' => 10
|
|
]);
|
|
echo "</td>";
|
|
echo "<td>" . __('Alert retention (days)', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showNumber("alert_retention_days", [
|
|
'value' => $this->getConfiguration('alert_retention_days', 90),
|
|
'min' => 7,
|
|
'max' => 365,
|
|
'step' => 7
|
|
]);
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Minimum rule level', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showNumber("min_rule_level", [
|
|
'value' => $this->getConfiguration('min_rule_level', 5),
|
|
'min' => 0,
|
|
'max' => 15
|
|
]);
|
|
echo "</td>";
|
|
echo "<td>" . __('Enable notifications', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("notification_enabled", $this->getConfiguration('notification_enabled', 1));
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
// Configuration des tickets par défaut
|
|
echo "<tr><th colspan='4'>" . __('Default Ticket Settings', 'siem-wazuh') . "</th></tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Default Priority', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Ticket::dropdownPriority('default_ticket_priority', $this->getConfiguration('default_ticket_priority', 3));
|
|
echo "</td>";
|
|
echo "<td>" . __('Default Urgency', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Ticket::dropdownUrgency('default_ticket_urgency', $this->getConfiguration('default_ticket_urgency', 3));
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Default Impact', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Ticket::dropdownImpact('default_ticket_impact', $this->getConfiguration('default_ticket_impact', 3));
|
|
echo "</td>";
|
|
echo "<td>" . __('Auto-assign tickets', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("auto_assign_tickets", $this->getConfiguration('auto_assign_tickets', 0));
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
if ($this->getConfiguration('auto_assign_tickets', 0)) {
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Default Assignee', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
User::dropdown([
|
|
'name' => 'default_assignee',
|
|
'value' => $this->getConfiguration('default_assignee', 0),
|
|
'right' => 'own_ticket'
|
|
]);
|
|
echo "</td>";
|
|
echo "<td>" . __('Default Group', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Group::dropdown([
|
|
'name' => 'default_group',
|
|
'value' => $this->getConfiguration('default_group', 0)
|
|
]);
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
}
|
|
|
|
// Configuration de mapping
|
|
echo "<tr><th colspan='4'>" . __('Asset Mapping Configuration', 'siem-wazuh') . "</th></tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Match by hostname', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("match_by_hostname", $this->getConfiguration('match_by_hostname', 1));
|
|
echo "</td>";
|
|
echo "<td>" . __('Match by IP address', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("match_by_ip", $this->getConfiguration('match_by_ip', 1));
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Case sensitive matching', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("case_sensitive_matching", $this->getConfiguration('case_sensitive_matching', 0));
|
|
echo "</td>";
|
|
echo "<td>" . __('Create unknown assets', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("create_unknown_assets", $this->getConfiguration('create_unknown_assets', 0));
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
// Configuration de debug
|
|
echo "<tr><th colspan='4'>" . __('Debug Configuration', 'siem-wazuh') . "</th></tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Enable debug mode', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showYesNo("debug_mode", $this->getConfiguration('debug_mode', 0));
|
|
echo "</td>";
|
|
echo "<td>" . __('Log level', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
$log_levels = [
|
|
'error' => __('Error only', 'siem-wazuh'),
|
|
'warning' => __('Warning and above', 'siem-wazuh'),
|
|
'info' => __('Info and above', 'siem-wazuh'),
|
|
'debug' => __('All messages', 'siem-wazuh')
|
|
];
|
|
Dropdown::showFromArray('log_level', $log_levels, [
|
|
'value' => $this->getConfiguration('log_level', 'info')
|
|
]);
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Keep debug logs (days)', 'siem-wazuh') . "</td>";
|
|
echo "<td>";
|
|
Dropdown::showNumber("debug_retention_days", [
|
|
'value' => $this->getConfiguration('debug_retention_days', 30),
|
|
'min' => 1,
|
|
'max' => 90
|
|
]);
|
|
echo "</td>";
|
|
echo "<td></td><td></td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_2'>";
|
|
echo "<td class='center' colspan='4'>";
|
|
echo "<input type='submit' name='update_config' value='" . _sx('button', 'Save') . "' class='submit'>";
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "</table>";
|
|
echo "</div>";
|
|
Html::closeForm();
|
|
|
|
// Affichage des statistiques
|
|
$this->showStatistics();
|
|
}
|
|
|
|
/**
|
|
* Process configuration form
|
|
*/
|
|
function processConfigForm() {
|
|
if (isset($_POST['update_config'])) {
|
|
$config_fields = [
|
|
'sync_enabled', 'auto_create_ticket', 'max_alerts_per_sync', 'alert_retention_days',
|
|
'min_rule_level', 'notification_enabled', 'default_ticket_priority',
|
|
'default_ticket_urgency', 'default_ticket_impact', 'auto_assign_tickets',
|
|
'default_assignee', 'default_group', 'match_by_hostname', 'match_by_ip',
|
|
'case_sensitive_matching', 'create_unknown_assets', 'debug_mode',
|
|
'log_level', 'debug_retention_days'
|
|
];
|
|
|
|
foreach ($config_fields as $field) {
|
|
if (isset($_POST[$field])) {
|
|
$this->setConfiguration($field, $_POST[$field]);
|
|
}
|
|
}
|
|
|
|
Session::addMessageAfterRedirect(__('Configuration updated successfully', 'siem-wazuh'));
|
|
Html::back();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show statistics
|
|
*/
|
|
function showStatistics() {
|
|
global $DB;
|
|
|
|
echo "<div class='spaced'>";
|
|
echo "<table class='tab_cadre_fixe'>";
|
|
echo "<tr><th colspan='4'>" . __('Statistics', 'siem-wazuh') . "</th></tr>";
|
|
|
|
// Statistiques des serveurs
|
|
$servers_count = countElementsInTable('glpi_plugin_siem_wazuh_servers');
|
|
$active_servers = countElementsInTable('glpi_plugin_siem_wazuh_servers', ['is_active' => 1]);
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Total servers', 'siem-wazuh') . "</td>";
|
|
echo "<td>$servers_count</td>";
|
|
echo "<td>" . __('Active servers', 'siem-wazuh') . "</td>";
|
|
echo "<td>$active_servers</td>";
|
|
echo "</tr>";
|
|
|
|
// Statistiques des alertes
|
|
$total_alerts = countElementsInTable('glpi_plugin_siem_wazuh_alerts');
|
|
$new_alerts = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['status' => 'new']);
|
|
$processed_alerts = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['status' => 'processed']);
|
|
$tickets_created = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['status' => 'ticket_created']);
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Total alerts', 'siem-wazuh') . "</td>";
|
|
echo "<td>$total_alerts</td>";
|
|
echo "<td>" . __('New alerts', 'siem-wazuh') . "</td>";
|
|
echo "<td>$new_alerts</td>";
|
|
echo "</tr>";
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Processed alerts', 'siem-wazuh') . "</td>";
|
|
echo "<td>$processed_alerts</td>";
|
|
echo "<td>" . __('Tickets created', 'siem-wazuh') . "</td>";
|
|
echo "<td>$tickets_created</td>";
|
|
echo "</tr>";
|
|
|
|
// Alertes par sévérité
|
|
$severities = PluginSiemWazuhAlert::getSeverityArray();
|
|
foreach ($severities as $severity => $label) {
|
|
$count = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['severity' => $severity]);
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . sprintf(__('%s alerts', 'siem-wazuh'), $label) . "</td>";
|
|
echo "<td>$count</td>";
|
|
if (next($severities) !== false) {
|
|
$next_severity = key($severities);
|
|
$next_label = current($severities);
|
|
$next_count = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['severity' => $next_severity]);
|
|
echo "<td>" . sprintf(__('%s alerts', 'siem-wazuh'), $next_label) . "</td>";
|
|
echo "<td>$next_count</td>";
|
|
next($severities);
|
|
} else {
|
|
echo "<td></td><td></td>";
|
|
}
|
|
echo "</tr>";
|
|
}
|
|
|
|
// 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();
|
|
|
|
echo "<tr class='tab_bg_1'>";
|
|
echo "<td>" . __('Last global sync', 'siem-wazuh') . "</td>";
|
|
echo "<td colspan='3'>";
|
|
echo $last_sync['last_sync'] ? Html::convDateTime($last_sync['last_sync']) : __('Never');
|
|
echo "</td>";
|
|
echo "</tr>";
|
|
|
|
echo "</table>";
|
|
echo "</div>";
|
|
}
|
|
|
|
/**
|
|
* Get menu content
|
|
*/
|
|
static function getMenuContent() {
|
|
$menu = [];
|
|
if (Session::haveRight(static::$rightname, READ)) {
|
|
$menu['title'] = self::getMenuName();
|
|
$menu['page'] = "/plugins/siem-wazuh/front/wazuhconfig.php";
|
|
$menu['links']['config'] = "/plugins/siem-wazuh/front/wazuhconfig.php";
|
|
}
|
|
return $menu;
|
|
}
|
|
|
|
/**
|
|
* Get menu name
|
|
*/
|
|
static function getMenuName() {
|
|
return self::getTypeName(1);
|
|
}
|
|
|
|
/**
|
|
* Get default configurations
|
|
*/
|
|
static function getDefaultConfigurations() {
|
|
return [
|
|
'sync_enabled' => 1,
|
|
'auto_create_ticket' => 1,
|
|
'max_alerts_per_sync' => 100,
|
|
'alert_retention_days' => 90,
|
|
'min_rule_level' => 5,
|
|
'notification_enabled' => 1,
|
|
'default_ticket_priority' => 3,
|
|
'default_ticket_urgency' => 3,
|
|
'default_ticket_impact' => 3,
|
|
'auto_assign_tickets' => 0,
|
|
'default_assignee' => 0,
|
|
'default_group' => 0,
|
|
'match_by_hostname' => 1,
|
|
'match_by_ip' => 1,
|
|
'case_sensitive_matching' => 0,
|
|
'create_unknown_assets' => 0,
|
|
'debug_mode' => 0,
|
|
'log_level' => 'info',
|
|
'debug_retention_days' => 30
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Install default configuration
|
|
*/
|
|
static function installDefaultConfiguration() {
|
|
$config = new self();
|
|
$defaults = self::getDefaultConfigurations();
|
|
|
|
foreach ($defaults as $name => $value) {
|
|
$config->setConfiguration($name, $value);
|
|
}
|
|
}
|
|
} |