Aller au contenu

Pilotage, empreinte et donnees de securite

Ce document fixe la cible du produit : un plan de controle qui pilote vraiment le bord, une empreinte client exploitable, des evenements de securite structures, des drains vers un SOC, un bus pour tenir la charge, et une couverture L4 en plus du HTTP.

Etat au 20 octobre 2026 : l'operateur applique desormais les interrupteurs du bloc security et retire les objets quand on les eteint (verifie en production sur EdgeSite toggle-test). Le reste de ce document est la feuille de route, avec l'effort estime et les pieges.


1. Ce que font les acteurs, et ce qu'il faut en reprendre

Cloudflare (WAF, Bot Management, Security Analytics)

  • Regles par phase (rulesets) : chaque requete traverse des phases ordonnees, et chaque regle peut journaliser sans bloquer. C'est la bonne abstraction : une politique est une suite d'etapes, pas un interrupteur.
  • Bot score 1-99 attache a chaque requete, calcule sur des signaux heuristiques (empreinte TLS/HTTP, coherence, comportement). Le score est fourni au client comme un fait, pas comme un verdict.
  • Turnstile : preuve de travail invisible, sans interaction, avec un jeton signe verifie au bord. C'est exactement notre modele, en mieux fini.
  • Under Attack Mode : un seul bouton qui durcit tout le site (challenge sur tout, cache reduit). Utile, et trompeusement difficile a bien faire.
  • Security Analytics : agregats par dimension (regle, action, pays, AS, user agent, empreinte) avec echantillons de requetes. C'est ce qui manque le plus a notre console.
  • Logpush : export par destination (S3, Splunk, Datadog, webhook) avec champs selectionnables, batching et reprise. Notre modele de drain doit s'en inspirer.
  • Rate limiting par expression plutot que par compteur global.

A reprendre : phases ordonnees, score comme fait, analyse par dimension, drains par destination avec choix des champs, mode crise. A eviter : le score opaque non explicable. Un client doit pouvoir demander pourquoi une requete a ete bloquee et obtenir une reponse.

DataDome

  • Empreinte d'appareil cote navigateur : canvas, WebGL, polices, fuseau, coherence entre signaux, plus un cookie signe. Ce que le reseau ne voit pas.
  • Signaux tiers : reputation d'adresse, d'AS, de plage hebergeur, d'empreinte deja vue sur d'autres clients. L'effet reseau est leur vraie douve.
  • Decision en quelques millisecondes au bord, avec un cache de reputation.
  • Challenge progressif : invisible, puis interaction, puis CAPTCHA selon la confiance. Jamais un mur binaire.
  • Protection de compte (credential stuffing, prise de compte) separee de la protection de site.
  • Console orientee enquete : une requete bloquee s'ouvre sur son contexte (empreinte, historique de l'adresse, regles declenchees).

A reprendre : challenge progressif, contexte d'enquete, separation site/compte. A eviter : l'empreinte navigateur invasive sans consentement. En Europe, un empreillage de fingerprinting doit etre documente et minimise.

Bunny Shield

  • Positionnement prix : DDoS + WAF + detection de bots pour quelques dollars par site, sans engagement. C'est le concurrent a battre sur le milieu de gamme.
  • Regles de bord scriptables (petits scripts par evenement) plutot qu'un langage de politique complet.
  • Simplicite radicale : un interrupteur par fonction, pas de matrice.
  • Reseau tres large, tarif tres bas : ils gagnent par l'echelle, pas par la finesse.

A reprendre : la grille tarifaire par site et non par requete, la simplicite de prise en main. A eviter : leur finesse de politique, insuffisante pour un infogerant.

