NOPE LinkedIn

Catégories:
Blog

La session partagée : garantir la cohérence d'anonymisation sur un batch de logs

Rubrique: Blog Tag: Anonymisation Tag: Architecture Tag: Logs Tag: NLP Tag: Cohérence Tag: Pipeline Tag: MLOps Tag: anonyfiles Tag: spaCy Tag: Cybersécurité

La session partagée : garantir la cohérence d’anonymisation sur un batch de logs

Anonymiser un fichier de logs est résolu. Anonymiser un batch de fichiers de logs de manière cohérente — même entité, même token, partout — est un problème d’architecture non trivial que les outils standards ne résolvent pas.

C’est pourtant la condition minimum pour que les logs anonymisés restent exploitables par leur destinataire.


Le cas d’usage qui impose la contrainte

L’infrastructure rencontre un problème critique. Les logs sont transmis au support de l’éditeur — VMware, Cisco, Fortinet — pour investigation. Ces logs ne doivent pas exposer l’infrastructure interne : noms de serveurs, IPs privées, comptes de service, noms de domaine internes, subnets.

Mais voici la contrainte que ce cas d’usage impose :

Si 192.168.10.50IP_001 dans le log firewall, alors 192.168.10.50 doit être IP_001 dans le log applicatif, le log réseau, et partout ailleurs dans le batch.

L’ingénieur support doit pouvoir :

  • Corréler des événements entre plusieurs fichiers de log
  • Suivre le comportement d’un même asset tout au long d’une séquence
  • Comprendre les relations : ce serveur a contacté cette IP, qui a déclenché cette règle

Si 192.168.10.50 est IP_001 dans le syslog et IP_007 dans le log firewall, l’analyse devient impossible. Le support ne peut pas travailler avec des logs incohérents.


Ce que les outils actuels gèrent (et ce qu’ils ne gèrent pas)

anonyfiles — le moteur de remplacement sous-jacent — gère déjà la cohérence intra-document :

# Session anonyfiles : même entité → même remplacement dans le document
session = ReplacementSession(config)
result1 = session.anonymize("Connexion de 192.168.10.50 acceptée")
result2 = session.anonymize("Alerte sur 192.168.10.50 — bruteforce détecté")
# → IP_001 dans les deux cas, cohérence garantie dans la session

Le mapping est stateful : la session conserve les associations entité → token et les réutilise à chaque nouvelle occurrence dans le document courant.

Ce qui manque : la session ne persiste pas entre documents. Un second fichier soumis à anonyfiles crée une nouvelle session — 192.168.10.50 peut recevoir un token différent.

Besoin anonyfiles actuel Gap
Cohérence intra-document ✓ (session stateful)
Cohérence inter-documents shared_mapping_proxy à implémenter
Token séquentiel lisible ✓ (config-driven)
Réversibilité UUID
Entités infra sécurité NER sécurité requis (articles 1 & 3)

Le problème plus profond : la résolution d’aliases

La cohérence inter-fichiers révèle un problème plus fondamental : un même asset peut apparaître sous plusieurs formes dans différents logs.

Log syslog    : "connexion de 192.168.10.50"
Log DNS       : "résolution de srv-web01.corp.local → 192.168.10.50"
Log firewall  : "trafic de srv-web01 vers 10.10.0.254"
Log applicatif: "requête depuis srv-web01.corp.local"

192.168.10.50 et srv-web01 et srv-web01.corp.local désignent le même asset. Un regex ou un NER classique les détecte comme trois entités distinctes. Ils ne peuvent pas inférer qu’il s’agit du même serveur.

Si les trois formes reçoivent des tokens différents (IP_001, HOST_001, HOST_002), le support éditeur ne peut pas suivre le fil des événements. La cohérence exige que le même asset reçoive le même token, quelle que soit la forme sous laquelle il apparaît.


L’architecture pipeline en trois étapes

La solution est un pipeline en trois étapes où le NER classique et le LLM ont des rôles distincts :

