Le récit d'ingénierie derrière AAGuard, notre service open source de protection. Pour les ingénieurs qui veulent comprendre la mécanique, pas seulement le marketing.
Le problème : la fenêtre de tir de l'attaquant
Un scanner naïf sonde votre infrastructure méthodiquement : .env, .git/config, wp-admin, les CVE connues, les webmails, les panneaux admin. Chaque requête prend quelques dizaines de millisecondes, et chaque requête est un signal que quelque chose ne tourne pas normalement.
Les outils classiques réagissent en deux temps, deux vitesses :
- L'analyste SOC : détecte le pattern au tableau de bord… entre 10 et 60 minutes plus tard. L'attaquant a déjà cartographié vos endpoints, testé vos CVE, trouvé la porte.
- L'IPS de firewall classique : réagit, mais sur des signatures lourdes, avec des règles centrées paquet, les scans à basse cadence (1 req/s sur 100 chemins distincts) passent entre les mailles.
La fenêtre de tir de l'attaquant, c'est le délai entre sa première requête et votre réponse. AAGuard a été conçu pour que cette fenêtre mesure ~6 millisecondes.
L'architecture : trois composants, deux hôtes
[hôte applications] [hôte firewall]
Apache / API / web /proc/net/nf_conntrack
sshd, logs NATS (poll 2s)
│ tail inotify │ collector
▼ ▼
Correlator HTTP ──── 6ms ────→ Correlator firewall
(signaux pondérés) (port scan, SYN flood,
│ conn flood, DDoS)
└────────→ NATS ←───────────────┘
│
▼
Consumer nftables
ban kernel-native, TTL 7j
│
┌──────────────┼──────────────┐
▼ ▼ ▼
AbuseIPDB RDAP/SMTP SQLite journal
(signal (abuse desk (tout conservé)
mondial) du FAI)
Deux hôtes, une seule connectique : NATS. L'hôte applicatif publie ses détections, l'hôte firewall les consomme et bannit au niveau kernel. Le même bus qui fait tourner le reste de la plateforme DalonCorp, une identification NSC, zéro connectique supplémentaire.
La mécanique : des signaux pondérés, pas des règles binaires
La faiblesse des IDS classiques : chaque règle déclenche ou ne déclenche pas. Résultat : les vrais scanners (lents, méthodiques) passent, les faux positifs (un script interne un peu bruyant) sont bannis.
AAGuard fonctionne autrement, par pondération accumulateur :
| Signal | Poids |
|---|---|
| Path de sonde connu (critical) | 1.0 → ban immédiat |
| Template Nuclei CVE (high) | 0.9 |
| User-agent scanner (high) | 0.9 |
| Rate excessif + 404s | 0.7-0.9 |
| Énumération webmail (medium) | 0.7 |
Le corrélateur additionne les poids par IP :
- seuil ≥ 0.5 → détection (un seul signal
highsuffit) - poids 1.0 → ban immédiat, première requête
- cooldown 30 s par IP : pas de double comptage
- allowlist IPv4/IPv6 : vos IP de monitoring et partenaires ne sont jamais suspects, quel que soit le trafic
C'est la différence entre un IDS qui crie et un système qui décide. Un scanner naïf (path de sonde seul : 0.9) est banni à la première requête. Un trafic ambigu accumule des preuves avant d'atteindre le seuil, les faux positifs n'ont pas d'espace de survie.
L'arme secrète : Nuclei en ingestion continue
AAGuard ne réinvente pas la détection CVE : il ingère les ~500 templates Nuclei (projectdiscovery) et en extrait automatiquement les chemins d'exploitation, des milliers de patterns actifs.
L'intelligence ajoutée :
- Corrélation par produit : vous associez chaque domaine au produit qui tourne dessus (
gitea.osef.cloud: "gitea",dalon.*: "meteor"). Les templates d'autres produits sont ignorés, plus de faux positifs Drupal sur Gitea, ni PaperCut sur Meteor. - Hot reload quotidien : systemd timer (3h),
SIGHUP, les nouveaux CVE du jour sont actifs sans redémarrage. - Filtrage par sévérité : critical/high/medium, seulement les templates vérifiés.
- Exclusions ciblées : les faux positifs identifiés sont blacklistés par ID de CVE (ex.
cve_2026_9082).
Le ban kernel-native : pourquoi nftables
Le ban classique (iptables via process) a trois faiblesses : visible par l'application (overhead), perdu au reboot (sauf script de restauration), et séquentiel (le kernel traite les règles l'une après l'autre).
L'approche nftables d'AAGuard :
- Sets kernel-native (
aaguard_banned_v4/aaguard_banned_v6) : le lookup est O(1) kernel-side, insensible au nombre d'IPs bannies (1 351 aujourd'hui, la limite est celle de la mémoire set) - Timeouts kernel : le TTL auto-expire dans le kernel, pas de timer applicatif à maintenir, pas de zombie ban si AAGuard s'arrête
- Persistence : les sets sont sauvegardés, un reboot n'efface pas la liste des attaquants
- Replay JetStream : en cas de redéploiement du firewall host, le Stream NATS rejoue les détections des dernières 24h, aucune IP ne revient par la porte
Le code est open source
Tout le code (détecteur, parser, corrélateur, consumer, CLI) est disponible :
gitea.osef.cloud/Dalon/aaguard
- Tests unitaires + RPC (NATS Embedded + JetStream)
- Benchmarks firewall + detector
- Docker compose pour déployer en 5 minutes
---
Cet article décrit la mécanique interne d'AAGuard. Pour le produit en tant que service : la page produit, ou la sécurité DalonCorp en 5 couches.
Pour aller plus loin
- Le produit AAGuard, la fiche vitrine
- La sécurité de bout en bout, les 5 couches defense-in-depth
- La proposition de valeur DalonCorp (PDF)