Rate-limit par IP avec nftables : configurer limit rate proprement
Le limit rate nftables est un mécanisme kernel natif qui permet de restreindre le nombre de paquets ou de connexions qu'une adresse IP peut générer sur une période donnée, protégeant ainsi vos services critiques contre les abus, les scans de port et les attaques par saturation. Ce tutoriel 2026 vous montre comment configurer concrètement le rate-limiting par IP avec nftables, comprendre les différences entre les méthodes limit, meter et quota, et intégrer ces règles dans une architecture de protection kernel complète associant nftables stateful et XDP pour un filtrage haute performance.
Pourquoi limiter le débit par IP avec nftables ?
Les attaques modernes exploitent la capacité de connexion des serveurs exposés : scans de port automatisés, flood TCP SYN, brute-force SSH, requêtes applicatives massives. Un pare-feu stateful seul laisse passer tous les paquets valides jusqu'à saturation de la table de connexions (conntrack) ou des ressources CPU. Le rate-limiting par IP introduit une contrainte stricte : chaque adresse source ne peut dépasser un seuil défini, par exemple 50 nouvelles connexions par seconde ou 1 000 paquets UDP par minute.
Nftables offre trois primitives principales pour ce contrôle :
- limit : seuil global (toutes IPs confondues), simple mais ne distingue pas les sources.
- meter : structure de hachage noyau qui suit chaque IP indépendamment, avec burst et timeout automatiques.
- quota : compteur global fixe (octets ou paquets), rarement utilisé pour le per-IP.
Le choix classique pour protéger un service public est le meter, qui crée un compteur dynamique par adresse source, réinitialise automatiquement après la fenêtre temporelle, et supporte des seuils burst pour absorber les rafales légitimes. Contrairement à iptables (hashlimit), nftables optimise cette logique directement dans le noyau sans module supplémentaire.

