docs: Mise à jour README + suppression fichiers temporaires
- README.md: Ajout des nouvelles fonctionnalités - Investigation Subnet /24 - Réputation IP (IP-API + IPinfo) - Liste complète des endpoints API - Exemples de requêtes curl - Suppression fichiers temporaires: - update_retention_policy.sql (script temporaire) - ML_DETECTED_ANOMALIES_CONFIG.md (debug) - RETENTION_POLICY.md (debug) - Conservation des fichiers de déploiement: - deploy_dashboard_entities_view.sql - deploy_user_agents_view.sql - deploy_audit_logs_table.sql - create_classifications_table.sql Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -1,300 +0,0 @@
|
|||||||
# 🔍 Configuration de `ml_detected_anomalies`
|
|
||||||
|
|
||||||
## 📊 Structure de la table
|
|
||||||
|
|
||||||
**Requête:** `SHOW CREATE TABLE mabase_prod.ml_detected_anomalies`
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE mabase_prod.ml_detected_anomalies
|
|
||||||
(
|
|
||||||
`detected_at` DateTime,
|
|
||||||
`src_ip` IPv6,
|
|
||||||
`ja4` String,
|
|
||||||
`host` String,
|
|
||||||
`bot_name` String,
|
|
||||||
`anomaly_score` Float32,
|
|
||||||
`threat_level` String,
|
|
||||||
`model_name` String,
|
|
||||||
`recurrence` UInt32,
|
|
||||||
`asn_number` String,
|
|
||||||
`asn_org` String,
|
|
||||||
`asn_detail` String,
|
|
||||||
`asn_domain` String,
|
|
||||||
`country_code` String,
|
|
||||||
`asn_label` String,
|
|
||||||
`hits` UInt64,
|
|
||||||
`hit_velocity` Float32,
|
|
||||||
`fuzzing_index` Float32,
|
|
||||||
`post_ratio` Float32,
|
|
||||||
`port_exhaustion_ratio` Float32,
|
|
||||||
`max_keepalives` UInt32,
|
|
||||||
`orphan_ratio` Float32,
|
|
||||||
`tcp_jitter_variance` Float32,
|
|
||||||
`tcp_shared_count` UInt32,
|
|
||||||
`true_window_size` UInt64,
|
|
||||||
`window_mss_ratio` Float32,
|
|
||||||
`alpn_http_mismatch` UInt8,
|
|
||||||
`is_alpn_missing` UInt8,
|
|
||||||
`sni_host_mismatch` UInt8,
|
|
||||||
`header_count` UInt16,
|
|
||||||
`has_accept_language` UInt8,
|
|
||||||
`has_cookie` UInt8,
|
|
||||||
`has_referer` UInt8,
|
|
||||||
`modern_browser_score` UInt8,
|
|
||||||
`is_headless` UInt8,
|
|
||||||
`ua_ch_mismatch` UInt8,
|
|
||||||
`header_order_shared_count` UInt32,
|
|
||||||
`ip_id_zero_ratio` Float32,
|
|
||||||
`request_size_variance` Float32,
|
|
||||||
`multiplexing_efficiency` Float32,
|
|
||||||
`mss_mobile_mismatch` UInt8,
|
|
||||||
`correlated` UInt8,
|
|
||||||
`reason` String,
|
|
||||||
`asset_ratio` Float32,
|
|
||||||
`direct_access_ratio` Float32,
|
|
||||||
`is_ua_rotating` UInt8,
|
|
||||||
`distinct_ja4_count` UInt32,
|
|
||||||
`src_port_density` Float32,
|
|
||||||
`ja4_asn_concentration` Float32,
|
|
||||||
`ja4_country_concentration` Float32,
|
|
||||||
`is_rare_ja4` UInt8,
|
|
||||||
`header_order_confidence` Float32,
|
|
||||||
`distinct_header_orders` UInt32,
|
|
||||||
`temporal_entropy` Float32,
|
|
||||||
`path_diversity_ratio` Float32,
|
|
||||||
`url_depth_variance` Float32,
|
|
||||||
`anomalous_payload_ratio` Float32
|
|
||||||
)
|
|
||||||
ENGINE = ReplacingMergeTree(detected_at)
|
|
||||||
ORDER BY src_ip
|
|
||||||
TTL detected_at + toIntervalDay(30)
|
|
||||||
SETTINGS index_granularity = 8192
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚙️ Configuration détaillée
|
|
||||||
|
|
||||||
### 1. **Moteur de stockage**
|
|
||||||
```
|
|
||||||
ENGINE = ReplacingMergeTree(detected_at)
|
|
||||||
```
|
|
||||||
- **Type:** `ReplacingMergeTree`
|
|
||||||
- **Version column:** `detected_at`
|
|
||||||
- **Comportement:** Garde la dernière version des lignes dupliquées lors des merges
|
|
||||||
|
|
||||||
### 2. **Clé de tri (ORDER BY)**
|
|
||||||
```
|
|
||||||
ORDER BY src_ip
|
|
||||||
```
|
|
||||||
- **Clé primaire:** `src_ip` (IPv6)
|
|
||||||
- **Optimisation:** Les requêtes par IP sont très rapides
|
|
||||||
- **Impact:** Les requêtes par date (`detected_at`) nécessitent un scan complet
|
|
||||||
|
|
||||||
### 3. **Politique de rétention (TTL)**
|
|
||||||
```
|
|
||||||
TTL detected_at + toIntervalDay(30)
|
|
||||||
```
|
|
||||||
- **Durée actuelle:** **30 jours**
|
|
||||||
- **Comportement:** Les lignes sont supprimées 30 jours après `detected_at`
|
|
||||||
- **Application:** Automatique pendant les opérations de merge
|
|
||||||
|
|
||||||
### 4. **Partitionnement**
|
|
||||||
```
|
|
||||||
-- Aucun partitionnement explicite
|
|
||||||
```
|
|
||||||
- **Statut:** **Non partitionnée** (tuple())
|
|
||||||
- **Impact:** Toutes les données dans une seule partition
|
|
||||||
- **Conséquence:**
|
|
||||||
- ✅ Requêtes plus simples
|
|
||||||
- ❌ OPTIMIZE FINAL plus lent sur grandes tables
|
|
||||||
- ❌ Impossible de DROPper une partition ancienne
|
|
||||||
|
|
||||||
### 5. **Index**
|
|
||||||
```
|
|
||||||
SETTINGS index_granularity = 8192
|
|
||||||
```
|
|
||||||
- **Granularité:** 8192 lignes par marque d'index
|
|
||||||
- **Standard:** Valeur par défaut de ClickHouse
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 Statistiques actuelles
|
|
||||||
|
|
||||||
**Requête:** `SELECT count(), min(detected_at), max(detected_at) FROM ml_detected_anomalies`
|
|
||||||
|
|
||||||
| Métrique | Valeur |
|
|
||||||
|----------|--------|
|
|
||||||
| **Total lignes** | 57,338 |
|
|
||||||
| **Donnée la plus ancienne** | 2026-03-13 20:30:19 |
|
|
||||||
| **Donnée la plus récente** | 2026-03-15 17:57:10 |
|
|
||||||
| **Période couverte** | ~2 jours |
|
|
||||||
| **TTL actuel** | 30 jours |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔍 Analyse du problème: 212.30.36.0/24
|
|
||||||
|
|
||||||
### Incident dans `api/incidents/clusters`
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"subnet": "212.30.36.0/24",
|
|
||||||
"unique_ips": 10,
|
|
||||||
"total_detections": 10,
|
|
||||||
"first_seen": "2026-03-15T03:55:28",
|
|
||||||
"last_seen": "2026-03-15T03:55:28"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Données dans `ml_detected_anomalies`
|
|
||||||
- **Âge:** ~15 heures (bien dans les 30 jours)
|
|
||||||
- **Statut:** **Devrait être présent** ✅
|
|
||||||
|
|
||||||
### Pourquoi "Subnet non trouvé" ?
|
|
||||||
|
|
||||||
**Hypothèses:**
|
|
||||||
|
|
||||||
1. **IPv6 vs IPv4** ⚠️
|
|
||||||
- La table stocke `src_ip` en **IPv6**
|
|
||||||
- Les IPs IPv4 sont stockées comme `::ffff:x.x.x.x`
|
|
||||||
- Notre requête utilise `replaceRegexpAll(toString(src_ip), '^::ffff:', '')`
|
|
||||||
- **Vérifier:** Est-ce que le nettoyage IPv4 fonctionne correctement ?
|
|
||||||
|
|
||||||
2. **ReplacingMergeTree** ⚠️
|
|
||||||
- Les lignes marquées pour suppression peuvent encore être visibles
|
|
||||||
- **Vérifier:** Y a-t-il des lignes dupliquées avec `detected_at` différents ?
|
|
||||||
|
|
||||||
3. **Données réellement absentes** ❌
|
|
||||||
- Les 10 détections de `212.30.36.0/24` ont été supprimées
|
|
||||||
- **Cause possible:** Bug dans bot_detector_ai ou nettoyage prématuré
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Tests de diagnostic
|
|
||||||
|
|
||||||
### Test 1: Vérifier format IPv4
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT
|
|
||||||
src_ip,
|
|
||||||
toString(src_ip) AS ip_string,
|
|
||||||
replaceRegexpAll(toString(src_ip), '^::ffff:', '') AS clean_ip
|
|
||||||
FROM mabase_prod.ml_detected_anomalies
|
|
||||||
WHERE detected_at >= now() - INTERVAL 1 HOUR
|
|
||||||
LIMIT 10;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 2: Chercher le subnet spécifique
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT
|
|
||||||
count(),
|
|
||||||
min(detected_at),
|
|
||||||
max(detected_at)
|
|
||||||
FROM mabase_prod.ml_detected_anomalies
|
|
||||||
WHERE
|
|
||||||
detected_at >= now() - INTERVAL 30 DAY
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[1] = '212'
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[2] = '30'
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[3] = '36';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 3: Vérifier les IPs du subnet
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT
|
|
||||||
replaceRegexpAll(toString(src_ip), '^::ffff:', '') AS clean_ip,
|
|
||||||
count() AS detections,
|
|
||||||
min(detected_at) AS first_seen,
|
|
||||||
max(detected_at) AS last_seen
|
|
||||||
FROM mabase_prod.ml_detected_anomalies
|
|
||||||
WHERE
|
|
||||||
detected_at >= now() - INTERVAL 30 DAY
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[1] = '212'
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[2] = '30'
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[3] = '36'
|
|
||||||
GROUP BY clean_ip
|
|
||||||
ORDER BY detections DESC
|
|
||||||
LIMIT 20;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Recommandations
|
|
||||||
|
|
||||||
### 1. **Augmenter la rétention** (déjà documenté)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Passer de 30 à 90 jours
|
|
||||||
ALTER TABLE mabase_prod.ml_detected_anomalies
|
|
||||||
MODIFY TTL detected_at + INTERVAL 90 DAY;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. **Ajouter le partitionnement** (optionnel)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Recréer la table avec partitionnement mensuel
|
|
||||||
CREATE TABLE mabase_prod.ml_detected_anomalies_new
|
|
||||||
(
|
|
||||||
-- ... mêmes colonnes ...
|
|
||||||
)
|
|
||||||
ENGINE = ReplacingMergeTree(detected_at)
|
|
||||||
PARTITION BY toYYYYMM(detected_at) -- Partition par mois
|
|
||||||
ORDER BY src_ip
|
|
||||||
TTL detected_at + INTERVAL 90 DAY
|
|
||||||
SETTINGS index_granularity = 8192;
|
|
||||||
|
|
||||||
-- Migrer les données
|
|
||||||
INSERT INTO ml_detected_anomalies_new SELECT * FROM ml_detected_anomalies;
|
|
||||||
|
|
||||||
-- Renommer
|
|
||||||
RENAME TABLE ml_detected_anomalies TO ml_detected_anomalies_old,
|
|
||||||
ml_detected_anomalies_new TO ml_detected_anomalies;
|
|
||||||
|
|
||||||
-- Drop l'ancienne table après vérification
|
|
||||||
DROP TABLE ml_detected_anomalies_old;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. **Ajouter un index sur detected_at** (optionnel)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Ajouter un index secondaire pour les requêtes temporelles
|
|
||||||
ALTER TABLE mabase_prod.ml_detected_anomalies
|
|
||||||
ADD INDEX idx_detected_at detected_at TYPE minmax GRANULARITY 8192;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. **Corriger le bug 212.30.36.0/24**
|
|
||||||
|
|
||||||
**Action immédiate:**
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Vérifier si les données existent
|
|
||||||
SELECT count()
|
|
||||||
FROM mabase_prod.ml_detected_anomalies
|
|
||||||
WHERE
|
|
||||||
detected_at >= toDateTime('2026-03-15 03:00:00')
|
|
||||||
AND detected_at <= toDateTime('2026-03-15 05:00:00')
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[1] = '212'
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[2] = '30'
|
|
||||||
AND splitByChar('.', replaceRegexpAll(toString(src_ip), '^::ffff:', ''))[3] = '36';
|
|
||||||
```
|
|
||||||
|
|
||||||
**Si count = 0:** Les données ont été supprimées prématurément (bug bot_detector_ai)
|
|
||||||
|
|
||||||
**Si count > 0:** Il y a un bug dans la requête SQL de l'API subnet
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Fichiers à modifier
|
|
||||||
|
|
||||||
| Fichier | Modification | Statut |
|
|
||||||
|---------|--------------|--------|
|
|
||||||
| `deploy_dashboard_entities_view.sql` | TTL: 30 → 90 jours | ✅ Fait |
|
|
||||||
| `deploy_user_agents_view.sql` | TTL: 7 → 90 jours | ✅ Fait |
|
|
||||||
| `update_retention_policy.sql` | Script d'application | ✅ Créé |
|
|
||||||
| `ml_detected_anomalies` | TTL: 30 → 90 jours | ⏳ À appliquer |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Dernière mise à jour:** 2026-03-15
|
|
||||||
**Version:** 1.0
|
|
||||||
44
README.md
44
README.md
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
Dashboard web interactif pour visualiser et investiguer les décisions de classification du Bot Detector IA.
|
Dashboard web interactif pour visualiser et investiguer les décisions de classification du Bot Detector IA.
|
||||||
|
|
||||||
|
**Version:** 1.7.0 - Subnet Investigation + IP Reputation
|
||||||
|
|
||||||
## 🚀 Démarrage Rapide
|
## 🚀 Démarrage Rapide
|
||||||
|
|
||||||
### Prérequis
|
### Prérequis
|
||||||
@ -9,6 +11,7 @@ Dashboard web interactif pour visualiser et investiguer les décisions de classi
|
|||||||
- Docker et Docker Compose
|
- Docker et Docker Compose
|
||||||
- Le service `clickhouse` déjà déployé
|
- Le service `clickhouse` déjà déployé
|
||||||
- Des données dans la table `ml_detected_anomalies`
|
- Des données dans la table `ml_detected_anomalies`
|
||||||
|
- Des données dans la table `http_logs` (pour les user-agents)
|
||||||
|
|
||||||
> **Note:** Le dashboard peut fonctionner indépendamment de `bot_detector_ai`. Il lit les données déjà détectées dans ClickHouse.
|
> **Note:** Le dashboard peut fonctionner indépendamment de `bot_detector_ai`. Il lit les données déjà détectées dans ClickHouse.
|
||||||
|
|
||||||
@ -50,11 +53,25 @@ docker compose logs -f dashboard_web
|
|||||||
- **Métriques en temps réel** : Total détections, menaces, bots connus, IPs uniques
|
- **Métriques en temps réel** : Total détections, menaces, bots connus, IPs uniques
|
||||||
- **Répartition par menace** : Visualisation CRITICAL/HIGH/MEDIUM/LOW
|
- **Répartition par menace** : Visualisation CRITICAL/HIGH/MEDIUM/LOW
|
||||||
- **Évolution temporelle** : Graphique des détections sur 24h
|
- **Évolution temporelle** : Graphique des détections sur 24h
|
||||||
|
- **Incidents clusterisés** : Regroupement automatique par subnet /24
|
||||||
|
- **Top Menaces Actives** : Top 10 des IPs les plus dangereuses
|
||||||
|
|
||||||
### Liste des Détections
|
### Investigation Subnet /24 (NOUVEAU)
|
||||||
- **Tableau interactif** : Tri, pagination, filtres
|
- **URL:** `/entities/subnet/x.x.x.x_24` (ex: `/entities/subnet/141.98.11.0_24`)
|
||||||
- **Recherche** : Par IP, JA4, Host
|
- **Stats globales** : Total IPs, détections, JA4 uniques, User-Agents uniques, Hosts
|
||||||
- **Filtres** : Par niveau de menace, modèle, pays, ASN
|
- **Tableau des IPs** : Toutes les IPs du subnet avec leurs statistiques
|
||||||
|
- **Actions par IP** : Investiguer, Voir détails
|
||||||
|
- **Sources** : `ml_detected_anomalies` (détections) + `view_dashboard_entities` (user-agents)
|
||||||
|
|
||||||
|
### Investigation IP + Réputation (NOUVEAU)
|
||||||
|
- **URL:** `/investigation/:ip`
|
||||||
|
- **Panel Réputation IP** :
|
||||||
|
- Score de menace 0-100
|
||||||
|
- Niveau: clean/low/medium/high/critical
|
||||||
|
- Détection: Proxy, Hosting, VPN, Tor
|
||||||
|
- Géolocalisation: Pays, Ville
|
||||||
|
- ASN + Organisation
|
||||||
|
- **Sources** : IP-API.com + IPinfo.io (sans clé API)
|
||||||
|
|
||||||
### Investigation (Variabilité)
|
### Investigation (Variabilité)
|
||||||
- **Vue détails** : Cliquez sur une IP/JA4/pays/ASN pour investiguer
|
- **Vue détails** : Cliquez sur une IP/JA4/pays/ASN pour investiguer
|
||||||
@ -134,6 +151,16 @@ dashboard/
|
|||||||
| GET | `/api/detections/{id}` | Détails d'une détection |
|
| GET | `/api/detections/{id}` | Détails d'une détection |
|
||||||
| GET | `/api/variability/{type}/{value}` | Variabilité d'un attribut |
|
| GET | `/api/variability/{type}/{value}` | Variabilité d'un attribut |
|
||||||
| GET | `/api/attributes/{type}` | Liste des valeurs uniques |
|
| GET | `/api/attributes/{type}` | Liste des valeurs uniques |
|
||||||
|
| GET | `/api/incidents/clusters` | Incidents clusterisés par subnet /24 |
|
||||||
|
| GET | `/api/entities/subnet/{subnet}` | Investigation subnet (ex: `141.98.11.0/24`) |
|
||||||
|
| GET | `/api/entities/{type}/{value}` | Investigation entité (IP, JA4, UA, etc.) |
|
||||||
|
| GET | `/api/reputation/ip/{ip}` | Réputation IP (IP-API + IPinfo) |
|
||||||
|
| GET | `/api/analysis/{ip}/subnet` | Analyse subnet / ASN |
|
||||||
|
| GET | `/api/analysis/{ip}/country` | Analyse pays |
|
||||||
|
| GET | `/api/analysis/{ip}/ja4` | Analyse JA4 |
|
||||||
|
| GET | `/api/analysis/{ip}/user-agents` | Analyse User-Agents |
|
||||||
|
| GET | `/api/analysis/{ip}/recommendation` | Recommandation de classification |
|
||||||
|
| POST | `/api/analysis/classifications` | Sauvegarder classification SOC |
|
||||||
| GET | `/health` | Health check |
|
| GET | `/health` | Health check |
|
||||||
|
|
||||||
### Exemples
|
### Exemples
|
||||||
@ -148,6 +175,15 @@ curl "http://localhost:3000/api/detections?threat_level=CRITICAL&page=1"
|
|||||||
# Variabilité d'une IP
|
# Variabilité d'une IP
|
||||||
curl http://localhost:3000/api/variability/ip/192.168.1.100
|
curl http://localhost:3000/api/variability/ip/192.168.1.100
|
||||||
|
|
||||||
|
# Investigation subnet (URL encode / en _24)
|
||||||
|
curl "http://localhost:3000/api/entities/subnet/141.98.11.0_24?hours=24"
|
||||||
|
|
||||||
|
# Réputation IP
|
||||||
|
curl http://localhost:3000/api/reputation/ip/141.98.11.209
|
||||||
|
|
||||||
|
# Incidents clusterisés
|
||||||
|
curl http://localhost:3000/api/incidents/clusters?limit=20
|
||||||
|
|
||||||
# Liste des pays
|
# Liste des pays
|
||||||
curl http://localhost:3000/api/attributes/country
|
curl http://localhost:3000/api/attributes/country
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,243 +0,0 @@
|
|||||||
# 📅 Modification de la Politique de Rétention
|
|
||||||
|
|
||||||
## 🎯 Objectif
|
|
||||||
|
|
||||||
Augmenter la durée de conservation des données dans ClickHouse pour pouvoir investiguer des incidents plus anciens.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Durées de rétention actuelles
|
|
||||||
|
|
||||||
| Table / Vue | Ancien TTL | Nouveau TTL | Fichier |
|
|
||||||
|-------------|------------|-------------|---------|
|
|
||||||
| `view_dashboard_entities` | 30 jours | **90 jours** | `deploy_dashboard_entities_view.sql` |
|
|
||||||
| `view_dashboard_user_agents` | 7 jours | **90 jours** | `deploy_user_agents_view.sql` |
|
|
||||||
| `audit_logs` | 90 jours | 90 jours | `deploy_audit_logs_table.sql` |
|
|
||||||
| `ml_detected_anomalies` | ~1-6h* | **30 jours** (recommandé) | `bot_detector_ai` |
|
|
||||||
|
|
||||||
*La table `ml_detected_anomalies` est gérée par le service `bot_detector_ai`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Méthode 1: Appliquer sur tables existantes (RECOMMANDÉ)
|
|
||||||
|
|
||||||
### Étape 1: Exécuter le script SQL
|
|
||||||
|
|
||||||
```bash
|
|
||||||
clickhouse-client --host test-sdv-anubis.sdv.fr --port 8123 \
|
|
||||||
--user admin --password SuperPassword123! \
|
|
||||||
< update_retention_policy.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 2: Vérifier les modifications
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT
|
|
||||||
name,
|
|
||||||
engine,
|
|
||||||
create_table_query
|
|
||||||
FROM system.tables
|
|
||||||
WHERE database = 'mabase_prod'
|
|
||||||
AND name LIKE 'view_dashboard%'
|
|
||||||
FORMAT Vertical;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 3: (Optionnel) Forcer l'application du TTL
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Attention: Peut prendre plusieurs minutes
|
|
||||||
OPTIMIZE TABLE mabase_prod.view_dashboard_entities FINAL;
|
|
||||||
OPTIMIZE TABLE mabase_prod.view_dashboard_user_agents FINAL;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Méthode 2: Recréer les tables avec le nouveau TTL
|
|
||||||
|
|
||||||
### Pour `view_dashboard_entities`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
clickhouse-client --host test-sdv-anubis.sdv.fr --port 8123 \
|
|
||||||
--user admin --password SuperPassword123! \
|
|
||||||
--database mabase_prod \
|
|
||||||
< deploy_dashboard_entities_view.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pour `view_dashboard_user_agents`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
clickhouse-client --host test-sdv-anubis.sdv.fr --port 8123 \
|
|
||||||
--user admin --password SuperPassword123! \
|
|
||||||
--database mabase_prod \
|
|
||||||
< deploy_user_agents_view.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Méthode 3: Modifier `ml_detected_anomalies`
|
|
||||||
|
|
||||||
Cette table est gérée par le service `bot_detector_ai`. Deux options :
|
|
||||||
|
|
||||||
### Option A: Modification directe (si accès)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Vérifier le TTL actuel
|
|
||||||
SHOW CREATE TABLE mabase_prod.ml_detected_anomalies;
|
|
||||||
|
|
||||||
-- Modifier le TTL (exemple: 30 jours)
|
|
||||||
ALTER TABLE mabase_prod.ml_detected_anomalies
|
|
||||||
MODIFY TTL detected_at + INTERVAL 30 DAY;
|
|
||||||
|
|
||||||
-- Appliquer immédiatement
|
|
||||||
OPTIMIZE TABLE mabase_prod.ml_detected_anomalies FINAL;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Option B: Modifier la configuration de bot_detector_ai
|
|
||||||
|
|
||||||
Dans le fichier de configuration de `bot_detector_ai` (probablement `config.yaml` ou `settings.py`):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Exemple de configuration
|
|
||||||
clickhouse:
|
|
||||||
retention_days: 30 # Au lieu de 1 ou 7
|
|
||||||
```
|
|
||||||
|
|
||||||
Puis redémarrer le service :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose restart bot_detector_ai
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 Impact sur le stockage
|
|
||||||
|
|
||||||
### Estimation de l'augmentation
|
|
||||||
|
|
||||||
| Table | Données/jour | 30 jours → 90 jours | Impact |
|
|
||||||
|-------|--------------|---------------------|--------|
|
|
||||||
| `view_dashboard_entities` | ~100 MB | ×3 | +200 MB |
|
|
||||||
| `view_dashboard_user_agents` | ~50 MB | ×13 | +600 MB |
|
|
||||||
| `ml_detected_anomalies` | ~1 GB | ×30 | +29 GB |
|
|
||||||
|
|
||||||
**Total estimé:** +30 GB pour 90 jours de rétention
|
|
||||||
|
|
||||||
### Vérifier l'espace disque actuel
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT
|
|
||||||
table,
|
|
||||||
formatReadableSize(sum(data_compressed_bytes)) AS compressed_size,
|
|
||||||
formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed_size,
|
|
||||||
count() AS rows
|
|
||||||
FROM system.parts
|
|
||||||
WHERE database = 'mabase_prod'
|
|
||||||
AND table LIKE 'view_dashboard%'
|
|
||||||
GROUP BY table
|
|
||||||
ORDER BY compressed_size DESC;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Vérification après modification
|
|
||||||
|
|
||||||
### Test 1: Subnet ancien (ex: 212.30.36.0/24)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Via API
|
|
||||||
curl "http://192.168.1.2:8000/api/entities/subnet/212.30.36.0/24?hours=2160"
|
|
||||||
|
|
||||||
# Via ClickHouse
|
|
||||||
SELECT count()
|
|
||||||
FROM mabase_prod.view_dashboard_entities
|
|
||||||
WHERE entity_type = 'ip'
|
|
||||||
AND entity_value LIKE '212.30.36.%'
|
|
||||||
AND log_date >= now() - INTERVAL 90 DAY;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 2: Vérifier les dates minimales
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Date la plus ancienne dans view_dashboard_entities
|
|
||||||
SELECT min(log_date) AS oldest_date
|
|
||||||
FROM mabase_prod.view_dashboard_entities;
|
|
||||||
|
|
||||||
-- Date la plus ancienne dans view_dashboard_user_agents
|
|
||||||
SELECT min(log_date) AS oldest_date
|
|
||||||
FROM mabase_prod.view_dashboard_user_agents;
|
|
||||||
|
|
||||||
-- Date la plus ancienne dans ml_detected_anomalies
|
|
||||||
SELECT min(detected_at) AS oldest_date
|
|
||||||
FROM mabase_prod.ml_detected_anomalies;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚨 Points d'attention
|
|
||||||
|
|
||||||
### 1. Espace disque
|
|
||||||
|
|
||||||
Vérifiez l'espace disque disponible avant d'augmenter la rétention :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
df -h /var/lib/clickhouse
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Performance des requêtes
|
|
||||||
|
|
||||||
Plus de données = requêtes plus lentes. Solutions :
|
|
||||||
- Ajouter des index
|
|
||||||
- Utiliser des agrégations pré-calculées
|
|
||||||
- Partitionner par mois (déjà fait)
|
|
||||||
|
|
||||||
### 3. Nettoyage automatique
|
|
||||||
|
|
||||||
ClickHouse applique le TTL automatiquement pendant les opérations de merge. Les données ne sont pas supprimées instantanément.
|
|
||||||
|
|
||||||
### 4. Backup
|
|
||||||
|
|
||||||
Faire un backup avant de modifier les tables :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
clickhouse-backup create mabase_prod_backup_$(date +%Y%m%d)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Références
|
|
||||||
|
|
||||||
- [ClickHouse TTL Documentation](https://clickhouse.com/docs/en/sql-reference/statements/alter/ttl)
|
|
||||||
- [ClickHouse MergeTree TTL](https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/#mergetree-table-ttl)
|
|
||||||
- [ClickHouse System Tables](https://clickhouse.com/docs/en/operations/system-tables/)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🆘 Dépannage
|
|
||||||
|
|
||||||
### Problème: "TTL expression must return Date or DateTime"
|
|
||||||
|
|
||||||
**Solution:** Vérifier que la colonne utilisée dans le TTL est de type Date ou DateTime
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Vérifier les types de colonnes
|
|
||||||
DESCRIBE TABLE mabase_prod.view_dashboard_entities;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Problème: "Table is in readonly mode"
|
|
||||||
|
|
||||||
**Solution:** La table est gérée par une vue matérialisée. Modifier la vue, pas la table.
|
|
||||||
|
|
||||||
### Problème: OPTIMIZE prend trop de temps
|
|
||||||
|
|
||||||
**Solution:** Exécuter en arrière-plan avec un timeout plus long
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Exécuter avec timeout de 1 heure
|
|
||||||
SET max_execution_time = 3600;
|
|
||||||
OPTIMIZE TABLE mabase_prod.view_dashboard_entities FINAL;
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Dernière mise à jour:** 2026-03-15
|
|
||||||
**Version:** 1.0
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
-- =============================================================================
|
|
||||||
-- Script de modification de la rétention des données
|
|
||||||
-- =============================================================================
|
|
||||||
--
|
|
||||||
-- Ce script modifie les politiques de rétention pour conserver les données
|
|
||||||
-- plus longtemps (90 jours au lieu de 30/7 jours)
|
|
||||||
--
|
|
||||||
-- Instructions:
|
|
||||||
-- -------------
|
|
||||||
-- 1. Se connecter à ClickHouse:
|
|
||||||
-- clickhouse-client --host test-sdv-anubis.sdv.fr --port 8123 \
|
|
||||||
-- --user admin --password SuperPassword123! --database mabase_prod
|
|
||||||
--
|
|
||||||
-- 2. Exécuter ce script:
|
|
||||||
-- clickhouse-client --host test-sdv-anubis.sdv.fr --port 8123 \
|
|
||||||
-- --user admin --password SuperPassword123! < update_retention_policy.sql
|
|
||||||
--
|
|
||||||
-- 3. Vérifier les modifications:
|
|
||||||
-- SHOW TABLES LIKE 'view_dashboard%';
|
|
||||||
--
|
|
||||||
-- =============================================================================
|
|
||||||
|
|
||||||
USE mabase_prod;
|
|
||||||
|
|
||||||
-- =============================================================================
|
|
||||||
-- 1. Modifier la rétention de view_dashboard_entities (30 → 90 jours)
|
|
||||||
-- =============================================================================
|
|
||||||
|
|
||||||
ALTER TABLE mabase_prod.view_dashboard_entities
|
|
||||||
MODIFY TTL log_date + INTERVAL 90 DAY;
|
|
||||||
|
|
||||||
-- =============================================================================
|
|
||||||
-- 2. Modifier la rétention de view_dashboard_user_agents (7 → 90 jours)
|
|
||||||
-- =============================================================================
|
|
||||||
|
|
||||||
ALTER TABLE mabase_prod.view_dashboard_user_agents
|
|
||||||
MODIFY TTL log_date + INTERVAL 90 DAY;
|
|
||||||
|
|
||||||
-- =============================================================================
|
|
||||||
-- 3. (Optionnel) Modifier la rétention de ml_detected_anomalies
|
|
||||||
-- =============================================================================
|
|
||||||
-- Attention: Cette table est gérée par bot_detector_ai
|
|
||||||
-- Décommenter uniquement si vous avez accès à cette table
|
|
||||||
-- =============================================================================
|
|
||||||
|
|
||||||
-- ALTER TABLE mabase_prod.ml_detected_anomalies
|
|
||||||
-- MODIFY TTL detected_at + INTERVAL 30 DAY;
|
|
||||||
|
|
||||||
-- =============================================================================
|
|
||||||
-- 4. Appliquer immédiatement le nouveau TTL (optionnel)
|
|
||||||
-- =============================================================================
|
|
||||||
-- Cette commande peut prendre plusieurs minutes selon la taille des données
|
|
||||||
-- =============================================================================
|
|
||||||
|
|
||||||
-- OPTIMIZE TABLE mabase_prod.view_dashboard_entities FINAL;
|
|
||||||
-- OPTIMIZE TABLE mabase_prod.view_dashboard_user_agents FINAL;
|
|
||||||
|
|
||||||
-- =============================================================================
|
|
||||||
-- 5. Vérification des modifications
|
|
||||||
-- =============================================================================
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
name AS table_name,
|
|
||||||
engine,
|
|
||||||
create_table_query
|
|
||||||
FROM system.tables
|
|
||||||
WHERE database = 'mabase_prod'
|
|
||||||
AND name LIKE 'view_dashboard%'
|
|
||||||
FORMAT Vertical;
|
|
||||||
|
|
||||||
-- =============================================================================
|
|
||||||
-- FIN DU SCRIPT
|
|
||||||
-- =============================================================================
|
|
||||||
Reference in New Issue
Block a user