Tutoriels

Centraliser les logs firewall de plusieurs serveurs Linux sans stack ELK

5 septembre 2026 · 10 min de lecture
Illustration immersive du sujet : logs firewall centralisés

Les logs firewall centralisés ont longtemps été l'apanage de stacks lourdes : ELK (Elasticsearch, Logstash, Kibana), Splunk ou Graylog. En 2026, cette approche montre ses limites : coût d'infrastructure, complexité opérationnelle, latence d'indexation et ressources CPU/RAM démesurées. Pourtant, centraliser les journaux de pare-feu reste indispensable pour auditer les menaces, corréler les attaques distribuées et satisfaire les exigences de conformité. Cet article démontre qu'une architecture moderne — XDP/eBPF pour la capture kernel-level, nftables pour le filtrage stateful, et TimescaleDB pour le stockage de séries temporelles — permet de traiter des millions de paquets par seconde tout en exposant des métriques temps réel, sans les inconvénients des moteurs de recherche full-text.



Pourquoi les stacks ELK échouent pour les logs firewall à haute fréquence

Elasticsearch a été conçu pour l'indexation full-text, pas pour l'ingestion continue de dizaines de millions d'événements réseau par jour. Trois goulets d'étranglement structurels :

  • Indexation synchrone : chaque paquet loggé génère un document JSON, induit un refresh du segment Lucene et sollicite le JVM heap. Sur un serveur de jeu DDoSé à 5 M pps, l'indexation devient le goulot.
  • Coût de stockage : un événement firewall (timestamp, IP source, port, action) pèse ~400 octets une fois indexé (métadonnées + inverted index). Avec 10 M paquets/jour, comptez 4 Go/jour de stockage SSD rapide, multiplié par le facteur de réplication.
  • Requêtes agrégées : extraire "top 10 IPs sources sur 7 jours" nécessite une aggregation bucket sur des milliards de documents. Latence multi-secondes garantie, même avec des shards correctement distribués.

Face à ces limites, de nombreux sysadmins activent le rate-limit de logging (limit rate 10/second burst 50 dans nftables) et sacrifient la granularité. Résultat : un attaquant intelligent disperse ses paquets sous le seuil, et l'audit post-mortem devient aveugle.



Architecture moderne : XDP + nftables + TimescaleDB

Capture kernel-level avec XDP/eBPF

XDP (eXpress Data Path) intercepte les paquets avant la stack TCP/IP, directement dans le driver réseau. Un programme eBPF stateless décide en sub-microseconde de l'action (XDP_DROP, XDP_PASS, XDP_TX) et incrémente des compteurs dans des BPF maps. Ces compteurs — par port, par règle, par adresse IP — sont lus en userspace sans copie mémoire coûteuse.

// Exemple simplifié : incrémenter un compteur par port destination
struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __type(key, __u32);
    __type(value, __u64);
    __uint(max_entries, 65536);
} port_stats SEC(".maps");

SEC("xdp")
int pakkt_filter(struct xdp_md *ctx) {
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;
    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end) return XDP_DROP;
    
    // Parser IPv4, TCP/UDP...
    __u32 dport = /* extraction */ ;
    __u64 *count = bpf_map_lookup_elem(&port_stats, &dport);
    if (count) __sync_fetch_and_add(count, 1);
    
    return XDP_PASS;
}

Cette approche capture les métriques sans générer de log par paquet. Seuls les compteurs agrégés sont exportés, typiquement toutes les 5 ou 30 secondes.

Firewall stateful avec nftables

XDP étant stateless, il ne peut pas inspecter les drapeaux TCP (SYN, ACK, RST) ni maintenir un état de connexion. C'est le rôle de nftables, qui opère au niveau de Netfilter (post-routing) avec conntrack. Une règle typique de rate-limit par connexion :

nft add rule inet pakkt input tcp dport 25565 ct state new \
  limit rate 50/second burst 100 counter accept

Le compteur intégré (counter) incrémente sans écrire de log. Pour les événements critiques (DROP sur IP blacklistée, dépassement de quota), on active un log ciblé :

nft add rule inet pakkt input ip saddr @blacklist counter log prefix "PAKKT_BL " drop

