Schema cleanup:
- Remove anubis_ua_rules table stub from 03_anubis_tables.sql
- Remove anubis_ua_rules from bot-detector deploy_schema.sql
- Remove UA seed step from clickhouse-init.sh (no more REGEXP_TREE dependency)
- Drop dict_anubis_ua, dict_anubis_country, anubis_ua_rules, anubis_country_rules
New scripts:
- scripts/init-stack.sh: comprehensive ClickHouse init (13 SQL files + migrations
+ validation + cleanup of obsolete tables). Supports --reset, --import-prod.
- scripts/import-prod-data.sh: imports pre-exported prod data (Native format)
with dynamic date shift (max(time) → now). Supports --shift, --no-truncate.
- scripts/data/prod-export/: directory for cached Native format exports
Makefile targets: init-stack, import-prod-data, init-and-import
Tested: init-stack.sh passes all 13 SQL + 7 critical tables + 7 dicts
import-prod-data.sh: 3M rows in ~37s with auto date shift
Dashboard: 55 routes OK, bot-detector: 36/36 tests pass
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
108 lines
4.9 KiB
SQL
108 lines
4.9 KiB
SQL
-- ============================================================================
|
|
-- ANUBIS CRAWLER RULES — Labeling des http_logs + pipeline ML
|
|
-- Architecture simplifiée (IP/CIDR et ASN uniquement) :
|
|
-- anubis_ip_rules (table) → dict_anubis_ip (IP_TRIE)
|
|
-- anubis_asn_rules (table) → dict_anubis_asn (FLAT)
|
|
-- http_logs : +anubis_bot_name, +anubis_bot_action, +anubis_bot_category
|
|
-- mv_http_logs : enrichissement Anubis (IP > ASN)
|
|
-- view_ai_features_1h : +anubis_bot_name, +anubis_bot_action (via dictGet)
|
|
-- ml_detected_anomalies / ml_all_scores : colonnes Anubis
|
|
-- ============================================================================
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 1. TABLE SOURCE — règles IP/CIDR (pour dictionnaire IP_TRIE)
|
|
-- Peuplée par fetch_rules.py depuis les fichiers YAML Anubis.
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS ja4_processing.anubis_ip_rules
|
|
(
|
|
prefix String,
|
|
bot_name LowCardinality(String),
|
|
action LowCardinality(String),
|
|
rule_id UInt64,
|
|
has_ua UInt8,
|
|
category LowCardinality(String)
|
|
)
|
|
ENGINE = ReplacingMergeTree()
|
|
ORDER BY prefix;
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 3. TABLE SOURCE — règles ASN (pour dictionnaire Flat)
|
|
-- Peuplée par fetch_rules.py depuis botPolicies.yaml.
|
|
-- ----------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS ja4_processing.anubis_asn_rules
|
|
(
|
|
asn UInt32,
|
|
bot_name LowCardinality(String),
|
|
action LowCardinality(String),
|
|
category LowCardinality(String)
|
|
)
|
|
ENGINE = ReplacingMergeTree()
|
|
ORDER BY asn;
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 4. DICTIONNAIRE IP — IP_TRIE (actif)
|
|
-- ----------------------------------------------------------------------------
|
|
DROP DICTIONARY IF EXISTS ja4_processing.dict_anubis_ip;
|
|
CREATE DICTIONARY ja4_processing.dict_anubis_ip
|
|
(
|
|
prefix String,
|
|
bot_name String,
|
|
action String,
|
|
rule_id UInt64,
|
|
has_ua UInt8,
|
|
category String
|
|
)
|
|
PRIMARY KEY prefix
|
|
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'admin' PASSWORD 'CHANGE_ME' DB 'ja4_processing' TABLE 'anubis_ip_rules'))
|
|
LAYOUT(IP_TRIE())
|
|
LIFETIME(MIN 300 MAX 600);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 5. DICTIONNAIRE ASN — Flat (actif)
|
|
-- ----------------------------------------------------------------------------
|
|
DROP DICTIONARY IF EXISTS ja4_processing.dict_anubis_asn;
|
|
CREATE DICTIONARY ja4_processing.dict_anubis_asn
|
|
(
|
|
asn UInt32,
|
|
bot_name String,
|
|
action String,
|
|
category String
|
|
)
|
|
PRIMARY KEY asn
|
|
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'admin' PASSWORD 'CHANGE_ME' DB 'ja4_processing' TABLE 'anubis_asn_rules'))
|
|
LAYOUT(FLAT())
|
|
LIFETIME(MIN 300 MAX 600);
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 6. AJOUT DES COLONNES ANUBIS dans http_logs (idempotent)
|
|
-- ----------------------------------------------------------------------------
|
|
ALTER TABLE ja4_logs.http_logs
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_name LowCardinality(String) DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_action LowCardinality(String) DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_category LowCardinality(String) DEFAULT '';
|
|
|
|
-- ============================================================================
|
|
-- INTÉGRATION ML — Propagation Anubis vers le pipeline bot_detector
|
|
-- ============================================================================
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 7. COLONNES ANUBIS dans ml_detected_anomalies
|
|
-- ----------------------------------------------------------------------------
|
|
ALTER TABLE ja4_processing.ml_detected_anomalies
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_name LowCardinality(String) DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_action LowCardinality(String) DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_category LowCardinality(String) DEFAULT '';
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 8. COLONNES ANUBIS dans ml_all_scores
|
|
-- ----------------------------------------------------------------------------
|
|
ALTER TABLE ja4_processing.ml_all_scores
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_name LowCardinality(String) DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_action LowCardinality(String) DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS anubis_bot_category LowCardinality(String) DEFAULT '';
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- 9. VIEW view_ai_features_1h — Enrichissement Anubis
|
|
-- Voir view_ai_features_anubis.sql pour le CREATE OR REPLACE VIEW complet.
|
|
-- ----------------------------------------------------------------------------
|