Skip to content

#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 interne

Configuration

Variables d'environnement

VariableExempleDescription
SURICATA_INTERFACEeth1Interface réseau à inspecter
HOME_NET10.100.0.0/8,172.23.0.0/16Réseaux internes RGZ
EXTERNAL_NET!$HOME_NETTout ce qui n'est pas HOME_NET
SURICATA_LOG_DIR/var/log/suricataRé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)

yaml
# 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 Pro

rgz_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étriqueTypeDescription
suricata_alert_totalCounterNombre total d'alertes par signature
suricata_drop_totalCounterPaquets droppés par IPS
suricata_flow_totalCounterFlux réseau analysés
suricata_dns_query_totalCounterRequêtes DNS (pour détection tunnel)
suricata_http_request_totalCounterRequêtes HTTP analysées
suricata_memory_bytesGaugeMémoire utilisée par Suricata

Healthcheck

bash
# 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ègleImplémentation
Mode IPSAF_PACKET inline — drop direct sans contourner nftables
Règles graduéesalert (suspicious) vs drop (confirmed attack) — pas de faux positifs bloquants
HOME_NETDéfinition stricte des réseaux internes pour éviter les alertes sur le trafic légitime
Whitelistrgz_whitelist.rules — exclure les flux RADIUS, SNMP, CoA du scoring
Rate limiting règlesthreshold.conf — éviter la tempête d'alertes sur pic de trafic normal

Commandes Utiles

bash
# 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-list

Implé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

PROJET MOSAÏQUE — 81 outils, 22 conteneurs, 500+ revendeurs WiFi Zone