Ces logs sont capturés par rsyslog/journald, filtrés par préfixe, et envoyés vers le collecteur central. Volume : quelques dizaines de lignes par seconde, au lieu de millions.

Stockage de séries temporelles avec TimescaleDB

TimescaleDB est une extension PostgreSQL qui partitionne automatiquement les tables par intervalle de temps (chunks de 1 jour par défaut). Deux avantages décisifs :

  • Insertion hyper-rapide : pas d'inverted index, pas de JVM, écritures séquentielles sur disque. Un serveur TimescaleDB sur SSD NVMe ingère 500k rows/s sans tuning exotique.
  • Compression native : les chunks de plus de 7 jours sont compressés (ratio ~10:1) et archivés sur stockage froid. Une requête SELECT avg(packets_dropped) FROM firewall_events WHERE time > now() - interval '30 days' reste sub-seconde grâce à l'indexation temporelle (BRIN).

Schéma de table exemple :

CREATE TABLE firewall_events (
  time        TIMESTAMPTZ NOT NULL,
  agent_id    UUID NOT NULL,
  src_ip      INET,
  dst_port    INTEGER,
  action      TEXT,
  packets     BIGINT,
  PRIMARY KEY (time, agent_id)
);

SELECT create_hypertable('firewall_events', 'time');
CREATE INDEX idx_agent_time ON firewall_events (agent_id, time DESC);

L'agent PAKKT lit les BPF maps toutes les 30 secondes, agrège les deltas par port/règle, et envoie un batch JSON via mTLS au panel central. Le panel insère en bulk dans TimescaleDB. Latence end-to-end : < 35 secondes entre le paquet capturé et son apparition dans le dashboard.



Centralisation multi-serveurs : architecture PAKKT

Dans un environnement de production (cluster de serveurs de jeu, ferme web, infrastructure multi-site), chaque machine exécute un agent léger qui :

  • Charge le programme XDP unique (pakkt_engine.bpf.o) sur l'interface publique via ip link set dev eth0 xdp obj.
  • Applique les règles nftables dans la table isolée inet pakkt, sans conflit avec Docker (table nat), fail2ban (table filter chain INPUT) ou iptables-persistent.
  • Collecte les métriques XDP (BPF maps) et nftables (compteurs de règles) toutes les 30 s.
  • Envoie les deltas vers le panel via HTTPS + authentification mTLS (certificat client intégré, rotation automatique).

Le panel centralise les données de tous les agents dans TimescaleDB, expose un dashboard temps réel (GeoIP, top IPs sources, top pays, métriques par port/règle), et conserve un audit log immuable. Exemple de requête typique :

SELECT
  time_bucket('5 minutes', time) AS bucket,
  dst_port,
  sum(packets) AS total_packets
FROM firewall_events
WHERE agent_id = 'uuid-serveur-jeu-1'
  AND time > now() - interval '1 hour'
GROUP BY bucket, dst_port
ORDER BY bucket DESC;

Cette requête s'exécute en < 50 ms sur un dataset de 100 M rows (30 jours de logs pour 10 agents), grâce à la compression et aux index BRIN. Pour comparaison, la même agrégation dans Elasticsearch (bucket aggregation sur 100 M documents) prend 3–8 secondes et consomme plusieurs Go de heap.

Intégrations panels tiers

PAKKT s'intègre nativement à Pterodactyl v1.x (panel de gestion de serveurs de jeu) : chaque serveur peut activer/désactiver des règles XDP ou blacklister des IPs depuis l'interface Pterodactyl, via l'API publique PAKKT. Les logs de l'agent sont remontés dans l'onglet "Logs" du serveur, permettant à l'hébergeur de facturer la protection comme addon. Intégrations Pelican et WHMCS prévues Q2 2026. Détails sur les intégrations PAKKT.



Comparaison chiffrée : ELK vs architecture moderne

