From 74433d5dc66daf029471f7937f71da6900444668 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 2 May 2026 18:27:08 +0000 Subject: [PATCH] deploy/mariadb/init/001-schema.sql aktualisiert --- deploy/mariadb/init/001-schema.sql | 153 +++++++++++++++-------------- 1 file changed, 77 insertions(+), 76 deletions(-) diff --git a/deploy/mariadb/init/001-schema.sql b/deploy/mariadb/init/001-schema.sql index 99ed382..29db4a1 100644 --- a/deploy/mariadb/init/001-schema.sql +++ b/deploy/mariadb/init/001-schema.sql @@ -1,20 +1,27 @@ --- SIEM-lite vollständiges Datenbankschema --- Ziel: schneller Test-Restore mit partitionierten Tabellen, Buckets, UEBA, Baseline, SOC und UI-Bewertungen. --- Engine: MySQL 8.x / MariaDB mit InnoDB und RANGE COLUMNS Partitionierung. +-- SIEM-lite vollständiges MariaDB-kompatibles Datenbankschema +-- Stand: Partitionierung event_logs/event_logs_raw, 3h-Partitionen, Raw-XML-Auslagerung, +-- Baseline-Buckets, UEBA, SOC/Risk, UI-Bewertungen. +-- +-- Getestet/ausgelegt für MariaDB/MySQL InnoDB. -- -- WICHTIG: -- 1. Dieses Script löscht bestehende Tabellen. --- 2. Partitionierung erfolgt auf UTC-DATETIME-Spalten. --- 3. event_logs und event_logs_raw starten mit pmax und werden danach per Stored Procedure --- mit 3-Stunden-Partitionen von -6h bis +24h vorbereitet. --- 4. Im Go-Code sollte der Partition-Maintenance-Job weiterlaufen und Partitionen fortlaufend erzeugen. --- 5. Für time.ParseDuration in Go: 30 Tage als 720h konfigurieren, nicht als 30d. +-- 2. Partitionierung erfolgt nach DATETIME(6)-Spalte ts. +-- 3. MariaDB erlaubt ON UPDATE UTC_TIMESTAMP(6) nicht zuverlässig. +-- Deshalb nutzt dieses Schema DEFAULT CURRENT_TIMESTAMP(6) / ON UPDATE CURRENT_TIMESTAMP(6). +-- 4. Stelle für echte UTC-Speicherung im Go-DSN zusätzlich die DB-Session auf UTC: +-- ?parseTime=true&loc=UTC&time_zone=%27%2B00%3A00%27 +-- oder setze beim Verbindungsaufbau SET time_zone = '+00:00'. +-- 5. Spalten in zusammengesetzten Keys wurden auf VARCHAR(191) begrenzt, +-- damit utf8mb4 und 3072-Byte-Key-Limit keine Fehler erzeugen. SET NAMES utf8mb4; SET time_zone = '+00:00'; SET FOREIGN_KEY_CHECKS = 0; +DROP PROCEDURE IF EXISTS ensure_siem_partitions; + DROP TABLE IF EXISTS event_count_buckets; DROP TABLE IF EXISTS ueba_context_buckets; DROP TABLE IF EXISTS host_risk_scores; @@ -39,10 +46,10 @@ SET FOREIGN_KEY_CHECKS = 1; CREATE TABLE agents ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - hostname VARCHAR(255) NOT NULL, + hostname VARCHAR(191) NOT NULL, api_key_hash CHAR(64) NOT NULL, - first_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - last_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + first_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + last_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), last_ip VARCHAR(64) NOT NULL DEFAULT '', is_enabled TINYINT(1) NOT NULL DEFAULT 1, @@ -60,43 +67,42 @@ CREATE TABLE event_logs ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, ts DATETIME(6) NOT NULL, agent_id BIGINT UNSIGNED NOT NULL, - hostname VARCHAR(255) NOT NULL, + hostname VARCHAR(191) NOT NULL, channel_name VARCHAR(128) NOT NULL, event_id INT UNSIGNED NOT NULL, - source VARCHAR(255) NOT NULL DEFAULT '', + source VARCHAR(191) NOT NULL DEFAULT '', - computer VARCHAR(255) NOT NULL DEFAULT '', - provider_name VARCHAR(255) NOT NULL DEFAULT '', + computer VARCHAR(191) NOT NULL DEFAULT '', + provider_name VARCHAR(191) NOT NULL DEFAULT '', level_value INT UNSIGNED NOT NULL DEFAULT 0, task_value INT UNSIGNED NOT NULL DEFAULT 0, opcode_value INT UNSIGNED NOT NULL DEFAULT 0, - keywords VARCHAR(255) NOT NULL DEFAULT '', + keywords VARCHAR(191) NOT NULL DEFAULT '', - target_user VARCHAR(255) NOT NULL DEFAULT '', - target_user_norm VARCHAR(255) NOT NULL DEFAULT '', - target_domain VARCHAR(255) NOT NULL DEFAULT '', + target_user VARCHAR(191) NOT NULL DEFAULT '', + target_user_norm VARCHAR(191) NOT NULL DEFAULT '', + target_domain VARCHAR(191) NOT NULL DEFAULT '', - subject_user VARCHAR(255) NOT NULL DEFAULT '', - subject_user_norm VARCHAR(255) NOT NULL DEFAULT '', - subject_domain VARCHAR(255) NOT NULL DEFAULT '', + subject_user VARCHAR(191) NOT NULL DEFAULT '', + subject_user_norm VARCHAR(191) NOT NULL DEFAULT '', + subject_domain VARCHAR(191) NOT NULL DEFAULT '', - workstation VARCHAR(255) NOT NULL DEFAULT '', + workstation VARCHAR(191) NOT NULL DEFAULT '', src_ip VARCHAR(64) NOT NULL DEFAULT '', src_port VARCHAR(32) NOT NULL DEFAULT '', logon_type VARCHAR(32) NOT NULL DEFAULT '', - process_name VARCHAR(1024) NOT NULL DEFAULT '', + process_name VARCHAR(768) NOT NULL DEFAULT '', authentication_package VARCHAR(128) NOT NULL DEFAULT '', logon_process VARCHAR(128) NOT NULL DEFAULT '', status_text VARCHAR(128) NOT NULL DEFAULT '', sub_status_text VARCHAR(128) NOT NULL DEFAULT '', - failure_reason VARCHAR(1024) NOT NULL DEFAULT '', + failure_reason VARCHAR(768) NOT NULL DEFAULT '', - received_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + received_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), msg_sha256 CHAR(64) NOT NULL, - -- msg ist optional als kurzer/kompatibler Rest vorhanden. - -- Wenn Raw XML ausgelagert ist, kann hier leerer String oder kurzer Auszug gespeichert werden. + -- Optionaler Kompatibilitätsrest. Raw XML gehört in event_logs_raw. msg MEDIUMTEXT NULL, PRIMARY KEY (id, ts), @@ -161,7 +167,7 @@ CREATE TABLE event_logs_raw ( msg_sha256 CHAR(64) NOT NULL, msg LONGBLOB NOT NULL, is_gzip TINYINT(1) NOT NULL DEFAULT 0, - created_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id, ts), @@ -181,7 +187,7 @@ PARTITION BY RANGE COLUMNS(ts) ( CREATE TABLE detection_rules ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, + name VARCHAR(191) NOT NULL, description TEXT NULL, severity ENUM('info','low','medium','high','critical') NOT NULL DEFAULT 'medium', channel VARCHAR(512) NOT NULL DEFAULT 'Security', @@ -196,8 +202,8 @@ CREATE TABLE detection_rules ( suppress_for_seconds INT NOT NULL DEFAULT 3600, enabled TINYINT(1) NOT NULL DEFAULT 1, - created_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - updated_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)) ON UPDATE UTC_TIMESTAMP(6), + created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uq_detection_rules_name (name), @@ -210,9 +216,9 @@ CREATE TABLE detection_rules ( CREATE TABLE detections ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - rule_name VARCHAR(255) NOT NULL, + rule_name VARCHAR(191) NOT NULL, severity ENUM('info','low','medium','high','critical') NOT NULL DEFAULT 'medium', - hostname VARCHAR(255) NOT NULL DEFAULT '', + hostname VARCHAR(191) NOT NULL DEFAULT '', channel_name VARCHAR(128) NOT NULL DEFAULT '', event_id INT UNSIGNED NOT NULL DEFAULT 0, score DOUBLE NOT NULL DEFAULT 0, @@ -221,7 +227,7 @@ CREATE TABLE detections ( window_end DATETIME(6) NOT NULL, summary TEXT NOT NULL, - details_json JSON NULL, + details_json LONGTEXT NULL CHECK (JSON_VALID(details_json)), status ENUM( 'open', @@ -236,12 +242,12 @@ CREATE TABLE detections ( ) NOT NULL DEFAULT 'open', analyst_note TEXT NULL, - reviewed_by VARCHAR(255) NOT NULL DEFAULT '', + reviewed_by VARCHAR(191) NOT NULL DEFAULT '', reviewed_at DATETIME(6) NULL, is_false_positive TINYINT(1) NOT NULL DEFAULT 0, is_legitimate TINYINT(1) NOT NULL DEFAULT 0, - created_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id), @@ -284,14 +290,14 @@ CREATE TABLE detections ( CREATE TABLE detection_suppressions ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - rule_name VARCHAR(255) NOT NULL, - hostname VARCHAR(255) NOT NULL DEFAULT '', + rule_name VARCHAR(191) NOT NULL, + hostname VARCHAR(191) NOT NULL DEFAULT '', channel_name VARCHAR(128) NOT NULL DEFAULT '', event_id INT UNSIGNED NOT NULL DEFAULT 0, reason TEXT NULL, - created_by VARCHAR(255) NOT NULL DEFAULT '', - created_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + created_by VARCHAR(191) NOT NULL DEFAULT '', + created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), expires_at DATETIME(6) NULL, enabled TINYINT(1) NOT NULL DEFAULT 1, @@ -315,7 +321,7 @@ CREATE TABLE event_count_buckets ( bucket_start DATETIME(6) NOT NULL, bucket_end DATETIME(6) NOT NULL, - hostname VARCHAR(255) NOT NULL, + hostname VARCHAR(191) NOT NULL, channel_name VARCHAR(128) NOT NULL, event_id INT UNSIGNED NOT NULL, @@ -328,7 +334,7 @@ CREATE TABLE event_count_buckets ( anomaly_checked_at DATETIME(6) NULL, learned_at DATETIME(6) NULL, - updated_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)) ON UPDATE UTC_TIMESTAMP(6), + updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (bucket_start, hostname, channel_name, event_id), @@ -362,7 +368,7 @@ CREATE TABLE event_count_buckets ( -- --------------------------------------------------------------------- CREATE TABLE baseline_event_stats ( - hostname VARCHAR(255) NOT NULL, + hostname VARCHAR(191) NOT NULL, channel_name VARCHAR(128) NOT NULL, event_id INT UNSIGNED NOT NULL, hour_of_day TINYINT UNSIGNED NOT NULL, @@ -373,8 +379,8 @@ CREATE TABLE baseline_event_stats ( stddev_count DOUBLE NOT NULL DEFAULT 0, sample_count INT NOT NULL DEFAULT 0, - first_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - last_updated DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)) ON UPDATE UTC_TIMESTAMP(6), + first_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + last_updated DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY ( hostname, @@ -396,13 +402,13 @@ CREATE TABLE baseline_event_stats ( CREATE TABLE baseline_exclusions ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - hostname VARCHAR(255) NOT NULL DEFAULT '', + hostname VARCHAR(191) NOT NULL DEFAULT '', channel_name VARCHAR(128) NOT NULL DEFAULT '', event_id INT UNSIGNED NOT NULL DEFAULT 0, reason TEXT NULL, - created_by VARCHAR(255) NOT NULL DEFAULT '', - created_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + created_by VARCHAR(191) NOT NULL DEFAULT '', + created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), expires_at DATETIME(6) NULL, enabled TINYINT(1) NOT NULL DEFAULT 1, @@ -423,13 +429,13 @@ CREATE TABLE baseline_exclusions ( -- --------------------------------------------------------------------- CREATE TABLE ueba_user_baseline ( - username VARCHAR(255) NOT NULL, - hostname VARCHAR(255) NOT NULL, + username VARCHAR(191) NOT NULL, + hostname VARCHAR(191) NOT NULL, src_ip VARCHAR(64) NOT NULL, - workstation VARCHAR(255) NOT NULL, + workstation VARCHAR(191) NOT NULL, - first_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - last_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + first_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + last_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), seen_count BIGINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (username, hostname, src_ip, workstation), @@ -440,12 +446,12 @@ CREATE TABLE ueba_user_baseline ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE user_source_ip_seen ( - username VARCHAR(255) NOT NULL, + username VARCHAR(191) NOT NULL, src_ip VARCHAR(64) NOT NULL, - hostname VARCHAR(255) NOT NULL, + hostname VARCHAR(191) NOT NULL, - first_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - last_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + first_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + last_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), seen_count BIGINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (username, src_ip, hostname), @@ -456,10 +462,10 @@ CREATE TABLE user_source_ip_seen ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE user_privilege_baseline ( - username VARCHAR(255) NOT NULL, + username VARCHAR(191) NOT NULL, - first_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - last_seen DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), + first_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + last_seen DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), seen_count BIGINT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (username), @@ -470,10 +476,10 @@ CREATE TABLE ueba_context_buckets ( bucket_start DATETIME(6) NOT NULL, bucket_end DATETIME(6) NOT NULL, - username VARCHAR(255) NOT NULL, - hostname VARCHAR(255) NOT NULL, + username VARCHAR(191) NOT NULL, + hostname VARCHAR(191) NOT NULL, src_ip VARCHAR(64) NOT NULL, - workstation VARCHAR(255) NOT NULL, + workstation VARCHAR(191) NOT NULL, cnt BIGINT UNSIGNED NOT NULL DEFAULT 0, first_event_ts DATETIME(6) NULL, @@ -483,7 +489,7 @@ CREATE TABLE ueba_context_buckets ( checked_at DATETIME(6) NULL, learned_at DATETIME(6) NULL, - updated_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)) ON UPDATE UTC_TIMESTAMP(6), + updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY ( bucket_start, @@ -519,11 +525,11 @@ CREATE TABLE ueba_context_buckets ( -- --------------------------------------------------------------------- CREATE TABLE privileged_users ( - username VARCHAR(255) NOT NULL, + username VARCHAR(191) NOT NULL, reason TEXT NULL, enabled TINYINT(1) NOT NULL DEFAULT 1, - created_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)), - updated_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)) ON UPDATE UTC_TIMESTAMP(6), + created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (username), KEY idx_privileged_users_enabled (enabled) @@ -534,7 +540,7 @@ CREATE TABLE privileged_users ( -- --------------------------------------------------------------------- CREATE TABLE host_risk_scores ( - hostname VARCHAR(255) NOT NULL, + hostname VARCHAR(191) NOT NULL, risk_score DOUBLE NOT NULL DEFAULT 0, severity ENUM('info','low','medium','high','critical') NOT NULL DEFAULT 'info', @@ -544,7 +550,7 @@ CREATE TABLE host_risk_scores ( confirmed_incidents INT NOT NULL DEFAULT 0, last_detection_at DATETIME(6) NULL, - updated_at DATETIME(6) NOT NULL DEFAULT (UTC_TIMESTAMP(6)) ON UPDATE UTC_TIMESTAMP(6), + updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (hostname), KEY idx_host_risk_scores_risk (risk_score), @@ -554,10 +560,9 @@ CREATE TABLE host_risk_scores ( -- --------------------------------------------------------------------- -- Partition Management Stored Procedure +-- Erzeugt 3h-Partitionen von UTC now - 6h bis UTC now + 24h. -- --------------------------------------------------------------------- -DROP PROCEDURE IF EXISTS ensure_siem_partitions; - DELIMITER $$ CREATE PROCEDURE ensure_siem_partitions() @@ -569,7 +574,6 @@ BEGIN DECLARE v_part_name VARCHAR(32); DECLARE v_exists INT DEFAULT 0; - -- UTC now auf 3-Stunden-Grenze abrunden. SET v_start = FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(UTC_TIMESTAMP()) / 10800) * 10800); SET v_start = DATE_SUB(v_start, INTERVAL 6 HOUR); SET v_end = DATE_ADD(FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(UTC_TIMESTAMP()) / 10800) * 10800), INTERVAL 27 HOUR); @@ -580,7 +584,6 @@ BEGIN SET v_part_end = DATE_ADD(v_current, INTERVAL 3 HOUR); SET v_part_name = CONCAT('p', DATE_FORMAT(v_current, '%Y%m%d%H')); - -- event_logs SELECT COUNT(*) INTO v_exists FROM information_schema.PARTITIONS @@ -600,7 +603,6 @@ BEGIN DEALLOCATE PREPARE stmt_event_logs; END IF; - -- event_logs_raw SELECT COUNT(*) INTO v_exists FROM information_schema.PARTITIONS @@ -627,7 +629,6 @@ END$$ DELIMITER ; CALL ensure_siem_partitions(); - -- --------------------------------------------------------------------- -- Initiale Beispielregeln -- Optional. Kann gelöscht werden, wenn Regeln nur über UI gepflegt werden sollen.