Diagnostiquer la saturation de conntrack et vérifier le nouveau plafond
Lorsque des connexions expirent par intermittence alors que les sessions déjà établies continuent de transférer des données et que les processus applicatifs ainsi que les sockets en écoute fonctionnent normalement, il faut examiner la table de suivi des connexions de Linux. Les pare-feu à états, la traduction d’adresses et certains réseaux de conteneurs s’appuient sur conntrack ; si de nouvelles entrées ne peuvent pas être créées, le trafic peut être abandonné avant même d’atteindre l’application. Cet article prend Debian 12 comme exemple et organise les opérations en quatre étapes : collecte de preuves, recherche de la cause, ajustement de la capacité et retour arrière. Il ne modifie aucune règle de pare-feu et ne purge pas les connexions existantes.
1. Identifier d’abord l’espace de noms réseau concerné
Les serveurs dédiés CloudDDR sont équipés d’un AMD EPYC 7543P et de 128Go ou 256Go de mémoire ECC, mais la quantité de mémoire ne détermine pas directement le plafond de conntrack. Les vérifications doivent porter sur le noyau du système, l’espace de noms réseau et le trafic applicatif. Après le paiement, consultez les identifiants dans la console et connectez-vous par SSH ; si plusieurs adresses sont indiquées, utilisez la première.
Exécutez les commandes dans l’espace de noms réseau qui traite réellement le trafic. Les résultats obtenus sur l’hôte ne décrivent pas nécessairement le système invité. Si le trafic des conteneurs passe par une traduction d’adresses sur l’hôte, vérifiez également ce dernier. Commencez par relever la version du noyau, l’espace de noms réseau courant, le nombre d’entrées et leur plafond :
uname -r
readlink /proc/self/ns/net
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
sudo sysctl net.netfilter.nf_conntrack_buckets
Si une clé est absente, cela signifie que le paramètre correspondant n’est pas exposé dans cet espace de noms ; ce n’est pas une preuve de saturation. Vérifiez d’abord si les modules concernés sont chargés et si le trafic applicatif utilise le suivi des connexions. N’activez pas une nouvelle fonctionnalité en plein incident simplement pour obtenir tous les résultats attendus.
N’exécutez pas
conntrack -F. La purge supprime les états de suivi, peut perturber les sessions existantes et les correspondances de traduction d’adresses, et efface les éléments nécessaires au diagnostic.
2. Étayer le diagnostic avec les variations des compteurs
L’installation de l’outil en espace utilisateur ne modifie pas les règles existantes, mais elle doit respecter la procédure de changement en vigueur. Les opérations suivantes lisent l’état du système et comparent deux relevés espacés pour déterminer si les compteurs continuent d’augmenter :
sudo apt-get install conntrack
umask 077
sudo conntrack -S > /tmp/conntrack-before.txt
sudo journalctl -k --since "-10 min" --no-pager \
| grep -Ei 'nf_conntrack|table full'
sleep 30
sudo conntrack -S > /tmp/conntrack-after.txt
diff -u /tmp/conntrack-before.txt /tmp/conntrack-after.txt
conntrack -S affiche généralement des compteurs cumulés par CPU. Comparez les lignes correspondant au même CPU et observez les augmentations de insert_failed, drop et early_drop, plutôt que d’attribuer à l’incident actuel les valeurs accumulées depuis le démarrage. Le sens des compteurs et les champs affichés peuvent varier selon le noyau ; tous les échecs d’insertion ne sont pas dus à un manque de capacité.
Relevez en parallèle le nombre d’expirations de délai côté application, l’occupation de la table et les messages du noyau. Le diagnostic devient suffisamment étayé lorsque l’occupation approche du plafond, que les compteurs d’échec augmentent et que les erreurs applicatives apparaissent au même moment. L’absence de messages correspondants dans les journaux n’exclut pas le problème : leur émission peut être limitée en fréquence. Des pics brefs peuvent aussi passer inaperçus entre deux relevés. Raccourcissez l’intervalle d’observation si nécessaire, sans exporter en boucle l’intégralité de la table.
3. Distinguer le nombre de connexions de leur rythme de création
Comprendre l’accumulation des entrées à partir d’un échantillon
Le nombre d’entrées ne correspond pas au nombre de requêtes en cours. Une connexion TCP peut transporter plusieurs requêtes, et UDP utilise lui aussi des entrées de suivi. Une fois les échanges terminés, une entrée peut rester présente jusqu’à l’expiration du délai associé. Il faut donc distinguer les connexions durables et stables, les hausses soudaines de connexions courtes et les sources de trafic anormales.
Vous pouvez effectuer un échantillonnage ponctuel et borné, afin d’éviter d’afficher à répétition toute la table lorsque la charge est élevée :
sudo timeout 5s conntrack -L -o extended 2>/tmp/conntrack-sample.err \
| head -n 200 > /tmp/conntrack-sample.txt
Cette commande ne recueille qu’une quantité limitée de sortie. Elle peut s’arrêter prématurément et renvoyer un code de sortie non nul ; l’échantillon ne constitue pas une statistique exhaustive. Le fichier contient des adresses : limitez les droits de lecture et anonymisez, si nécessaire, les pièces jointes aux tickets. La sortie comprend les tuples du sens initial et du sens retour. Ne mélangez pas ces deux ensembles d’adresses lors de l’analyse des sources.
Examinez le protocole, l’état TCP, le délai restant et la source dans le sens initial. Face à un grand nombre de connexions courtes, consultez également le pool de connexions de l’application et les journaux de nouvelles tentatives. Si quelques sources créent continuellement de nouveaux flux, confrontez cette observation aux journaux d’accès. Si les entrées UDP s’accumulent durablement, vérifiez le rythme réel des échanges. Un nom d’état ne suffit pas à conclure à une attaque, et une anomalie de trafic ne doit pas être réduite à un simple problème de capacité.
Si le rythme de création des connexions ne diminue pas, agrandir la table ne fera que retarder la prochaine saturation. Corriger des tentatives répétées sans limite, rétablir la réutilisation des connexions ou traiter les sources anormales nécessite souvent une validation distincte de celle de l’ajustement de capacité.
4. Évaluer la mémoire avant de modifier une seule variable
Le plafond n’est ni une préallocation mémoire ni une garantie de débit
Augmenter nf_conntrack_max ne crée pas immédiatement toutes les entrées possibles, mais le remplissage continu de la table consomme de la mémoire du noyau. Utilisez free -h, /proc/meminfo et sudo slabtop -o pour observer la mémoire et les caches slab. La taille des objets de ces caches ne couvre pas l’ensemble des coûts, notamment les champs d’extension et les surcoûts d’allocation. Il est donc déconseillé d’appliquer une formule fixe en « octets par connexion ».
nf_conntrack_buckets indique le nombre de compartiments de la table de hachage, et non sa capacité en connexions. Relever uniquement le plafond peut allonger les chaînes de ces compartiments et augmenter le coût des recherches ; surveillez donc aussi le CPU et la latence applicative. La possibilité de modifier le nombre de compartiments à chaud dépend du noyau et de l’espace de noms. Ce paramètre ne sera pas modifié conjointement dans cette procédure.
L’exemple suivant illustre uniquement un changement temporaire visant un plafond de 262144. Avant de l’exécuter, vérifiez que cette valeur dépasse la valeur actuelle, que le budget mémoire le permet et qu’une autre session d’administration est disponible. Ce n’est pas une valeur recommandée pour toutes les machines. Les commandes s’exécutent dans un shell disposant des droits d’administration :
sudo -i
OLD=$(sysctl -n net.netfilter.nf_conntrack_max)
test "$OLD" -lt 262144 || exit 1
umask 077
printf '%s\n' "$OLD" > /run/conntrack-max.before
sysctl -w net.netfilter.nf_conntrack_max=262144
sysctl -n net.netfilter.nf_conntrack_max
Après avoir conservé la valeur d’origine, répétez les mêmes tests applicatifs et les mêmes relevés de compteurs. Ne raccourcissez pas en parallèle le délai d’expiration des connexions TCP à l’état established : des connexions durables mais inactives peuvent encore être utilisées par l’application, et une réduction globale de ce délai introduirait une nouvelle cause de déconnexion.
5. Séparer validation, retour arrière et persistance
La validation doit au minimum couvrir le trafic qui déclenchait l’incident ainsi que les connexions durables reprenant leurs échanges après une période d’inactivité. Vérifiez le taux de réussite des nouvelles connexions, les augmentations des compteurs d’échec, la tendance de croissance de l’occupation, la mémoire disponible, le CPU et la latence applicative. Constater uniquement que le plafond a augmenté ne suffit pas à considérer le problème comme résolu.
Si la pression mémoire, la charge CPU ou la latence se dégradent, revenez à la valeur sauvegardée :
sudo sysctl -w \
net.netfilter.nf_conntrack_max="$(sudo cat /run/conntrack-max.before)"
Abaisser le plafond ne supprime pas immédiatement les entrées existantes. Si l’occupation reste supérieure au plafond restauré, la création de nouvelles entrées peut continuer à être bloquée. Il faut attendre la disparition naturelle des entrées et traiter les sources du trafic. Ne purgez pas la table pour accélérer le rétablissement.
Une fois l’ajustement temporaire validé, vérifiez si le même paramètre est déjà défini dans /etc/sysctl.conf ou dans /etc/sysctl.d/, afin d’éviter que plusieurs fichiers ne se remplacent mutuellement leurs valeurs. Inscrivez la valeur validée dans un fichier de configuration dédié, suivi dans un système de gestion de versions, par exemple :
net.netfilter.nf_conntrack_max = 262144
Chargez uniquement ce fichier, puis vérifiez à nouveau la valeur effective. Ne rechargez pas en bloc des paramètres sans rapport avec l’incident pendant son traitement. Lors d’un redémarrage contrôlé ultérieur, vérifiez également la valeur finale après le chargement des modules : écrire le paramètre dans un fichier ne garantit pas qu’il sera effectivement appliqué au démarrage.
Le compte rendu final doit inclure les sources du trafic, les compteurs avant et après le changement, les tests applicatifs, les observations mémoire, la valeur d’origine et la procédure de restauration. La gestion de la capacité du suivi des connexions est aboutie lorsque les preuves permettent d’expliquer l’incident et que les résultats de l’ajustement sont reproductibles, pas simplement lorsqu’un nombre plus élevé apparaît comme plafond de la table.
Questions fréquentes
Une table conntrack presque pleine prouve-t-elle la cause des pertes ?
Non. Il faut corréler la hausse de insert_failed, drop ou early_drop avec les journaux du noyau et les échecs applicatifs sur la même période. Une forte occupation indique seulement une pression sur la capacité.
Faut-il réduire les délais TCP en augmentant nf_conntrack_max ?
Non, ces changements doivent rester distincts. Conserver les délais du protocole et vérifier d’abord un plafond compatible avec la mémoire disponible. Réduire le délai global TCP established peut perturber les connexions longues et inactives.
Serveur dédié AMD EPYC 7543P à partir de $447/mois.