#08 — rgz-ids
PLANIFIÉ
Priorité: 🔴 CRITIQUE · Type: TYPE A · Conteneur: rgz-ids · Code: config/suricata/
Dépendances: #07 rgz-gateway
Description
rgz-ids est le système de détection et prévention des intrusions (IDS/IPS) de la plateforme RGZ. Il tourne Suricata 7.x en mode inline (AF_PACKET), ce qui lui permet d'inspecter le trafic réseau en temps réel et d'agir directement sur les paquets (drop) sans passer par une copie mirrored. C'est un complément essentiel à rgz-gateway : là où le gateway applique des règles statiques de routage et de filtrage, rgz-ids détecte les comportements anormaux et les menaces dynamiques.
Suricata est configuré pour couvrir les vecteurs d'attaque les plus courants dans le contexte WiFi au Bénin. Les règles custom RGZ (config/suricata/rules/rgz_anomaly.rules) couvrent : la détection de MAC spoofing (un abonné qui usurpe la MAC d'un autre abonné authentifié), les tunnels DNS (exfiltration de données ou bypass du portail captif via des requêtes DNS volumineuses), les attaques brute-force sur les portails web, et les port scans. Les règles Emerging Threats et Pro sont également activées pour les signatures de malwares et exploits courants.
Les alertes Suricata sont exportées vers deux destinations : Prometheus (via suricata-exporter qui expose les métriques sur le port 9336) et ELK Stack (#40) via des logs JSON dans un volume partagé avec Logstash. L'outil #44 (anomaly-detection) utilise les métriques Suricata exposées dans Prometheus pour déclencher des alertes Grafana sur les pics de trafic suspects.
Le mode IPS (drop) est activé par défaut pour les signatures à haute confiance. Les règles personnalisées RGZ utilisent une politique d'action graduée : alert pour les comportements suspects (logging uniquement), drop pour les attaques avérées. Le personnel NOC peut ajuster les actions via l'interface Kibana en temps réel.
Architecture Interne
Trafic réseau (sur interface du host, partagée via net=host ou AF_PACKET)
│
▼
rgz-ids (Suricata 7.x)
│
├── Inspection inline AF_PACKET (mode IPS)
│ ├── Suricata lit les paquets avant qu'ils passent par nftables
│ └── Drop des paquets malveillants (IPS inline)
│
├── Règles actives:
│ ├── Emerging Threats Open (signatures communautaires)
│ ├── rgz_anomaly.rules (règles custom — MAC spoof, DNS tunnel, brute)
│ └── rgz_whitelist.rules (exceptions explicites)
│
├── Outputs:
│ ├── /var/log/suricata/eve.json → Logstash → ELK (#40)
│ ├── Metrics HTTP :9336 → Prometheus (#38) → Grafana (#37)
│ └── /var/log/suricata/fast.log → alertes rapides (texte)
│
└── Triggers anomaly-detection (#44):
├── Alert HIGH: MAC spoofing détecté
├── Alert HIGH: DNS tunnel suspect (>100 req/min)
├── Alert MEDIUM: Brute force portail (>10 tentatives/2min)
└── Alert LOW: Port scan interneConfiguration
Variables d'environnement
| Variable | Exemple | Description |
|---|---|---|
SURICATA_INTERFACE | eth1 | Interface réseau à inspecter |
HOME_NET | 10.100.0.0/8,172.23.0.0/16 | Réseaux internes RGZ |
EXTERNAL_NET | !$HOME_NET | Tout ce qui n'est pas HOME_NET |
SURICATA_LOG_DIR | /var/log/suricata | Répertoire des logs EVE JSON |
Fichiers de configuration
config/suricata/
├── suricata.yaml # Config principale Suricata
├── rules/
│ ├── rgz_anomaly.rules # Règles custom RGZ (#44)
│ ├── rgz_whitelist.rules # Exceptions (flux légitimes à ne pas bloquer)
│ └── local.rules # Règles de développement/test
└── threshold.conf # Seuils rate-limiting par règle (anti-noise)suricata.yaml (extraits clés)
# Mode AF_PACKET (IPS inline)
af-packet:
- interface: eth1
threads: auto
cluster-id: 99
cluster-type: cluster_flow
defrag: yes
use-mmap: yes
# Home network (réseaux internes RGZ)
vars:
address-groups:
HOME_NET: "10.100.0.0/8,172.23.0.0/16,127.0.0.1/8"
EXTERNAL_NET: "!$HOME_NET"
# Outputs EVE JSON (vers ELK via volume partagé)
outputs:
- eve-log:
enabled: yes
filetype: regular
filename: /var/log/suricata/eve.json
types:
- alert
- flow
- http
- dns
- tls
- stats
# Métriques Prometheus
- stats:
enabled: yes
interval: 10
# Règles à charger
rule-files:
- /etc/suricata/rules/rgz_anomaly.rules
- /etc/suricata/rules/rgz_whitelist.rules
- /var/lib/suricata/rules/emerging-threats.rules # si abonnement ET Prorgz_anomaly.rules (règles custom)
# Règle 1 — MAC Spoofing (abonné utilisant la MAC d'un autre abonné actif)
# Détection basique : même MAC sur deux IPs différentes dans HOME_NET
alert arp any any -> $HOME_NET any (msg:"RGZ MAC-SPOOF possible"; \
arp.opcode:2; flow:stateless; \
threshold:type both,track by_src,count 5,seconds 60; \
classtype:policy-violation; sid:9000001; rev:1;)
# Règle 2 — DNS Tunneling (requêtes DNS volumineuses ou longues)
alert dns $HOME_NET any -> any 53 (msg:"RGZ DNS-TUNNEL suspect - requete longue"; \
dns.query; content:"."; dns.query.length:>60; \
threshold:type threshold,track by_src,count 20,seconds 60; \
classtype:policy-violation; sid:9000002; rev:1;)
# Règle 3 — Brute force portail captif
alert http $HOME_NET any -> $HTTP_SERVERS $HTTP_PORTS \
(msg:"RGZ BRUTE-FORCE portail captif"; \
flow:to_server,established; http.method; content:"POST"; \
http.uri; content:"/api/v1/auth/otp/"; \
threshold:type both,track by_src,count 10,seconds 120; \
classtype:web-application-attack; sid:9000003; rev:1;)
# Règle 4 — Port scan interne
alert tcp $HOME_NET any -> $HOME_NET 1:1024 \
(msg:"RGZ PORT-SCAN interne detecte"; \
flags:S; flow:stateless; \
threshold:type both,track by_src,count 30,seconds 60; \
classtype:recon; sid:9000004; rev:1;)
# Règle 5 — Drop direct : connexions vers Tor known relays
drop ip any any -> [list_tor_exits] any \
(msg:"RGZ DROP TOR-EXIT connection"; \
classtype:policy-violation; sid:9000005; rev:1;)Métriques Exposées (Prometheus)
| Métrique | Type | Description |
|---|---|---|
suricata_alert_total | Counter | Nombre total d'alertes par signature |
suricata_drop_total | Counter | Paquets droppés par IPS |
suricata_flow_total | Counter | Flux réseau analysés |
suricata_dns_query_total | Counter | Requêtes DNS (pour détection tunnel) |
suricata_http_request_total | Counter | Requêtes HTTP analysées |
suricata_memory_bytes | Gauge | Mémoire utilisée par Suricata |
Healthcheck
# Vérifier que Suricata tourne
docker exec rgz-ids suricata --list-runmodes
# Vérifier les règles chargées
docker exec rgz-ids suricata --list-app-layer-protos
# Stats temps réel
docker exec rgz-ids suricatasc -c /var/run/suricata/suricata.socket dump-counters 2>/dev/null | head -30
# Vérifier la santé via l'API Unix socket
docker exec rgz-ids suricatasc -c /var/run/suricata/suricata.socket uptime
# Logs d'alertes (EVE JSON)
docker exec rgz-ids tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'Sécurité
| Règle | Implémentation |
|---|---|
| Mode IPS | AF_PACKET inline — drop direct sans contourner nftables |
| Règles graduées | alert (suspicious) vs drop (confirmed attack) — pas de faux positifs bloquants |
| HOME_NET | Définition stricte des réseaux internes pour éviter les alertes sur le trafic légitime |
| Whitelist | rgz_whitelist.rules — exclure les flux RADIUS, SNMP, CoA du scoring |
| Rate limiting règles | threshold.conf — éviter la tempête d'alertes sur pic de trafic normal |
Commandes Utiles
# Démarrage avec rebuild
docker compose -f /home/claude-dev/RGZ/docker-compose.core.yml up -d --build rgz-ids
# Logs Suricata
docker logs rgz-ids -f --tail=100
# Alertes récentes (dernières 50)
docker exec rgz-ids tail -n 50 /var/log/suricata/fast.log
# Alertes EVE JSON filtrées par gravité
docker exec rgz-ids cat /var/log/suricata/eve.json | \
jq 'select(.event_type=="alert" and .alert.severity==1)' | head -20
# Recharger les règles sans restart (live reload)
docker exec rgz-ids kill -USR2 $(docker exec rgz-ids cat /var/run/suricata/suricata.pid)
# Mettre à jour les règles Emerging Threats
docker exec rgz-ids suricata-update
# Tester une règle custom
docker exec rgz-ids suricata -T -c /etc/suricata/suricata.yaml \
-S /etc/suricata/rules/rgz_anomaly.rules
# Stats par interface
docker exec rgz-ids suricatasc -c /var/run/suricata/suricata.socket iface-listImplémentation TODO
- [x] Service défini dans
docker-compose.core.yml - [x] Volume logs partagé avec Logstash (ELK #40)
- [ ]
config/suricata/suricata.yaml— Config complète (AF_PACKET, HOME_NET, outputs) - [ ]
config/suricata/rules/rgz_anomaly.rules— 5+ règles custom (#44) - [ ]
config/suricata/rules/rgz_whitelist.rules— Exclusions RADIUS/SNMP/CoA - [ ]
config/suricata/threshold.conf— Rate limiting par SID - [ ] Intégration Prometheus (suricata-exporter ou output stats)
- [ ] Dashboard Grafana Suricata (#37) — alertes par type, tendances
- [ ] Tests règles custom (pcap replay avec tcpreplay)
- [ ] Validation mode IPS vs mode IDS (selon environnement)
Dernière mise à jour: 2026-02-21