Critère ELK (Elasticsearch + Logstash + Kibana) XDP + nftables + TimescaleDB
Ingestion (logs/s) ~10k logs/s par nœud (JVM heap 8 Go) 500k rows/s (insert bulk, CPU 1 core)
Stockage (100 M événements) ~40 Go indexé (SSD rapide requis) ~4 Go compressé (chunk > 7 jours)
Latence requête agrégée (30 jours) 3–8 s (aggregation bucket) < 50 ms (time_bucket + BRIN index)
RAM agent de collecte Logstash : 512 Mo–1 Go Agent Go : < 5 Mo (mTLS + heartbeat)
Impact CPU sur serveur protégé Filebeat + rate-limit logs : ~2–5 % XDP + agent PAKKT : < 1 %

Ces chiffres sont issus de benchmarks internes sur serveur bare-metal (Xeon E-2388G, 64 Go RAM, SSD NVMe). Le gain principal se situe sur la latence d'indexation et le coût de stockage : TimescaleDB compresse les chunks anciens à un ratio de 10:1, contre aucun mécanisme natif de compression dans Elasticsearch (nécessite snapshot vers S3 + restauration manuelle).



Conformité et audit : logs immuables sans surcoût

Les normes PCI-DSS, ISO 27001 et HDS imposent la conservation des logs de sécurité pendant 1 à 3 ans, avec garantie d'intégrité (non-altération). Avec Elasticsearch, cela implique :

  • Snapshot quotidien vers S3 ou stockage objet (coût de transfert + stockage).
  • Restauration manuelle d'index ancien pour requêter au-delà de la fenêtre active (opération lourde).
  • Aucun mécanisme natif d'audit trail : un administrateur peut supprimer un document sans trace.

TimescaleDB, étant PostgreSQL, bénéficie de :

  • WAL (Write-Ahead Log) natif : chaque INSERT est journalisé, réplication en streaming possible vers un standby en lecture seule.
  • Compression continue : les chunks > 7 jours sont compressés automatiquement, sans snapshot manuel. Requêtes sur données compressées transparentes.
  • pg_audit : extension qui trace toute opération DDL/DML (INSERT, DELETE, TRUNCATE) dans un log immuable, signable via syslog-ng + serveur distant.

Exemple de politique de rétention automatisée :

SELECT add_retention_policy('firewall_events', INTERVAL '90 days');
-- Les chunks > 90 jours sont supprimés automatiquement
-- Pour conserver 1 an : INTERVAL '365 days', puis archivage S3 via pg_dump

Pour les audits forensiques post-incident, une requête SQL standard suffit :

SELECT time, src_ip, dst_port, action, packets
FROM firewall_events
WHERE agent_id = 'uuid-serveur-compromis'
  AND time BETWEEN '2026-03-15 14:00' AND '2026-03-15 15:00'
  AND action = 'DROP'
ORDER BY time ASC;

Aucun besoin de restaurer un snapshot, aucune latence d'indexation : le résultat est immédiat. L'auditeur RSSI exporte en CSV ou JSON via COPY TO, signe le fichier avec GPG, et archive. Conformité PCI-DSS acquise.



Déploiement : de la VM unique au cluster multi-région

Cas 1 : serveur unique (TPE, communauté de jeu)

Agent PAKKT installé sur la machine de jeu, panel hébergé en SaaS. L'agent charge le programme XDP, applique les règles nftables, et envoie les métriques toutes les 30 s. Dashboard accessible via PAKKT.io, tarif 3 €/mois (essai gratuit 7 jours sur le premier agent). Zéro infrastructure additionnelle à gérer : TimescaleDB, GeoIP et frontend sont managés.

Cas 2 : cluster de serveurs (hébergeur, ESport)

10–50 agents sur des machines dédiées. Chaque agent remonte ses métriques vers le panel central. Le panel agrège les données par région, par type de serveur (Minecraft, CS2, Rust), et expose des vues consolidées. Règles XDP et blacklists IP synchronisées automatiquement : une IP blacklistée sur le serveur A est propagée à B, C, D en < 60 s (via BPF map update + heartbeat).

Cas 3 : multi-région avec réplication

Hébergeur avec datacenters en Europe, Amérique du Nord et Asie. Un panel PAKKT par région (self-hosted possible via licence entreprise, roadmap Q3 2026), chaque panel écrit dans son instance TimescaleDB locale. Réplication logique PostgreSQL (pglogical ou wal2json) vers un data warehouse central pour les rapports cross-région. Latence de réplication : < 5 s en fibre dédiée.

