Objectif : transformer les données brutes collectées en KPIs actionnables, construire des dashboards de sécurité opérationnels, configurer des alertes automatiques et générer des rapports périodiques.
Toutes les actions du Jour 4 se font dans l'interface web Splunk (http://[IP_SOC]:8000) ou en ligne de commande sur la VM SOC. La VM cible peut rester démarrée pour générer du trafic en arrière-plan, mais aucune configuration ne lui est nécessaire.
http://[IP_SOC]:8000security contenant des données réelleslinux_secure, suricata, fail2ban, wazuhTP2_Attaques_SSH_Timeline) et Jour 3 (TP3_Detection_360) sauvegardésSettings → Licensing| Horaire | Activité | VM(s) | Durée |
|---|---|---|---|
| 09h00 – 09h30 | Cours — KPIs dans un SI, importance des métriques pour la prise de décision | — | 30 min |
| 09h30 – 10h00 | Cours — Niveaux d'alertes (P1/P2/P3), processus d'escalade, rôles L1/L2/L3 | — | 30 min |
| 10h00 – 10h15 | Pause | — | 15 min |
| 10h15 – 13h00 | TP 1 — Construction des dashboards de sécurité | SOC | 2h45 |
| 13h00 – 14h00 | Pause déjeuner | — | 1h |
| 14h00 – 16h00 | TP 2 — Mise en place des alertes de sécurité | SOC | 2h |
| 16h00 – 17h30 | TP 3 — Génération de rapports automatisés | SOC | 1h30 |
| 17h30 – 18h00 | Validation + débrief + snapshot | — | 30 min |
Un dashboard Splunk est une collection de panels SPL. Chaque panel exécute une recherche et affiche le résultat sous forme de graphique, tableau ou valeur unique. On va construire un dashboard opérationnel de SOC avec 4 panels complémentaires.
Les dashboards sont plus parlants avec des données récentes. Générer quelques événements de test depuis la VM cible.
# Tentatives SSH échouées (alimente linux_secure et fail2ban) for i in {1..8}; do ssh -o ConnectTimeout=2 -o StrictHostKeyChecking=no \ scantest@192.168.91.10 2>/dev/null || true sleep 1 done # Trafic Apache (alimente access_combined) for i in {1..15}; do curl -s http://localhost > /dev/null; done curl -s http://localhost/.env > /dev/null curl -s http://localhost/admin > /dev/null curl -s http://localhost/wp-login.php > /dev/null # Scan Nmap vers la VM SOC (alimente suricata) nmap -sS -p 1-500 192.168.91.10
Les Forwarders ont un délai d'envoi de quelques secondes à 1 minute. Vérifier dans Splunk : index=security | head 5 — le champ _time des derniers événements doit être récent.
Dashboard Title : SOC_Vue_Operationnelle Dashboard ID : soc_vue_operationnelle (auto-rempli) Description : Vue temps réel — Alertes Suricata, SSH, Fail2ban, Wazuh Shared in App : Search (ou All Apps) → Create Dashboard (Classic Dashboards)
Choisir Classic Dashboards — c'est le mode standard basé sur XML et SPL, plus stable et plus pédagogique. Dashboard Studio (nouveau) utilise un éditeur visuel mais est moins stable sur les versions récentes.
Ce panel montre l'évolution temporelle du nombre d'alertes par outil de détection. C'est la vue principale d'un analyste L1 en début de journée.
index=security
(sourcetype=suricata event_type=alert)
OR (sourcetype=linux_secure "Failed password")
OR (sourcetype=fail2ban "Ban")
OR (sourcetype=wazuh)
| eval outil=case(
sourcetype=="suricata", "Suricata",
sourcetype=="linux_secure","SSH Echecs",
sourcetype=="fail2ban", "Fail2ban",
sourcetype=="wazuh", "Wazuh")
| timechart span=15m count by outil
# Title: "Alertes par outil — 24h"
# Time range: Last 24 hours
Identifie les IPs sources qui génèrent le plus d'alertes réseau — les "top scanners" visibles depuis Suricata.
index=security sourcetype=suricata event_type=alert | spath output=src_ip path=src_ip | spath output=signature path=alert.signature | where isnotnull(src_ip) AND src_ip!="127.0.0.1" | stats count as nb_alertes by src_ip | sort -nb_alertes | head 10 # Title: "Top 10 IPs suspectes (Suricata)" # Visualization: Bar Chart (nb_alertes en Y, src_ip en X)
Liste les alertes Wazuh de niveau ≥ 7 (critiques) avec leur agent source et leur description. C'est la table de triage de l'analyste L1.
index=security sourcetype=wazuh | spath output=level path=rule.level | spath output=description path=rule.description | spath output=agent path=agent.name | where level >= 7 | eval criticite=case(level>=12,"CRITIQUE",level>=9,"HAUTE",level>=7,"MOYENNE") | table _time, criticite, level, agent, description | sort -level, -_time # Title: "Alertes Wazuh — Niveau ≥ 7" # Visualization: Table # Time range: Last 24 hours
Affiche le nombre total d'IPs bannies aujourd'hui avec une mini-courbe d'évolution. C'est un KPI de synthèse idéal pour un écran de supervision.
index=security sourcetype=fail2ban "Ban" | rex "NOTICE \[(?<jail>\w+)\] Ban (?<banned_ip>\d+\.\d+\.\d+\.\d+)" | where isnotnull(banned_ip) | stats count as total_bans, dc(banned_ip) as ips_distinctes # Title: "IPs bannies — Aujourd'hui" # Visualization: Single Value # Time range: Today
index=security | stats count by sourcetype | sort -count # Title: "Répartition des événements par source" # Visualization: Pie Chart # Time range: Last 7 days
Cliquer sur Save en haut à droite. Le dashboard est maintenant accessible depuis Dashboards → SOC_Vue_Operationnelle. Il se rafraîchit automatiquement selon la plage de temps sélectionnée.
En mode supervision, le dashboard doit se mettre à jour automatiquement. Cela se configure dans le XML du dashboard.
<!-- Trouver la balise <dashboard> en haut du XML et modifier ainsi --> <dashboard version="1.1" theme="dark" refresh="60"> <!-- refresh="60" = rafraîchissement automatique toutes les 60 secondes --> <!-- ⚠️ Ne pas ajouter refreshType="delay" — non reconnu par Splunk Enterprise 9.x -->
L'attribut refreshType="delay" n'est pas reconnu par toutes les versions de Splunk Enterprise et génère l'erreur "Unknown attribute refreshType for node dashboard". Il faut utiliser uniquement refresh="60" — c'est suffisant pour le rafraîchissement automatique.
Une alerte Splunk exécute une recherche SPL à intervalles réguliers. Si le résultat dépasse un seuil défini, Splunk déclenche une action : email, webhook, script, etc. On configure deux alertes couvrant les vecteurs d'attaque principaux.
Recherche SPL → exécutée périodiquement (ex: toutes les 5 min) → si condition remplie (ex: count > 5) → action déclenchée (email, log, webhook) → throttle pour éviter le spam (ex: 1 fois par heure max par IP source)
Sans SMTP configuré, l'action email dans les alertes et rapports est grisée. Cette étape est facultative pour le TP mais requise en production. Si vous n'avez pas de serveur SMTP disponible, passez directement à la Section A — les alertes fonctionnent sans email.
Serveur de messagerie (SMTP) : [hôte SMTP de votre fournisseur] Port : 587 (TLS/STARTTLS) ou 465 (SSL) Sécurité de connexion : TLS Nom d'utilisateur : [votre identifiant email] Mot de passe : [mot de passe ou token d'application] Adresse d'envoi : [votre adresse email]
| Fournisseur | Serveur SMTP | Port | Authentification |
|---|---|---|---|
| Gmail | smtp.gmail.com | 587 | Mot de passe d'application (pas le mot de passe habituel) |
| Microsoft 365 | smtp.office365.com | 587 | Identifiant + mot de passe du compte |
| Outlook.com | smtp-mail.outlook.com | 587 | Identifiant + mot de passe du compte |
| SMTP entreprise | Demander à l'administrateur | 25 ou 587 | Selon config interne (relay autorisé ou auth) |
| Serveur local | localhost ou 127.0.0.1 | 25 | Souvent sans auth (relay local) |
Ces fournisseurs bloquent les connexions SMTP avec le mot de passe de compte normal si l'authentification multifacteur est activée. Il faut générer un mot de passe d'application (ou token d'application) dans les paramètres de sécurité du compte.
Pour Gmail : myaccount.google.com → Sécurité → Mots de passe des applications
Pour M365 : portal.azure.com → Entra ID → Authentification → Mots de passe d'application
# Dans Splunk : Paramètres → Paramètres du serveur → Paramètres de messagerie # → Remplir les champs → cliquer "Envoyer un e-mail de test" # → Vérifier la réception dans votre boîte mail # Test alternatif depuis la ligne de commande de la VM SOC : curl -s --ssl-reqd \ --mail-from "expediteur@domaine.com" \ --mail-rcpt "destinataire@domaine.com" \ --url "smtps://[VOTRE_SERVEUR_SMTP]:587" \ --user "identifiant@domaine.com:MOT_DE_PASSE" \ -T /dev/null \ && echo "SMTP OK" || echo "SMTP ERREUR"
Les alertes s'enregistrent dans Activité → Alertes déclenchées et les rapports sont consultables dans Splunk, même sans email. L'email est une fonctionnalité additionnelle de notification — elle ne conditionne pas le fonctionnement du SOC.
Cette alerte se déclenche dès qu'une IP source génère plus de 5 tentatives SSH échouées en 5 minutes — seuil bas pour le TP, à ajuster en production selon le contexte.
index=security sourcetype=linux_secure "Failed password" | rex "from (?<src_ip>\d+\.\d+\.\d+\.\d+)" | where isnotnull(src_ip) | stats count as nb_echecs by src_ip | where nb_echecs >= 5
Alert name : Brute Force SSH Detecte Description : Une IP a généré 5+ tentatives SSH échouées en 5 minutes Alert type : Scheduled Schedule : Run every 5 minutes (Cron : */5 * * * *) Time range : Last 5 minutes Trigger condition : Number of Results > 0 (la recherche retourne des lignes seulement si nb_echecs >= 5) Déclencher : "Pour chaque résultat" (pas "Une fois") → Ce choix fait apparaître le champ de throttle par valeur Throttle : ✅ Supprimer les déclenchements pendant 60 minutes Supprimer les résultats contenant la valeur de champ : src_ip (Dans l'interface Splunk FR : "Supprimer les résultats contenant la valeur de champ") (évite le spam — 1 alerte max par IP par heure)
La requête SPL filtre elle-même avec where nb_echecs >= 5. Si elle retourne 0 lignes, aucune IP ne dépasse le seuil — pas d'alerte. Si elle retourne 1+ lignes, au moins une IP est suspecte — alerte déclenchée. C'est plus flexible que le seuil natif Splunk car on contrôle tout en SPL.
Chaque alerte peut déclencher plusieurs actions simultanément. L'action log est obligatoire (Splunk refuse de sauvegarder sans elle), l'email est optionnel.
# Action OBLIGATOIRE — Splunk refuse de sauvegarder sans au moins une action Ajouter aux alertes déclenchées → Mode: Pour chaque résultat (= Per-Result) → Gravité: Élevée (= High — brute force SSH = menace sérieuse) # Action OPTIONNELLE — nécessite SMTP configuré (voir section dédiée ci-dessous) Envoyer un e-mail → À: votre@email.com → Objet: [SOC ALERTE] Brute Force SSH détecté — $result.src_ip$ → Message: IP $result.src_ip$ a effectué $result.nb_echecs$ tentatives SSH
Si vous cliquez Enregistrer sans avoir ajouté d'action, Splunk affiche "Activer au moins une action". L'action minimale est Ajouter aux alertes déclenchées — elle enregistre dans Activité → Alertes déclenchées sans email. Suffisant pour valider le TP.
# Générer 8 tentatives SSH échouées (dépasse le seuil de 5) for i in {1..8}; do ssh -o ConnectTimeout=2 -o StrictHostKeyChecking=no \ alertetest@192.168.91.10 2>/dev/null || true sleep 0.5 done echo "8 tentatives envoyées — attendre 5 min max pour l'alerte"
Activity → Triggered Alerts # → Doit afficher "Brute Force SSH Detecte" avec l'heure du déclenchement # Ou forcer l'exécution immédiate : # Alerts → "Brute Force SSH Detecte" → Run Now (icône ▶)
L'alerte apparaît dans Activity → Triggered Alerts avec le statut "Fired". Si email configuré, un mail est reçu avec l'IP source et le nombre de tentatives.
index=security sourcetype=suricata event_type=alert | spath output=signature path=alert.signature | spath output=src_ip path=src_ip | where match(signature, "SCAN|scan|nmap|Nmap") | stats count as nb_alertes, values(signature) as signatures by src_ip | where nb_alertes >= 3
Alert name : Scan Reseau Detecte
Schedule : Every 5 minutes — Last 5 minutes
Trigger : Number of Results > 0
Throttle : 30 minutes, group by : src_ip
Action : Add to Triggered Alerts (severity: Medium)
index=security sourcetype=wazuh | spath output=level path=rule.level | spath output=description path=rule.description | spath output=agent path=agent.name | where level >= 9 | table _time, agent, level, description
Alert name : Wazuh Alerte Critique
Schedule : Every 5 minutes — Last 5 minutes
Trigger : Number of Results > 0
Throttle : 60 minutes, group by : agent
Action : Add to Triggered Alerts (severity: Critical)
Toutes les alertes déclenchées sont visibles dans Activity → Triggered Alerts. C'est l'équivalent d'une file d'incidents pour l'analyste L1 — chaque entrée représente un événement à qualifier et traiter.
En SOC réel, chaque alerte est qualifiée selon deux axes : probabilité que ce soit une vraie attaque et impact potentiel sur le SI.
| Priorité | Alerte | Splunk Severity | Délai de réponse attendu | Action L1 |
|---|---|---|---|---|
| P1 — Critique | Wazuh niveau ≥ 12 / rootkit | Critical | < 15 min | Isolation immédiate + escalade L2 |
| P2 — Haute | Brute force SSH réussi / FIM fichier critique | High | < 1h | Vérification + blocage IP + ticket |
| P3 — Moyenne | Scan réseau / Fail2ban ban / SSH échoué | Medium | < 4h | Log + surveillance renforcée |
| P4 — Basse | Trafic Apache 404 / alertes Suricata informatives | Low | Rapport quotidien | Agrégation dans rapport périodique |
Avec les 3 alertes configurées aujourd'hui, quelle priorité (P1/P2/P3/P4) assigneriez-vous à chacune ? Un scan Nmap de votre VM SOC par votre propre VM cible est-il une vraie menace dans ce contexte ? Que se passerait-il si le scan venait d'une IP externe inconnue ?
Un rapport Splunk est une recherche SPL sauvegardée avec une planification périodique (quotidien, hebdomadaire) et un format d'export (PDF, CSV, email). On construit le rapport hebdomadaire du SOC, destiné au RSSI.
Alerte : réactive — se déclenche quand une condition anormale est détectée. Destinée aux analystes L1 pour action immédiate.
Rapport : proactif — s'exécute périodiquement quel que soit l'état du SI. Destiné au management et RSSI pour vision stratégique.
Ce rapport agrège tous les événements de sécurité de la semaine écoulée, ventilés par outil et par criticité. Il est envoyé chaque lundi matin au RSSI.
index=security earliest=-7d latest=now
| eval outil=case(
sourcetype=="suricata" AND event_type="alert", "Suricata (NIDS)",
sourcetype=="linux_secure" AND match(_raw,"Failed password"), "SSH Echecs",
sourcetype=="fail2ban" AND match(_raw,"Ban"), "Fail2ban Bans",
sourcetype=="wazuh", "Wazuh (HIDS)",
true(), "Autre")
| where outil!="Autre"
| stats
count as total_evenements,
dc(host) as nb_hotes_impliques
by outil
| sort -total_evenements
| addcoltotals total_evenements label="TOTAL"
index=security sourcetype=suricata event_type=alert earliest=-7d
| spath output=src_ip path=src_ip
| spath output=signature path=alert.signature
| spath output=severity path=alert.severity
| stats
count as nb_alertes,
dc(signature) as signatures_distinctes
by src_ip
| sort -nb_alertes
| head 10
| rename src_ip as "IP Source",
nb_alertes as "Nb Alertes",
signatures_distinctes as "Signatures distinctes"
Schedule Report : ✅ Schedule Report Run on cron schedule : 0 8 * * 1 # → Chaque lundi à 08h00 # Décomposition : 0=minute 8=heure *=jour *=mois 1=lundi Time Range : Last 7 days # Remplir les champs de la planification : Planifier le rapport : ✅ Planifier le rapport Cron schedule : 0 8 * * 1 # → Chaque lundi à 08h00 Plage de temps : 7 derniers jours # Section "Envoyer un e-mail" (si SMTP configuré) : À : rssi@entreprise.com, soc-team@entreprise.com Objet : [SOC] Rapport hebdomadaire de sécurité Inclure : ✅ Joindre PDF (= Format PDF — la case à cocher, pas un menu séparé) ✅ Lier à Rapport ✅ Lien vers les résultats → Enregistrer
Dans Splunk, le format PDF s'active en cochant Joindre PDF dans la section "Inclure" — il n'y a pas de champ "Format" séparé. Si vous cherchez un menu "Format", vous ne le trouverez pas.
L'icône "Envoyer" sur le rapport n'apparaît que si SMTP est configuré. Sans SMTP, utiliser Ouvrir dans la recherche pour vérifier que la requête retourne des données — c'est la validation suffisante pour le TP. L'envoi email sera automatique à la prochaine exécution planifiée une fois SMTP configuré.
Pour générer un PDF immédiatement sans attendre la planification, Splunk propose un export direct depuis la recherche ou depuis le rapport.
Un fichier PDF nommé Rapport_SOC_Hebdomadaire.pdf contenant le tableau de synthèse avec les colonnes Outil / Nb Événements / Nb Hôtes impliqués. Ce PDF est le livrable que vous présenteriez au RSSI.
Le CSV est utile pour une analyse complémentaire dans Excel ou pour alimenter un outil de reporting externe (PowerBI, Tableau). On exporte les 7 derniers jours d'alertes triées.
index=security earliest=-7d latest=now
| eval
date=strftime(_time,"%Y-%m-%d %H:%M"),
outil=case(
sourcetype=="suricata","Suricata",
sourcetype=="linux_secure","SSH",
sourcetype=="fail2ban","Fail2ban",
sourcetype=="wazuh","Wazuh",
true(),"Autre")
| table date, outil, sourcetype, host, _raw
| rename
date as "Date/Heure",
outil as "Outil",
sourcetype as "Type",
host as "Hôte",
_raw as "Événement brut"
| sort -"Date/Heure"
En production, les exports CSV périodiques peuvent être automatisés via l'API REST Splunk : curl -k -u admin:pass "https://localhost:8089/services/search/jobs/export?search=index%3Dsecurity&output_mode=csv" > rapport.csv. Cette approche est utilisée pour alimenter des pipelines de données externes.
Le Jour 5 est le projet intégrateur — tout ce qui a été construit aujourd'hui sera évalué dans le contexte d'attaques réelles simulées depuis Kali Linux.
Faire les screenshots avant d'éteindre les VMs — une fois éteintes, les dashboards et alertes restent mais les données récentes ne seront plus visibles de la même façon.
SOC_Vue_Operationnelle est visible dans Dashboards et s'affiche sans erreurBrute Force SSH Detecte visible dans Alerts avec statut EnabledActivity → Triggered AlertsScan Reseau Detecte visible et activéeWazuh Alerte Critique visible et activéeActivity → Triggered Alerts avec au moins une alerte déclenchéeRapport_SOC_Hebdomadaire visible dans Reports0 8 * * 1 (lundi 08h00)Rapport_Top_Menaces_Semaine créé et planifiéAvec le Panel 1 (timeline 15 min) et l'alerte SSH configurée à 5 min, la détection théorique est de 5 à 20 minutes selon le timing. Sans alerte et sans dashboard, l'analyste devrait lancer une recherche manuellement — détection en heures voire jours. C'est l'impact direct du travail d'aujourd'hui : passer d'une détection réactive (après coup) à une détection proactive (en cours).
1. Chiffrer le PDF ou le lien de téléchargement. 2. Restreindre la liste de destinataires aux seules personnes habilitées. 3. Anonymiser les IPs dans la version destinée aux parties externes. 4. Conserver les rapports dans un espace de stockage avec contrôle d'accès et durée de rétention définie (RGPD). 5. Ne jamais envoyer via email non chiffré en dehors du périmètre de l'entreprise.
1. Pas de corrélation automatisée entre les outils (un ban Fail2ban + un scan Suricata de la même IP n'est pas encore traité comme un seul incident). 2. Trafic chiffré non analysé (HTTPS, DNS sur TLS). 3. Pas de VM Windows encore surveillée (Wazuh agent). 4. Pas de réponse automatique (isolation d'un hôte, blocage IP au firewall). 5. Le taux de couverture réel du SI n'est pas encore mesuré. Ce sont les axes d'amélioration du Jour 5.