Configurer un meter nftables pour limiter les nouvelles connexions par IP
La construction d'un meter dans nftables suit une syntaxe déclarative claire. Un meter associe une clé (par exemple l'adresse source IPv4) à un compteur de rate-limit. Voici la commande pour protéger un service TCP (port 25565, typique d'un serveur Minecraft) en autorisant chaque IP à ouvrir maximum 20 nouvelles connexions par seconde avec un burst de 50 connexions :
nft add rule inet pakkt input tcp dport 25565 ct state new \
meter minecraft_rate { ip saddr limit rate 20/second burst 50 packets } accept
Décomposition des éléments :
inet pakkt input: tableinet(IPv4+IPv6), chaîneinputdans la table isoléepakktpour éviter tout conflit avec Docker, fail2ban ou iptables-persistent.tcp dport 25565: filtre sur le port de destination TCP 25565.ct state new: ne compte QUE les nouvelles connexions (état SYN), pas les paquets établis ou reliés.meter minecraft_rate: nom arbitraire du meter, stocké en mémoire kernel.{ ip saddr limit rate 20/second burst 50 packets }: clé = adresse source IPv4, limite = 20 paquets/seconde avec burst de 50 (autorise une rafale ponctuelle jusqu'à 50 connexions simultanées, puis lissage à 20/s).accept: si le seuil n'est PAS dépassé, accepte le paquet ; sinon passe à la règle suivante (ou tombe sur la politique par défaut).
Pour IPv6, remplacez ip saddr par ip6 saddr. Pour couvrir les deux familles dans une seule règle (table inet), utilisez un meter distinct par famille ou un meta nfproto conditionnel.
Ajouter une action de drop explicite
Par défaut, si une IP dépasse son quota, le paquet continue le traitement des règles suivantes. Pour bloquer immédiatement les abus, chaînez un drop après le meter ou inversez la logique avec un compteur et un log :
nft add rule inet pakkt input tcp dport 25565 ct state new \
meter minecraft_rate { ip saddr limit rate over 20/second burst 50 packets } \
log prefix "PAKKT rate-limit: " drop
La syntaxe limit rate over inverse le test : si l'IP dépasse 20/s, le paquet matche, est loggué puis droppé. Cette approche facilite l'audit dans dmesg ou journalctl -k.
Rate-limit en paquets par minute pour UDP
Les services UDP sans état (DNS, SSDP, Game Query protocols) subissent souvent des amplifications DDoS. Limiter en paquets par minute offre une tolérance plus large :
nft add rule inet pakkt input udp dport 19132 \
meter bedrock_rate { ip saddr limit rate 300/minute burst 100 packets } accept
Chaque IP peut envoyer 300 paquets/minute (soit 5 paquets/seconde en moyenne) avec un burst de 100 paquets. Le noyau maintient un compteur par IP, expire automatiquement les entrées inactives après timeout (par défaut ~60 secondes pour nftables), et libère la mémoire.

Combiner rate-limit nftables et XDP pour une défense multi-couches
Nftables opère en couche 3/4 du modèle OSI, après allocation de la socket buffer (SKB) par le noyau. Un flood volumétrique (plusieurs millions de pps) sature déjà le CPU avant que nftables ne traite les paquets. C'est pourquoi PAKKT.io associe XDP (eXpress Data Path) en première ligne : filtrage au niveau pilote réseau, avant même la création du SKB, avec latence sub-microseconde par paquet.
Le PAKKT Engine, programme XDP unique chargé par interface (un seul xdp actif par carte), gère jusqu'à 256 règles pilotées par BPF maps : port range, protocole (TCP/UDP/ICMP/any), type de règle (block, rate_limit global en pps, allow_only), taille de paquet min/max. Les paquets légitimes passent (XDP_PASS) vers la pile réseau classique, où nftables applique ensuite le rate-limit par IP avec conntrack et meters.
Exemple d'architecture complémentaire
- Couche XDP (PAKKT Engine) : bloque tout paquet > 1 500 octets sur le port 25565 (anti-amplification), rate-limit global 500 000 pps sur ce port, drop des fragments IP.
- Couche nftables (table
inet pakkt) : meter 20 connexions/seconde par IP source (ct state new), conntrack pour suivre les flux établis, log des abus. - Blacklist/Whitelist : BPF map
pakkt_blacklistsynchronisée avec un set nftables@pakkt_blacklist, mise à jour temps réel via API ou panel.
Cette défense multi-couches traite les volumétriques (XDP), affine le contrôle par IP et par connexion (nftables), et centralise la gestion via l'agent PAKKT, qui s'intègre nativement à Pterodactyl v1.x pour appliquer des templates de protection par serveur de jeu.
Mesurer l'impact performance avec bpftool et nft
Pour auditer les métriques XDP en temps réel, utilisez :
bpftool prog show
bpftool map dump name pakkt_rules
Pour lister les meters nftables actifs et leurs compteurs :
nft list meter inet pakkt minecraft_rate
L'overhead CPU cumulé (XDP + nftables) reste typiquement < 1 % sur un serveur moderne avec rate-limit configuré. Le PAKKT Engine ajoute une latence négligeable (sub-microseconde) ; nftables ajoute quelques microsecondes par paquet pour le conntrack et le meter lookup, acceptable pour la majorité des services temps réel.
Ajuster les paramètres de burst et timeout selon le profil de trafic
Le paramètre burst définit la capacité du "seau de jetons" (token bucket) : combien de paquets peuvent passer simultanément avant que le rate-limit strict ne s'applique. Un burst trop faible bloque les rafales légitimes (connexion de plusieurs joueurs simultanés, requête API batch) ; un burst trop élevé laisse passer des micro-floods.
Recommandations par type de service
| Service | Rate (par IP) | Burst | Justification |
| SSH (22/tcp) | 5/minute | 3 packets | Usage humain, anti-brute-force strict. |
| HTTP/HTTPS (80,443/tcp) | 100/second | 200 packets | Navigation web, API publiques avec pics. |
| Serveur Minecraft (25565/tcp) | 20/second | 50 packets | Connexion simultanée de plusieurs clients. |
| DNS (53/udp) | 50/second | 100 packets | Requêtes répétées légitimes (résolution AAAA, A, TXT). |
| Query UDP jeu (19132, 27015) | 300/minute | 100 packets | Polling serveur, tolérance large pour éviter faux positifs. |
Pour ajuster dynamiquement le timeout des entrées meter (par défaut ~60s), nftables ne l'expose pas directement dans la syntaxe limit ; le noyau gère l'expiration automatique. Si vous devez un contrôle fin (par exemple, blacklist temporaire de 10 minutes après dépassement), combinez le meter avec un set dynamique et un update :
nft add set inet pakkt temp_blacklist { type ipv4_addr; flags dynamic,timeout; timeout 10m; }
nft add rule inet pakkt input tcp dport 25565 ct state new \
meter minecraft_rate { ip saddr limit rate over 20/second } \
add @temp_blacklist { ip saddr } drop
Ici, toute IP dépassant 20/s est ajoutée au set temp_blacklist avec timeout de 10 minutes, puis droppée immédiatement. Le set expire automatiquement l'entrée après 10 minutes.
Surveiller les abus en temps réel avec PAKKT
Le panel PAKKT centralise les métriques par port et par règle dans TimescaleDB : nombre de paquets droppés, top IPs sources, répartition géographique (carte monde GeoIP), historique sur 7/30/90 jours. Les logs internes de l'agent (synchronisation des BPF maps, rechargement des règles nftables, heartbeat mTLS) facilitent le troubleshooting. L'audit log trace chaque modification de règle (API, panel, template marketplace), garantissant la conformité et la traçabilité.
Gestion avancée : rate-limit par connexion et par service
Nftables permet d'affiner le rate-limit au-delà de l'IP source. Vous pouvez limiter par tuple (IP source + port destination), par groupe de ports, ou même par payload applicatif avec une règle de match personnalisée.
Rate-limit par tuple (IP + port)
nft add rule inet pakkt input tcp dport { 80, 443 } ct state new \
meter http_per_ip_port { ip saddr . tcp dport limit rate 50/second burst 100 packets } accept
La clé du meter est le tuple ip saddr . tcp dport : chaque combinaison (IP, port) dispose de son propre compteur. Un client peut ouvrir 50 connexions/s sur le port 80 et 50 connexions/s sur le port 443 indépendamment.
Rate-limit global avec log différencié
Pour tracer les abus sans bloquer immédiatement, créez une règle de log avant le drop :
nft add rule inet pakkt input tcp dport 22 ct state new \
meter ssh_rate { ip saddr limit rate over 5/minute } \
log prefix "SSH brute-force: " flags all counter
nft add rule inet pakkt input tcp dport 22 ct state new \
meter ssh_rate { ip saddr limit rate over 5/minute } drop
Chaque dépassement génère une ligne de log avec préfixe, flags TCP, et incrémente un compteur nftables. Les logs sont récupérables via journalctl -k | grep "SSH brute-force" ou centralisés dans un SIEM.
Intégration avec conntrack helpers et modules
Nftables supporte les helpers conntrack (FTP, SIP, H.323) pour tracker les flux secondaires. Combinez le rate-limit avec ct helper pour limiter les connexions de contrôle sans briser les canaux de données :
nft add ct helper ftp-helper { type "ftp" protocol tcp \; }
nft add rule inet pakkt input tcp dport 21 ct state new \
ct helper set "ftp-helper" \
meter ftp_rate { ip saddr limit rate 10/minute burst 5 packets } accept
Cette configuration autorise 10 nouvelles connexions FTP de contrôle par minute par IP, tout en laissant le helper ouvrir les canaux de données passifs/actifs sans limite.

Conclusion
Configurer le limit rate nftables par IP avec des meters offre un contrôle granulaire et performant contre les abus réseau, sans nécessiter de modules tiers ou de pare-feu applicatif complexe. En associant cette couche stateful à XDP pour le filtrage haute vitesse, vous construisez une défense kernel complète, auditée en temps réel et pilotable via API. Les seuils de burst, timeout et tuples de clé s'ajustent précisément selon le profil de trafic, garantissant disponibilité des services légitimes et blocage des attaquants au plus près du matériel.
FAQ
Quelle est la différence entre limit et meter dans nftables pour le rate-limiting par IP ?
limit applique un seuil global (toutes IPs confondues), adapté pour limiter le débit total d'une règle. meter crée un compteur distinct par clé (IP source, tuple IP+port, etc.), permettant un rate-limit individuel par adresse. Pour protéger contre les abus par IP, utilisez toujours un meter avec ip saddr ou ip6 saddr comme clé.
Comment surveiller les dépassements de rate-limit en temps réel sans saturer les logs kernel ?
Ajoutez un compteur nftables (counter) dans la règle de drop, puis interrogez-le avec nft list meter inet pakkt nom_meter ou nft list chain inet pakkt input. Pour les logs détaillés, limitez la fréquence avec log prefix "..." limit rate 1/second ou centralisez les événements via l'API PAKKT qui agrège les métriques dans TimescaleDB et expose un dashboard temps réel avec GeoIP et top IPs sources.
Peut-on rate-limiter en octets par seconde (bandwidth shaping) avec nftables et XDP ?
Nftables supporte limit rate X bytes/second, mais uniquement en global (pas par IP avec meter). XDP (PAKKT Engine) est stateless et rate-limite en paquets par seconde (max_pps, max_port_pps), pas en octets. Pour du bandwidth shaping par IP, utilisez tc (Traffic Control) avec qdisc HTB/FQ_CODEL en complément, ou une solution de QoS au niveau switch/routeur. PAKKT se concentre sur le filtrage packet-rate kernel pour la protection anti-DDoS.
Déployez PAKKT en 30 secondes
Protection kernel double couche XDP + nftables, pilotable depuis un panel centralisé. Essai gratuit 7 jours.