graph TD
    A[Batch de logs\nfichier1.log, fichier2.log, ...] --> B

    B[Étape 1 — Scan rapide\nregex + spaCy NER]
    B --> C[Inventaire d'entités\npar fichier, agrégé]

    C --> D[Étape 2 — Consolidation LLM\nPhi-3.5-mini local]
    D --> E[Mapping unifié\nentité/alias → TOKEN_NNN]

    E --> F[Étape 3 — Application\nanonyfiles session partagée]
    F --> G[Logs anonymisés\ncohérents sur tout le batch]
    F --> H[Mapping réversible\nchiffré UUID]

Étape 1 — Scan rapide (NER)

Le NER extrait les entités de chaque fichier. Le résultat est agrégé sur tout le batch — pas les logs bruts, seulement l’inventaire :

{
  "file1.log": {
    "IP_ADDRESS": ["192.168.10.50", "10.10.0.254"],
    "HOSTNAME": ["srv-web01.corp.local"],
    "SERVICE_ACCOUNT": ["svc_splunk_admin"]
  },
  "file2.log": {
    "IP_ADDRESS": ["192.168.10.50"],
    "HOSTNAME": ["srv-web01", "srv-web01.corp.local"]
  }
}

L’inventaire est compact — quelques centaines d’entités, pas des mégaoctets de logs bruts. C’est ce qui rend la prochaine étape viable.

Étape 2 — Consolidation LLM (résolution d’aliases)

Le LLM ne lit pas les logs. Il reçoit l’inventaire structuré et répond à une question précise : quelles entités désignent le même asset ?

prompt = """Tu es un expert réseau. Regroupe les entités qui désignent le même asset
et attribue un token séquentiel à chaque groupe.

Entités extraites :
IPs: 192.168.10.50, 10.10.0.254
Hostnames: srv-web01, srv-web01.corp.local
Comptes: svc_splunk_admin

Retourne un JSON : {"groupes": [{"token": "HOST_001", "aliases": [...]}]}"""

Résultat attendu :

{
  "groupes": [
    {
      "token": "HOST_001",
      "aliases": ["srv-web01", "srv-web01.corp.local", "192.168.10.50"]
    },
    {
      "token": "IP_002",
      "aliases": ["10.10.0.254"]
    },
    {
      "token": "SVC_001",
      "aliases": ["svc_splunk_admin"]
    }
  ]
}

Le LLM fait ce que le NER ne peut pas faire : inférer que srv-web01, srv-web01.corp.local et 192.168.10.50 sont le même asset. Cette résolution sémantique est exactement le type de tâche où les LLMs excellent — et où les NER classiques échouent structurellement.

Pourquoi Phi-3.5-mini local ?

Pour les logs d’infrastructure, même l’inventaire extrait (noms de serveurs internes, comptes de service, subnets) est sensible. Il ne doit pas transiter vers une API externe. Phi-3.5-mini en ONNX sur CPU (variante cpu-int4, ~2.5 Go de RAM) suffit pour cette tâche poncctuelle — la consolidation n’est pas un traitement en continu, c’est un appel par batch.

Étape 3 — Application (anonyfiles session partagée)

Le mapping unifié est injecté dans une session anonyfiles partagée sur tout le batch. Chaque fichier est soumis à la même session — toutes les formes d’un même asset (srv-web01, srv-web01.corp.local, 192.168.10.50) sont remplacées par le même token HOST_001.


La stratégie de token séquentiel

Pour le cas d’usage “envoi à un éditeur”, Faker (remplacement par des valeurs fictives crédibles) n’est pas adapté :

Stratégie Lisibilité Corrélabilité Réversibilité Adapté à
REDACTED Basse (tout est [REDACTED]) Nulle Non Archivage pur
Faker (IP fictive, hostname fictif) Haute Partielle (si cohérent) Non LLM externe
Token séquentiel (HOST_001, IP_002) Haute Totale Oui Support éditeur

Le token séquentiel est le seul qui garantit simultanément :

  • Lisibilité : l’ingénieur support comprend qu’il y a un HOST_001 et un HOST_002
  • Corrélabilité : toutes les occurrences de HOST_001 dans tous les fichiers désignent le même asset
  • Réversibilité : le mapping HOST_001 → srv-dc01.corp.local est exporté chiffré pour l’expéditeur
192.168.10.50      → IP_001
192.168.10.51      → IP_002
srv-dc01.corp      → HOST_001
svc_splunk         → SVC_001
CORP\jdoe          → USER_001
10.10.0.0/24       → SUBNET_001

Séparation des responsabilités (architecture finale)

Composant Rôle Technologie
Scan NER Extraire les entités candidates Regex + AnonyNER (spaCy fine-tuné)
Consolidation Résoudre les aliases, classifier (interne/sensible) LLM local (Phi-3.5-mini ONNX)
Application Appliquer le mapping, garantir la cohérence inter-fichiers anonyfiles fork (session partagée)
Orchestration Piloter le pipeline, gérer le batch, exporter le mapping AnonyAgent (cyber-agent-engine)

Chaque composant a un rôle clair, remplaçable indépendamment. Le moteur anonyfiles peut évoluer sans toucher à la logique de consolidation. Le LLM de consolidation peut être remplacé par un modèle plus récent sans modifier le scan NER.


État d’avancement et prochaines étapes

Ce qui fonctionne :

  • Le scan NER (AnonyNER spaCy) — pipeline de production opérationnel
  • anonyfiles — cohérence intra-document, token séquentiel, réversibilité UUID
  • Le LLM de consolidation — prototype Phi-3.5-mini ONNX validé sur inventaires courts

Ce qui reste à implémenter :

  • shared_mapping_proxy — l’interface qui partage la session anonyfiles sur un batch entier (le gap central du pipeline)
  • Validation de la qualité de résolution d’aliases du LLM sur des inventaires d’infrastructure réels (risque d’hallucination sur des noms d’assets proches)
  • Chiffrement du mapping réversible exporté (mapping en clair aujourd’hui)

L’engagement de contribution : Les règles NER sécurité (regex pour HOSTNAME, IP RFC1918, CVE, comptes svc_*) sont développées dans le fork anonyfiles et soumises en contribution upstream. La logique de consolidation LLM et l’orchestration restent dans cyber-agent-engine — elles dépendent de l’environnement opérationnel et ne sont pas généralisables upstream.


Conclusion de la série

L’anonymisation des logs de sécurité est un problème à plusieurs couches :

  1. Détection — les entités de sécurité (HOSTNAME, SERVICE_ACCOUNT, FIREWALL_RULE) sont invisibles aux NER génériques → fine-tuner spaCy sur un corpus annoté domaine-spécifique
  2. Corpus — les données d’entraînement sont rares par nature → LogHub, SDLog, génération LLM-assistée
  3. Résistance — l’anonymisation peut être contournée par attaque LLM sur le contexte résiduel → tester avec Recollect & Rank, appliquer k-anonymité
  4. Cohérence — un batch multi-fichiers exige un mapping partagé et une résolution d’aliases cross-documents → pipeline trois étapes (scan → consolidation LLM → application)

Aucune de ces couches n’est triviale prise isolément. Ensemble, elles constituent un pipeline d’anonymisation qui tient ses promesses face à des logs d’infrastructure réels.


Ressources :