Techniquement, rien n'empêche de router tous les agents vers un panel unique, mais la latence mTLS transatlantique (80–120 ms RTT) retarde le heartbeat. Architecture recommandée : panel régional + réplication asynchrone pour l'analytique globale.



Limitations et frontières techniques

Cette architecture n'est pas une solution miracle universelle. Quatre points de vigilance :

  • Pas de DPI (Deep Packet Inspection) : XDP et nftables opèrent en L2/L3/L4. Pour détecter une attaque applicative (exploit Minecraft, flood HTTP/2), il faut une sonde L7 (Suricata, Zeek) en amont ou un WAF.
  • Pas de scrubbing cloud : PAKKT protège sur le serveur. Une attaque saturant la bande passante en amont (100 Gbps) doit être mitigée par le datacenter ou un service de scrubbing (OVH VAC, Cloudflare Magic Transit). PAKKT devient alors la seconde ligne de défense, filtrant les reliquats et les attaques low-and-slow.
  • Rate-limit stateless en pps uniquement : le PAKKT Engine XDP rate-limite par paquets (max_pps, max_port_pps). Pour un rate-limit en octets (Mbps), utiliser nftables avec limit rate 100 mbytes/second.
  • Linux uniquement : agent compatible noyau 5.x ou supérieur avec support XDP (la majorité des distributions depuis 2020). Pas de support Windows, BSD ou macOS.

Pour approfondir les spécifications kernel XDP, consulter la documentation officielle kernel.org.



Conclusion

Centraliser des logs firewall sans ELK est non seulement possible en 2026, c'est devenu la norme pour les infrastructures exigeantes. XDP/eBPF capture les métriques au plus près du matériel, nftables applique le filtrage stateful avec des compteurs légers, et TimescaleDB stocke les séries temporelles avec une compression 10:1 et des requêtes sub-secondes. Cette stack réduit le coût d'infrastructure de 70 % (pas de cluster Elasticsearch multi-nœuds), divise par 10 la latence d'indexation, et simplifie radicalement l'audit de conformité. Les logs firewall centralisés deviennent un actif stratégique, interrogeable en SQL, sans sacrifier la performance ni la granularité.



FAQ

Peut-on migrer des logs Elasticsearch existants vers TimescaleDB sans perte ?

Oui. Exportez les index Elasticsearch en JSON via l'API _search avec scroll, transformez les documents en rows SQL (script Python + psycopg2), puis insérez en bulk dans TimescaleDB. Pour 100 M documents, comptez 2–4 heures sur SSD NVMe. Attention : les champs full-text (message, stacktrace) doivent être stockés en JSONB ou TEXT, l'indexation Lucene disparaît (utilisez pg_trgm pour la recherche floue si nécessaire).

Comment garantir que les métriques XDP ne sont pas perdues entre deux collectes de l'agent ?

Les BPF maps de type PERCPU_ARRAY accumulent les compteurs par cœur CPU sans verrouillage. L'agent lit ces maps toutes les 30 s, calcule le delta depuis la lecture précédente, et réinitialise les compteurs (ou conserve un offset). Si l'agent crash, le prochain heartbeat détecte l'absence de données et déclenche une alerte. Les compteurs XDP étant en RAM kernel, un reboot les efface : pour la persistence, l'agent doit écrire les deltas sur disque avant envoi (optionnel, activable via flag --persist-metrics).

Quelle est la latence ajoutée par XDP sur le chemin des paquets légitimes ?

Un programme XDP optimisé ajoute < 0,1 µs par paquet sur CPU moderne (vérifier avec bpftool prog show et perf). Le PAKKT Engine, avec jusqu'à 256 règles en BPF map, reste sous 0,5 µs en moyenne (lookup hash map O(1), pas de boucle). Pour comparaison, nftables ajoute 1–3 µs (conntrack, NAT), et iptables legacy 5–10 µs. Impact sur la latence applicative (ping, jitter) : négligeable (< 1 % d'augmentation mesurée sur serveur Minecraft 200 joueurs).

Protégez vos serveurs

Déployez PAKKT en 30 secondes

Protection kernel double couche XDP + nftables, pilotable depuis un panel centralisé. Essai gratuit 7 jours.