Aperçu — ce que fait cet écran
Security ▸ Detections (/security/detections) est l’écran phare de la détection d’InfraGuard. Il réunit trois choses sur une seule page :
- Récit des algorithmes de détection — des info-bulles pédagogiques expliquant comment chaque moteur attrape les menaces (Kitsune ML · heuristiques srct · nginx
is_suspicious· JA3). - Récit post-détection — met en évidence, à partir de données réelles, les IP anormales · requêtes web suspectes · historique d’exécution que chaque moteur a capturés sur la fenêtre récente.
- ★ Jeux de règles de séquence JA3 — une heuristique déterministe lit la séquence chronologique d’empreintes JA3 d’une seule IP source et énumère son « comportement anormal continu » sous forme de jeux de règles professionnels enregistrés dans
infr_sec_ruleset.
La collecte et le blocage automatique tournent déjà côté backend (l’ancienne interface stats-design n’affichait que les tables pare-feu et liste noire) — l’objet de cet écran est de faire remonter cette télémétrie cachée sous forme de récit fiable.
Cet écran est principalement en lecture + analyse à la demande. Les détecteurs eux-mêmes (kts_tx · srct_tx · eve_ingest) sont des collecteurs Node exécutés sous pm2 sur les hôtes cibles ; l’application se contente de lire les tables qu’ils remplissent. Elle n’inspecte jamais le trafic elle-même.
La voie de narration par LLM a été supprimée le 2026-09-04. L’analyse envoyait auparavant le résumé de séquence à un adaptateur IA et enregistrait sa réponse en texte libre. Trois problèmes mesurés y ont mis fin : la conclusion du LLM (« rotation JA3 ») était celle qu’un calcul de ratio de trois lignes produisait déjà, pour environ 9 100 jetons par exécution ; le texte libre figeait la langue de son auteur, si bien que les sessions en anglais lisaient des cartes en coréen ; et l’écriture apposait
provider/modeldepuis l’adaptateur même sur la voie de repli, de sorte que 10 des 13 lignes enregistrées se réclamaient demodel=kimi-k2.6tout en étant une sortie de gabarit. L’analyse est désormais purement heuristique — aucun appel externe, aucun coût en jetons — etprovider/modelconsignent ce qui s’est réellement exécuté.
Quand l’utiliser
- Pour juger si une IP donnée est un botnet / scanner automatisé d’après son schéma de rotation JA3.
- Pour balayer d’un coup d’œil ce que les moteurs IDS / ML / nginx attrapent en ce moment (point d’entrée du tri).
- Pour déployer les collecteurs de détection sur un nouvel hôte (copie de la commande pm2 / du code source).
- Pour transformer les principaux contrevenants JA3 en jeux de règles recommandant un blocage ou un signalement.
- En arrivant depuis Overview / Threats par un lien direct afin d’analyser aussitôt une IP précise (présélection
?ip=).
Disposition
Bandeau de KPI
| KPI | Signification | Source |
|---|---|---|
| Anomalies IA | Nombre d’anomalies Kitsune sur la fenêtre choisie | comptage de kitsune_detail_log |
| Blocages IA | Parmi elles, is_blocked=1 (seuil + veto réunis) |
kitsune_detail_log where is_blocked |
| Web suspect | Requêtes nginx is_suspicious=1 sur la fenêtre |
comptage de nginx_meta_ct |
| Jeux de règles | Règles actuellement actives (status=active) |
infr_sec_ruleset |
Les deux premiers KPI parlent d’« IA » parce que Kitsune est réellement un auto-encodeur d’apprentissage automatique — cette étiquette est exacte et reste en place.
Panneau des algorithmes de détection (info-bulles edu)
Chaque carte de moteur ouvre une info-bulle pédagogique avec principe · ce qu’il surveille · astuces. Le texte vit dans le pack de langue statique security.det.edu.*.
- Kitsune — détection d’anomalies par ensemble d’auto-encodeurs
- srct — bloqueur automatique heuristique Suricata (5 catégories)
- nginx is_suspicious — marqueur d’attaque web après terminaison TLS
- Analyse de séquences JA3 — la vedette de cet écran
Guide de déploiement pm2
Fournit la commande et le code source pour déployer les 5 collecteurs de détection en cron pm2 sur un hôte cible (voir Sources de données · tableau pm2).
Journal de détection et historique d’exécution
- IP anormales (top Kitsune) — les 50 premières par
anomaly_score: IP · score · nombre de sessions · indicateur de blocage · run_ts. - Web suspect (top nginx) — les 12 premières correspondances
is_suspicious: src_ip · hits · dernier horodatage. - Historique d’exécution — les 30 lignes les plus récentes de
kitsune_process_log·srct_process_log(compteurs analysés/bloqués · message).
Contrevenants JA3 et jeux de règles
- Liste des contrevenants — les 12 principaux contrevenants JA3 sur une fenêtre fixe de 6 heures :
ja3_variety·tls_conns·sni_variety· last_ts · pays (geo). Le réseau propre (IP /24 des instances enregistrées) est exclu. - Tableau des jeux de règles — règles enregistrées (60 dernières) : entité · comportement · catégorie · gravité · action · confiance · origine. Par ligne : Activer / Écarter / Supprimer.
Mode d’emploi
1) Balayer l’état de la détection
Le sélecteur de plage (1h / 6h / 24h) en haut change la fenêtre d’observation (24h par défaut). Les KPI et les journaux de détection sont recalculés pour cette fenêtre. La page interroge toutes les ~30 s et le service met en cache 30 s.
Seule la liste des contrevenants porte toujours sur les 6 dernières heures, quelle que soit la plage. La rotation JA3 s’accumule sur plusieurs heures : une fenêtre courte ne révèle pas le schéma (aligné sur la fenêtre JA3 de 360 minutes du blocage automatique).
2) Lancer l’analyse de séquence JA3 (★)
- Choisissez une IP dans la liste des contrevenants (ou arrivez par lien direct depuis Overview/Threats) et cliquez sur [Analyser].
- Le serveur extrait la séquence TLS JA3 de cette IP depuis
suricata_tls_ctdans l’ordre chronologique (fenêtre = politique d’exploitationsec_ai_window_min, 60 min par défaut · jusqu’à 200 lignes). - Si la longueur de séquence est inférieure au minimum (
sec_ai_min_seq, 5 par défaut), elle est ignorée avecinsufficient_sequence. - L’heuristique classe la séquence en constats (voir le tableau des règles ci-dessous).
- Le résultat est enregistré en jeux de règles ; la liste et l’entonnoir d’Overview se rafraîchissent aussitôt.
Exemple de réponse :
{
"ok": true,
"provider": "heuristic",
"model": null,
"saved": 1,
"seq_len": 37,
"findings": [
{ "key": "ja3_rotation",
"params": { "conns": 37, "variety": 34 },
"category": "tls_anomaly",
"severity": "crit", "action": "block", "confidence": 91 }
]
}
L’analyse est déterministe et gratuite : la même séquence donne toujours les mêmes jeux de règles, elle ne contacte jamais de service externe et fonctionne sans accès réseau. Son exécution ne coûte rien : relancez-la librement dès que les chiffres d’un contrevenant évoluent.
Règles heuristiques
Les constats sont bâtis à partir de statistiques de séquence (rotation = ja3_variety / seq_len).
| Condition | Jeu de règles | Catégorie | Gravité | Action | Confiance |
|---|---|---|---|---|---|
| variety ≥ 3 ET rotation ≥ 0,5 | Rotation JA3 (scanner automatisé/botnet) | tls_anomaly | rotation≥0,9 → crit, sinon warn | block | 50 + round(rotation×45), max 95 |
| URL sensibles observées (.env·.git·wp-config…) | Sondage d’identifiants/fichiers de configuration | credential_access | crit | block | 88 |
| variety = 1 ET conns ≥ 10 ET sni_variety ≥ 4 | Balayage multi-cibles à JA3 unique | scan | warn | observe | 72 |
| Aucun des cas ci-dessus | Activité TLS de référence | other | info | observe | 40 |
Les URL sensibles sont détectées par l’expression régulière .env .git wp-config .aws /actuator phpunit /.. shell.php wp-login xmlrpc (depuis le contexte nginx is_suspicious + suricata_http).
Catégories, gravités et actions sont validées contre les enum des colonnes avant insertion (recon · credential_access · exfil · bruteforce · c2 · tls_anomaly · scan · other / info · warn · crit / observe · block · isolate · report).
Formulation des jeux de règles et langues
Un constat est enregistré comme une identité, pas comme une phrase. heuristicFindings() émet {key, params} ; la ligne conserve rule_key + params (migration 000783) et la formulation est appliquée à la lecture, dans la langue du lecteur.
- Le texte vit dans
resources/lang/<locale>/security.phpsousdet.rule.<key>.{name,behavior}— traduit dans les 8 langues de la console. - Les colonnes
name/behaviorconservent le rendu anglais en repli, afin que les exports, les audits et les lignes écrites avant 000783 restent lisibles. Sirule_keymanque, ou si une langue n’a pas la clé, le texte enregistré est utilisé — la clé brute n’est jamais affichée. - Le cache de Detections est indexé par langue (
infr:sec:det:<locale>:<range>). Sans cela, une session en coréen qui remplit le cache de 30 secondes le transmettrait au lecteur anglophone suivant — ce qui se produisait exactement.
Les lignes créées avant 000783 conservent leur texte d’origine. La migration ne restaure
rule_keyque lorsque les propres éléments de preuve d’une ligne reproduisent exactement l’ancien gabarit (aucune supposition) ; les lignes en texte libre écrites par l’ancienne voie LLM restent figées jusqu’à ce que l’IP concernée soit réanalysée, ce qui les remplace.
3) Gérer les jeux de règles
| Action | Effet |
|---|---|
| Activer | status=active (répercuté dans l’entonnoir d’Overview / le récit de blocage) |
| Écarter | status=dismissed |
| Supprimer | Retire la ligne |
Une nouvelle analyse ne remplace que les jeux de règles d’origine automatique de cette IP (supprime entity_type=ip, entity_key=ip, source=ai puis les recrée) — les règles rédigées à la main sont conservées.
Le champ
actiond’un jeu de règles est une recommandation, pas une instruction. Rien n’agit dessus : le blocage automatique calcule la rotation JA3 directement depuissuricata_tls_ctet ne lit jamaisinfr_sec_ruleset. Une règle indiquantaction=blockne bloque rien — le blocage se fait depuis Blocklist ou via le planificateur de blocage automatique.
4) Accumulation planifiée (sur activation)
La commande infr:sec-analyze parcourt les principaux contrevenants JA3 et accumule des jeux de règles. C’est une commande à passage unique qui se termine après exécution, donc planifiable en toute sécurité (ce n’est pas un démon).
# Contourner le verrou et exécuter une fois (débogage)
php artisan infr:sec-analyze --force
# Analyser une seule IP (ignore le verrou)
php artisan infr:sec-analyze --ip=203.0.113.10
- Verrou : politique d’exploitation
sec_ai_schedule_on(0= désactivé par défaut). Désactivé, la commande ne fait rien — activez-la dans l’onglet sécurité de Politique d’exploitation. - Une exécution planifiée analyse les
sec_ai_top_n(10 par défaut) premiers contrevenants. - La planification s’exécute toutes les 30 minutes et, l’analyse étant heuristique, ne coûte aucun jeton et ne fait aucun appel externe. Elle reste désactivée par défaut uniquement parce que ces jeux de règles sont informatifs.
5) Copier les commandes de déploiement pm2
La carte pm2 propose [Copier la commande] (ligne d’exécution pm2), [Copier le code source] (corps du fragment) et [Remplir avec les valeurs de l’instance et copier] (substitution des jetons HOSTNAME/IP). Le code provient du fragment initialisé dans Inventory ▸ Tools (infr_snippet).
Sources de données
Tables héritées lues (ne pas modifier)
| Table | Usage | Collecteur alimentant |
|---|---|---|
kitsune_detail_log |
IP anormale · anomaly_score · is_blocked | kts_tx |
kitsune_process_log |
Historique d’exécution Kitsune | kts_tx |
srct_process_log |
Historique d’exécution srct | srct_tx |
nginx_meta_ct |
Requêtes web suspectes (is_suspicious) |
nginx_shipper/aggregator |
suricata_tls_ct |
Séquence JA3 (ja3_hash · sni · version) | eve_ingest |
suricata_http_ct |
Contexte HTTP pour l’analyse | eve_ingest |
blacklist_info |
Résultats du blocage automatique (référence) | kts_tx · srct_tx |
ip_info_loop |
Enrichissement geo/ASN | — |
Nouvelles tables appartenant à l’application
infr_sec_ruleset(migrations 000730 · 000783) — jeux de règles. Colonnes :entity_type·entity_key·name·behavior·rule_key·params(json) ·category·severity·action·confidence·ja3·sequence(json) ·evidence(json) ·source(ai=dérivé par la machine | manual) ·provider·model·status(draft|active|dismissed). Remplie parSecurityAiService::persist().infr_snippet— corps de code source pm2.infr_audit_log— auditesec.ai_analyze·sec.ruleset_save·sec.ruleset_delete. La première chaîne d’action reste inchangée afin de ne pas couper en deux la piste d’audit existante.
Collecteurs déployés par pm2
| key | Alimente | Commande de déploiement (cron-restart) |
|---|---|---|
| eve_ingest | suricata_*_ct |
pm2 start infr_eve_ingest.cjs --name infr-eve --cron-restart="0 0 * * 6" |
| kts_tx | kitsune_*_log · blacklist_info |
pm2 start infr_kts_tx.cjs --name infr-kitsune --cron-restart="0 0 * * 2" |
| srct_tx | srct_process_log · blacklist_info |
pm2 start infr_srct_tx.cjs --name infr-srct --cron-restart="0 0 * * 4" |
| sync_black | ipset · iptables |
pm2 start infr_sync_black.mjs --name infr-syncblack --cron-restart="*/5 * * * *" |
| sync_firewall | firewall_status |
pm2 start infr_sync_firewall.cjs --name infr-firewall --cron-restart="0 0 * * 0" |
Services et routes
- DetectionService — construit les KPI, journaux de détection, contrevenants et jeux de règles (cache de 30 s par langue, lecture seule via
SecurityRepository) ;phrase()applique la formulation à la lecture. - SecurityAiService — séquence JA3 → constats heuristiques → upsert du jeu de règles. Ne contient aucun appel LLM.
- SecurityScope::excludePrefixes() — exclusion du réseau propre (IP /24 des instances enregistrées + politique d’exploitation ; aucune valeur codée en dur).
| Méthode | Route |
|---|---|
| GET | /security/detections (index) |
| GET | /security/detections/live (interrogation) |
| POST | /security/detections/analyze (analyser) |
| POST | /security/detections/ruleset/save |
| POST | /security/detections/ruleset/delete |
Accès
| Opération | Contrôle |
|---|---|
| Voir l’écran | Accès au domaine de rôle Security (min_req 2) — demo (1) ne voit pas du tout le domaine sécurité ; staff (5) · admin (10) peuvent consulter |
| Analyser / enregistrer·supprimer une règle | user_level ≥ 2 (canWrite) + audit dans infr_audit_log |
- Le contrôle d’écriture est appliqué dans le
canWrite()du contrôleur (sessioninfr_user_level ≥ 2) — le niveau demo ne peut ni analyser ni modifier les règles. - L’IP saisie est validée par
filter_var(FILTER_VALIDATE_IP)(IP invalide → 422). - Toute opération destructrice est inscrite au journal d’audit → Audit.
Dépannage et FAQ
Analyse ignorée avec
insufficient_sequence— la séquencesuricata_tls_ctde cette IP est inférieure àsec_ai_min_seq(5 par défaut). Élargissez la fenêtre (sec_ai_window_min, 60 min par défaut) ou choisissez une IP plus active dans la fenêtre de 6 heures de la liste des contrevenants.
- Un ancien jeu de règles s’affiche dans la mauvaise langue — il a été écrit avant 000783 et porte un texte figé. Réanalysez cette IP : la nouvelle ligne enregistre
rule_keyet suit la langue du lecteur. Les lignes des IP qui n’apparaissent plus peuvent être supprimées du tableau. - Les KPI/jeux de règles ne changent pas — c’est le cache de 30 s conjugué à la cadence d’interrogation. L’analyse et l’enregistrement invalident immédiatement le cache (
flush, pour toutes les variantes de langue) : un rafraîchissement les répercute. - La liste des contrevenants est vide — aucune activité JA3 sur les 6 dernières heures de
suricata_tls_ct, ou tout a été exclu comme réseau propre. Vérifiez que le collecteureve_ingesttourne. - La planification ne fait rien —
sec_ai_schedule_on=0(par défaut). Activez-la dans l’onglet sécurité de Politique d’exploitation, ou exécutez une fois avec--force. - Les journaux de détection sont tous à zéro — le processus pm2 concerné est peut-être mort. Redémarrez-le avec la commande de déploiement de la carte pm2 et vérifiez l’historique d’exécution.
Voir aussi
- Aperçu sécurité — entonnoir de défense
- Menaces — tri des menaces IDS
- Jeux de règles — catalogue des règles de détection
- Blocage automatique
- Liste de blocage et réputation
- Politique d’exploitation