Les autres, en une ligne chacun

  • Akamai : politique par application, protection des API par schema, detection comportementale. Reference sur les grandes surfaces.
  • Imperva : classification des API, protection des identifiants, tres fort sur l'audit de conformite.
  • Fastly : calcul au bord (Compute@Edge) et journaux en flux. C'est le modele a suivre pour les drains : le client branche ce qu'il veut.
  • AWS WAF/Shield : regles managees, labels de regles (une regle pose une etiquette, une autre decide sur l'etiquette). Les labels sont une excellente idee, plus souple que des priorites numeriques.
  • Sucuri : simplicite et nettoyage de site compromis. Utile a connaitre pour l'argumentaire, pas pour l'architecture.

CrowdSec, pour la structure

  • Scenario : un ensemble de regles qui, sur une fenetre, produit une alerte.
  • Decision : la sanction attachee a une alerte (type, portee, valeur, duree, origine). Une alerte peut porter plusieurs decisions.
  • Portee : Ip, Range, Country, AS, User, Session.
  • LAPI : le point central qui recoit les alertes et sert les decisions aux bouncers, avec listes communautaires et abonnements.
  • Bouncer : le composant qui applique (pare-feu, serveur web, proxy).
  • Console : enquete, historique, duree de blocage, faux positifs.

C'est le bon decoupage : evenement, alerte, decision, application. Notre console melange encore les trois. Le document de schema en section 7 corrige cela.


2. L'operateur comme plan de controle

Ce qui marche aujourd'hui

  • CRD EdgeSite et BlocklistSource, reconciliation idempotente, reprise toutes les cinq minutes.
  • Bloc spec.security : waf, sensitiveFiles, challenge, blocklists, allowlists. Chaque interrupteur cree ou retire un objet reel.
  • Suppression effective a l'extinction (verifie : AuthorizationPolicy et WasmPlugin retires, puis recreees au rallumage).
  • Lecture de l'etat frais depuis l'API, sans cache, pour ne jamais decider sur une vue perimee.
  • Conditions Ready avec message lisible et compteur d'objets.

Ce qui manque pour en faire un outil de pilotage

  1. Finaliseur de suppression : supprimer un EdgeSite doit retirer ses objets (aujourd'hui ils survivent, orphelins, si les ownerReferences ne suffisent pas).
  2. Detection de derive : comparer l'objet desire a l'objet reel et corriger. Aujourd'hui on applique sans verifier, donc une modification manuelle passe.
  3. Statut par fonction : status.features[] avec applied, reason, since. La console afficherait la verite du terrain, pas l'intention.
  4. Validation a l'admission (CEL) : refuser un domaine malforme, un port interdit, un nom d'amont vide, une difficulte de challenge hors bornes.
  5. Valeurs par defaut dans le CRD : un manifeste minimal doit produire un site sur. Aujourd'hui les defauts sont dans le code Go, invisibles pour le client.
  6. Plan avant application (dry-run) : rendre le diff entre l'etat desire et l'etat reel, pour que la console montre ce qui va changer avant de le faire.
  7. Evenements Kubernetes : chaque application, chaque retrait, chaque echec doit produire un evenement lisible (kubectl describe).
  8. Metriques de reconciliation : duree, nombre, echecs par type, age de la derniere reussite. Sans cela, l'operateur est une boite noire.
  9. Derive de version : status.observedGeneration compare a generation, et condition Stalled si la reconciliation echoue en boucle.
  10. Haute disponibilite : election de leader (deja fournie par controller-runtime), deux replicas, PodDisruptionBudget.
  11. Rollout par vagues : appliquer un changement de configuration a 1 %, 10 %, 100 % des noeuds de bord, avec retour arriere automatique sur erreur.
  12. Webhook de conversion : le jour ou v1beta1 arrive, il faut pouvoir lire les anciens objets sans casser les clients.

3. Liste exhaustive des propositions

Effort : S (moins d'une journee), M (deux a cinq jours), L (une a trois semaines).

A. Boucle de controle (operateur)

# Proposition Effort Pourquoi
A1 Finaliseur de suppression S Ne plus laisser d'objets orphelins
A2 status.features[] par fonction S La console dit ce qui est pose, pas ce qui est demande
A3 Detection de derive et correction M Un objet modifie a la main doit revenir
A4 Validation CEL dans le CRD S Refuser tot, pas au milieu de la reconciliation
A5 Defauts declares dans le CRD S Un manifeste minimal doit suffire
A6 Dry-run et diff lisible M Montrer ce qui va changer avant de le faire
A7 Evenements Kubernetes S Diagnostic sans lire les journaux
A8 Metriques Prometheus de reconciliation S Voir l'operateur travailler
A9 Deux replicas et PDB M Plus de point unique
A10 Rollout par vagues avec retour arriere L Changer la politique sans couper un client
A11 Signature des manifestes (cosign) M Prouver que l'image executee est la bonne
A12 Revision d'historique (status.history) M Savoir qui a change quoi, quand

B. Politique et decision

# Proposition Effort Pourquoi
B1 Phases ordonnees a la Cloudflare M Remplacer les priorites numeriques par un pipeline lisible
B2 Etiquettes de regles (labels) S Une regle pose une etiquette, une autre decide
B3 Score expose comme un fait, pas un verdict S Expliquer une decision
B4 Challenge progressif (invisible, interaction, CAPTCHA) M Moins de friction qu'un mur
B5 Protection de compte (credential stuffing) L Le cas d'usage le plus demande en e-commerce
B6 Limitation de debit par expression M Par route, par utilisateur, par empreinte
B7 Mode crise global (un bouton, tout durcit) S Repondre a une attaque en dix secondes
B8 Politique par route et par methode M Le WAF actuel ne distingue pas /api de /blog
B9 Simulateur de regles (rejouer un journal) M Tester une politique sur le trafic passe
B10 Explication de decision (x-exoledge-reason) S Le client voit la regle qui a tranche

C. Empreinte et identification

# Proposition Effort Pourquoi
C1 JA4 dans chaque evenement HTTP S Voir la vraie nature du client
C2 JA4H (empreinte HTTP normalisee) M Distinguer un navigateur d'un script qui l'imite
C3 JA4S cote serveur (empreinte de notre reponse) S Detecter les clients qui ne suivent pas le protocole
C4 JA4T/JA4TS par eBPF (pile TCP) L Detecter les systemes d'exploitation annonces a tort
C5 JA4X sur les certificats clients (mTLS) M Identifier un partenaire par son certificat
C6 Reputation d'empreinte partagee entre organisations M Une empreinte vue sur vingt sites est un bot
C7 Empreinte navigateur (canvas, WebGL) cote challenge L Le seul signal que le reseau ne voit pas
C8 Coherence UA / empreinte / ordre des en-tetes M Le meilleur detecteur de scripts deguises

D. Journalisation et drains

# Proposition Effort Pourquoi
D1 Drain OTLP par organisation (gRPC et HTTP) M Brancher un SOC sans lui imposer notre format
D2 Choix des champs exportes S Ne pas envoyer d'adresses IP a un tiers sans raison
D3 Tampon disque et reprise apres coupure M Un SOC injoignable ne doit rien perdre
D4 Echantillonnage reglable par drain S Tenir la charge sans tout jeter
D5 Evenement de test a la demande S Prouver au client que le drain marche
D6 Metriques par drain (envoye, en echec, en attente) S Voir la sante du tuyau
D7 Redaction (IP tronquee, en-tetes sensibles) S Minimisation avant export
D8 Archivage froid en Parquet M Garder un an sans garder un an de base

E. Bus et fiabilite

# Proposition Effort Pourquoi
E1 Bus Iggy derriere une interface M Decoupler bord et consommateurs
E2 Sujets security.events, decisions, audit S Trois volumes, trois retentions
E3 Cle d'idempotence (UUID v7) S Rejouer sans doubler
E4 Groupes de consommateurs et offsets M Plusieurs lecteurs independants
E5 Repli HTTP si le bus tombe S Le bord ne s'arrete jamais
E6 Comparaison mesuree Iggy / NATS / Redpanda M Ne pas choisir sur une promesse

F. L4 et protocoles

# Proposition Effort Pourquoi
F1 Ecouteurs TCP dans EdgeSite M Bases de donnees, SSH, MQTT
F2 Ecouteurs UDP (DNS, QUIC) M Sans connexion, donc regles par 5-uplet
F3 Routage gRPC (h2c, sante, retries) S Le protocole par defaut des API internes
F4 Passe-plat TLS avec routage par SNI M Ne pas terminer le TLS d'un client
F5 Decision L4 (reputation, debit, JA4T) M Le WAF ne voit rien en L4
F6 Protection contre l'amplification (UDP) M Ne pas devenir un reflecteur
F7 PROXY protocol vers l'amont S Garder l'adresse reelle du client
F8 Limitation de connexions et delais par ecouteur S Tenir une attaque par epuisement

G. Console et experience

# Proposition Effort Pourquoi
G1 Analyse par dimension (regle, pays, AS, empreinte) M La page qui manque le plus
G2 Enquete sur une requete bloquee M Voir le contexte, pas juste la ligne
G3 Editeur de politique avec apercu du diff L Configurer sans craindre de casser
G4 Gestion des faux positifs (exclure une regle) S Le quotidien d'un infogerant
G5 Journal d'audit des actions d'administration S Qui a desactive quoi
G6 Export CSV et PDF d'un rapport d'incident S Ce que demande le client final
G7 Tableau de bord par organisation pour l'infogerant M Vendre a un revendeur, pas a un site
G8 Notifications (courriel, webhook, ntfy) S Personne ne regarde une console en permanence

H. Exploitation et securite de la plateforme

# Proposition Effort Pourquoi
H1 Deux repliques Overwatch et base en HA M Ne pas perdre la console en meme temps que le bord
H2 Sauvegarde et restauration verifiees M Une base perdue, c'est un client perdu
H3 Rotation des secrets automatisee M Lecons des fuites de jetons
H4 Chiffrement au repos des journaux S Donnees personnelles dans les URL
H5 Retention par organisation S Le contrat, pas un reglage global
H6 Tests de charge du bord (req/s, latence) M Connaitre sa limite avant le client
H7 Exercice d'attaque annuel M Prouver la resistance, pas la supposer
H8 Page de statut et SLA mesures M Argument commercial

I. Produit et commercial

# Proposition Effort Pourquoi
I1 Offre par site, pas par requete S Lisible pour une PME
I2 Marque blanche (logo, domaine, courriels) M Vendre aux infogerants
I3 Essai sans carte, 14 jours S Le seul modele qui convertit
I4 Rapport mensuel automatique M Justifier l'abonnement
I5 Grille de revente (marge par site) S Interesser un integrateur
I6 Page de transparence (sous-traitants, hebergement) S Argument souverainete

4. La suite JA4+ dans le produit

Ce que c'est

Neuf empreintes, chacune decrivant une couche differente de la connexion :

  • JA4 : ClientHello TLS (version, chiffrements, extensions, ALPN). La plus utile au quotidien.
  • JA4S : ServerHello, donc l'empreinte de notre propre reponse. Sert a reperer les clients qui ne suivent pas le protocole.
  • JA4H : requete HTTP normalisee (methode, version, en-tetes dans l'ordre, cookies, langue). Distingue un vrai navigateur d'un script qui copie son en-tete User-Agent.
  • JA4T / JA4TS : pile TCP (fenetre, options, TTL). Demande de voir le premier paquet, donc pas depuis un proxy applicatif : eBPF, nftables ou Zeek.
  • JA4X : certificat X.509, utile en mTLS pour identifier un partenaire.
  • JA4SSH : session SSH.
  • JA4L / JA4LS : latence et distance estimees.
  • JA4D : DHCP.

Ce que nous pouvons capturer, et ou

  • JA4 : oui, au terminateur TLS. Envoy expose %TLS_JA4_FINGERPRINT% comme operateur de commande dans les journaux d'acces. C'est la premiere brique, elle ne coute rien.
  • JA4H : a calculer nous-memes dans le decideur a partir des en-tetes recus. Envoy ne le fournit pas.
  • JA4S : necessite de calculer sur la reponse ; possible dans le plugin wasm cote reponse, plus rarement utile.
  • JA4T : impossible depuis un proxy applicatif. Il faut un programme eBPF sur le noeud (Cilium peut exporter les paquets) ou un agent dedie.
  • JA4X : possible en mTLS, le certificat client est disponible au terminateur.

Licence, point bloquant a traiter avant de vendre

  • JA4 (ClientHello) est publie sous licence BSD-3 : utilisation libre.
  • JA4S, JA4H, JA4X, JA4T, JA4TS, JA4SSH, JA4L, JA4D sont sous FoxIO License 1.1, avec brevet en cours. La licence autorise l'usage interne et la recherche, mais une licence commerciale (OEM) est requise pour integrer ces empreintes dans un produit vendu.
  • Consequence : soit on prend la licence OEM aupres de FoxIO, soit on se limite a JA4 (BSD) et a nos propres calculs pour JA4H (une normalisation de requete est facile a reecrire, sans copier leur code).
  • A verifier avant tout engagement commercial : demander un devis, et documenter la reponse. C'est exactement le genre de dependance qui casse un contrat de revente six mois plus tard.

Mise en oeuvre, ce qui a ete appris

  • %TLS_JA4_FINGERPRINT% rend null tant que l'inspecteur TLS ne le demande pas. L'operateur existe, la configuration est acceptee, et le champ reste vide. Il faut poser enable_ja4_fingerprinting: true sur envoy.filters.listener.tls_inspector (EnvoyFilter LISTENER, contexte GATEWAY). Une valeur nulle est pire qu'une cle absente : on croit la donnee presente.
  • %TLS_VERSION% n'existe pas comme operateur de journal d'acces : Envoy rejette l'ecouteur entier et le proxy garde silencieusement l'ancien format. Le symptome est un journal qui ne change pas, pas une erreur visible.
  • Le journal doit etre JSON avec des cles nommees : le collecteur fusionne l'objet (Merge_Log) et le decideur lit des champs, pas une ligne a decouper.
  • Fluent Bit transmet tel quel : aucun changement de configuration n'a ete necessaire une fois le champ present dans la ligne.
  • Cout : nul en CPU mesurable. L'empreinte est calculee une fois par connexion.

Ce qu'on en fait

  • Un client qui se declare Firefox mais dont l'empreinte TLS est celle de Go ou de Python est un robot. C'est la regle la plus rentable, et elle est gratuite.
  • Une meme empreinte vue sur cinquante adresses differentes est un reseau de machines. Une meme adresse qui change d'empreinte a chaque requete est un outils de rotation.
  • Une empreinte inconnue, jamais vue, sur un site a faible trafic, merite un challenge, pas un blocage.
  • Stockage : table dans Valkey, cle = empreinte, valeur = compteurs (premiere vue, derniere vue, nombre d'adresses, nombre de sites), duree de vie 30 jours. Cardinalite bornee : une empreinte fait 36 caracteres, on en voit quelques milliers par jour.
  • Pieges : HTTP/3 ne passe pas par le meme chemin (QUIC, donc autre empreinte) ; un proxy d'entreprise reutilise la meme empreinte pour des milliers d'utilisateurs ; les mobiles changent d'empreinte a chaque mise a jour. Une empreinte seule ne condamne jamais : elle pese dans un score.

5. Drains de journaux vers un SOC, au format OpenTelemetry

Modele

Un drain est une destination declaree par organisation : type (otlp-grpc, otlp-http, webhook), adresse, en-tetes d'authentification, jeu de champs, filtre, echantillonnage, etat.

Traduction vers OTLP

  • resource : service.name=edge, service.namespace=<organisation>, exoledge.site=<domaine>, exoledge.region=<region>, host.name=<noeud>.
  • scope : exoledge.edge version du composeur.
  • logRecord : timeUnixNano (instant de la decision), severityNumber derive de l'action (block = WARN, challenge = INFO, allow = DEBUG), severityText, body = phrase lisible, attributes = la fiche structuree (section 7).
  • Identifiants de trace : si la requete porte un traceparent, on le propage. Un SOC peut ainsi relier l'attaque a la trace applicative.

Livraison

  • gRPC en priorite (protobuf, compression gzip), HTTP/protobuf en repli pour les SOC qui n'ouvrent que 443.
  • Lots de 512 evenements ou 5 secondes, tampon disque de 1 Go, reprise avec attente exponentielle (1 s, 2 s, 4 s, jusqu'a 5 min), plafond de concurrence.
  • Ne jamais bloquer le bord : le drain lit depuis le bus, jamais depuis le chemin de la requete. Si le SOC tombe, on perd du journal, jamais du trafic.
  • Mesures exposees : evenements produits, envoyes, en echec, en attente, age du plus ancien evenement en tampon.

Choix des champs et minimisation

Par defaut : domaine, instant, action, regle, pays, AS, empreinte, methode, chemin tronque, code de reponse. Pas d'adresse IP complete vers un tiers sans accord explicite : proposer l'adresse tronquee (192.0.2.0/24) ou un hachage avec sel par organisation. C'est la difference entre un produit vendable en Europe et un incident RGPD.


6. Un bus de messages : Iggy

Pourquoi

Aujourd'hui, Fluent Bit pousse vers /v1/ingest en HTTP. Un seul consommateur, aucun rejeu, aucune reprise si la console tombe. Des qu'on ajoute un drain SOC, un export analytique et un detecteur d'anomalies, il faut un bus : plusieurs lecteurs independants, un rejeu apres incident, une retention par sujet.

Pourquoi Iggy

  • Ecrit en Rust, un seul binaire, faible empreinte memoire : coherent avec le reste du produit.
  • Modele simple : flux, sujets, partitions, groupes de consommateurs, offsets.
  • Protocoles TCP, QUIC et HTTP : un SOC peut lire en HTTP sans client special.
  • Licence Apache 2.0.

Topologie proposee

  • Flux edge, sujets :
  • security.events : une entree par decision, retention 72 h, volume eleve.
  • decisions : une entree par sanction, retention 90 jours, volume faible, compacte par cle (adresse, portee).
  • audit : actions d'administration, retention un an, jamais compacte.
  • Producteur : le decideur au bord, en ecriture asynchrone avec tampon borne. Si le bus est plein, on echantillonne, on ne bloque pas.
  • Consommateurs : Overwatch (affichage et base), drainer OTLP, export froid, detecteur de motifs.

Reserves, a lever par la mesure

  • Iggy est un projet jeune (Apache, en incubation). Pas d'ecosysteme, peu de retours de production a grande echelle. Il faut mesurer : 50 000 evenements par seconde, latence au 99e centile, comportement quand un consommateur est lent, reprise apres arret brutal.
  • Comparer avec NATS JetStream (mature, tres leger, Rust possible via client) et Redpanda (compatible Kafka, plus lourd). Le choix doit se faire sur des chiffres, pas sur l'enthousiasme.
  • Garder une interface interne (publish, subscribe, commit) pour pouvoir changer de bus sans toucher au bord.

7. Journal de securite structure, inspire de CrowdSec

Le defaut actuel

Nos lignes de journal melangent trois choses : la requete, la decision et la sanction. Impossible de repondre proprement a "combien de fois cette regle a bloque ce pays cette semaine" sans analyser du texte.

Le modele

Une entree = un evenement de decision. Champs fixes, pas de dictionnaire libre.

{
  "id": "018f3c2e-7b41-7c9a-9d0e-2f6b1a5c8e44",
  "time": "2026-10-20T09:14:03.412Z",
  "organisation": "acme",
  "site": "www.acme.fr",
  "kind": "decision",
  "action": "challenge",
  "score": 45,
  "scenario": "http_probing",
  "rule": "930120",
  "rule_message": "OS File Access Attempt",
  "phase": "request_headers",
  "source": {
    "ip": "203.0.113.42",
    "asn": 64500,
    "as_org": "Example Hosting",
    "country": "NL",
    "range": "203.0.113.0/24",
    "reputation": { "tor": false, "proxy": true, "cve": false, "lists": ["proxies"] }
  },
  "client": {
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
    "ja4": "t13d1516h2_8daaf6152771_02713d6af862",
    "ja4h": "ge11nn050000_9f8a3d2c11b0",
    "coherent": false,
    "clearance": false
  },
  "request": {
    "method": "GET",
    "path": "/.env",
    "query_keys": ["debug"],
    "host": "www.acme.fr",
    "bytes": 412,
    "status": 403
  },
  "decision": {
    "type": "challenge",
    "scope": "ip",
    "value": "203.0.113.42",
    "duration_s": 1800,
    "origin": "edge"
  },
  "latency_ms": 3.1,
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}

Regles de conception

  • Un identifiant stable (UUID v7, trie par temps) sert de cle d'idempotence dans le bus et en base.
  • scenario decrit la famille (http_probing, sqli, credential_stuffing, cve_2025_55182), rule la regle technique qui a declenche. Deux niveaux, comme CrowdSec : l'alerte parle au metier, la regle parle au moteur.
  • action est le resultat : allow, challenge, throttle, block, log_only. Distinct de decision.type qui est la sanction posee, avec sa duree. Une requete peut etre bloquee sans qu'une sanction soit enregistree.
  • Pas de corps de requete, pas d'en-tete Authorization, pas de cookie. On garde les cles de requete, jamais les valeurs sensibles.
  • Adresse : tronquee dans les exports tiers, complete en base locale avec duree de vie.
  • Cardinalite bornee : les etiquettes de metriques sont rule, action, country, site. Jamais le chemin brut.

Stockage

  • PostgreSQL en JSONB, table partitionnee par jour, index sur site, time, source.ip, rule.
  • 30 jours chauds en base, un an en Parquet dans un stockage objet, restauration a la demande.
  • Overwatch : nouvelle page /events avec les memes filtres que le flux actuel, plus une vue par scenario et une vue par adresse.

Ce que cela debloque

  • Repondre a "pourquoi cette requete a ete bloquee" avec la regle exacte.
  • Alimenter un SIEM sans lui imposer une analyse de texte.
  • Comparer deux semaines, deux sites, deux organisations.
  • Facturer sur des faits mesures.

8. TCP, UDP et gRPC

Ce qu'Istio sait faire

  • La porte accepte des ecouteurs HTTP, HTTPS, TLS (passe-plat), TCP, UDP. TCPRoute et UDPRoute sont dans le canal experimental de Gateway API : il faut installer les CRD correspondantes (deja installees pour HTTPRoute).
  • gRPC ne demande rien de special : c'est du HTTP/2, donc un HTTPRoute avec appProtocol: kubernetes.io/h2c cote service. Les delais, les reprises et la duplication de trafic fonctionnent comme en HTTP.
  • Passe-plat TLS : l'ecouteur TLS avec mode: Passthrough route par SNI, sans terminer la connexion. On perd l'inspection HTTP mais on garde JA4 du ClientHello, ce qui est deja beaucoup.

Ce que cela impose

  • En L4, pas de chemin, pas d'en-tete, pas de WAF. La decision se limite a l'adresse, a la reputation, au debit de connexions et a l'empreinte TCP. La console doit le dire clairement : afficher "le WAF ne voit pas ce flux" evite une fausse impression de protection.
  • UDP n'a pas de connexion : compter par 5-uplet sur une fenetre courte, et reflechir a l'amplification (une reponse DNS peut etre cinquante fois la requete). Un service UDP expose sans limite devient un reflecteur.
  • Le PROXY protocol est necessaire si l'amont veut l'adresse reelle du client.
  • Un ecouteur TCP qui termine le TLS doit avoir son certificat ; un ecouteur en passe-plat n'en a pas besoin.

Modele dans EdgeSite

spec:
  listeners:
    - name: grpc-api
      protocol: HTTP
      port: 443
      hostname: api.acme.fr
      http:
        appProtocol: kubernetes.io/h2c
        timeout: 30s
        retries: 2
    - name: pg
      protocol: TCP
      port: 5432
      hostname: db.acme.fr
      tcp:
        upstream: postgres
        port: 5432
        proxyProtocol: true
        maxConnections: 200
    - name: dns
      protocol: UDP
      port: 53
      udp:
        upstream: dns-svc
        port: 53
        ratePerSecond: 500

L'operateur rend un ecouteur de porte par entree, une route HTTPRoute, TCPRoute ou UDPRoute selon le protocole, et une politique de debit L4 quand elle est demandee.

Ordre de mise en oeuvre

  1. gRPC (aucune brique nouvelle).
  2. TCP avec upstream simple, sans passe-plat.
  3. Passe-plat TLS par SNI.
  4. UDP avec limitation par 5-uplet.
  5. Decision L4 branchee sur la reputation et JA4T.

9. Feuille de route

Phase 1, deux semaines, ce qui rend le produit utilisable Finaliseur, status.features[], evenements Kubernetes, validation CEL, defauts dans le CRD (A1-A5, A7). Schema d'evenement de securite et page /events (7). Drain OTLP v1 en gRPC avec tampon et evenement de test (D1, D3, D5). gRPC et TCP simple dans EdgeSite (F1, F3). JA4 dans le journal (C1).

Phase 2, trois semaines, ce qui le rend vendable Bus Iggy derriere une interface, avec mesure face a NATS (E1-E6). JA4H calcule maison, reputation d'empreinte partagee (C2, C6). Drains par organisation avec choix des champs et redaction (D2, D4, D7). Analyse par dimension dans la console (G1). Passe-plat TLS et UDP limite (F4, F6).

Phase 3, un mois, ce qui le rend solide Rollout par vagues (A10), deux replicas et base en HA (A9, H1), archivage froid (D8), protection de compte (B5), simulateur de regles (B9), exercice d'attaque (H7), marque blanche (I2).

Ce qu'il ne faut pas faire tout de suite Un langage de politique maison (Coraza et les presets suffisent), un modele de machine learning au bord (aucune donnee, aucun gain demontre), du multi-region avant l'agent de distribution, un bus avant d'avoir mesure le volume reel.


10. Les trois decisions a prendre

  1. Licence JA4+ : payer l'OEM a FoxIO, ou se limiter a JA4 (BSD) et a nos calculs. A trancher avant la premiere vente, pas apres.
  2. Bus : Iggy si la mesure tient la charge, sinon NATS JetStream. Le choix se fait sur un banc d'essai, pas sur une preference.
  3. L4 : couvrir TCP et gRPC vite, UDP plus tard, et toujours dire au client ce que le WAF ne voit pas.