Introduction
Le dépannage réseau sous Linux fonctionne mieux comme un processus reproductible et fondé sur des preuves plutôt que comme une collection de commandes mémorisées. Lorsqu'un service cesse de répondre, qu'un déploiement ne peut pas atteindre sa base de données ou que le DNS renvoie des réponses inattendues, un opérateur doit passer du symptôme à la cause racine sans aggraver le problème.
Ce guide s'adresse aux développeurs, consultants DevOps et ingénieurs de startup qui exploitent directement des systèmes Linux. Il couvre les quatre domaines à l'origine de la plupart des incidents : la résolution DNS, l'état des ports locaux, la connectivité de bout en bout et le flux de travail de diagnostic qui les relie. Chaque section présente d'abord une commande en lecture seule, explique le résultat attendu, identifie les signaux de défaillance courants, puis introduit le plus petit changement sûr avec une étape de vérification et un chemin de retour en arrière.
La sécurité opérationnelle est le thème récurrent. Observez avant de modifier, limitez le rayon d'impact de tout changement, gardez les secrets et les identifiants de production hors de votre historique de commandes et de votre documentation, et définissez toujours ce à quoi ressemble le succès avant d'appuyer sur Entrée.
Inventaire de la version et de l'environnement
Avant de dépanner, vous avez besoin d'un inventaire fiable du système que vous vous apprêtez à inspecter. Deviner la distribution, la version du noyau ou le gestionnaire de réseau peut vous amener à exécuter des commandes qui ne sont pas installées, à produire des résultats trompeurs ou à modifier le mauvais fichier de configuration.
Commencez par trois commandes en lecture seule qui fonctionnent sur pratiquement toutes les distributions Linux.
cat /etc/os-release
uname -r
ip -brief address
/etc/os-release affiche la distribution et la version, par exemple PRETTY_NAME="Ubuntu 22.04.3 LTS" ou VERSION_ID="9" sur Debian 9. uname -r imprime la version du noyau en cours d'exécution, comme 5.15.0-91-generic. ip -brief address liste toutes les interfaces et leurs adresses IPv4 et IPv6 dans un tableau compact.
Un exemple de sortie de la dernière commande pourrait ressembler à ceci :
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 10.0.0.42/24 2001:db8::42/64
Vous en déduisez le nom de l'interface (eth0, et non l'ancien eth1 ou un nom prévisible comme enp3s0), l'état du lien (UP) et les adresses configurées. Si eth0 était DOWN au lieu de UP, on s'attendrait à des problèmes de connectivité et l'étape suivante serait d'inspecter ip link show eth0 et les journaux du service réseau, et non de commencer à tester les ports distants.
Ensuite, identifiez le résolveur DNS utilisé par le système et les services qui écoutent sur quels ports. Ces deux observations sont en lecture seule.
cat /etc/resolv.conf
ss -lntup
/etc/resolv.conf peut contenir nameserver 127.0.0.53, indiquant systemd-resolved comme résolveur local relais, ou nameserver 10.0.0.2, ce qui signifie l'utilisation directe d'un serveur DNS local. ss -lntup montre les sockets TCP et UDP en écoute avec le processus propriétaire. Cherchez :22 (sshd), :80 ou :443 (un serveur web) et :53 si un résolveur local comme dnsmasq est en cours d'exécution.
Exemple de sortie :
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=812,fd=3))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1200,fd=6))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=812,fd=4))
Si ss n'est pas disponible, installez le paquet iproute2 (généralement déjà présent) ou utilisez l'ancien netstat -lntup, mais vérifiez que la version du paquet est appropriée pour votre distribution. Sur Alpine Linux, par exemple, ss fait partie d'iproute2, qui peut nécessiter d'être ajouté avec apk add iproute2.
Consignez cet inventaire avant d'effectuer tout changement. Il vous donne une base de référence connue et rend toute dérive évidente par la suite.
Chemin de configuration sûr
Lorsqu'un changement est nécessaire, suivez un chemin qui minimise les risques : sauvegardez le fichier, modifiez un seul paramètre à la fois, redémarrez uniquement le service concerné, vérifiez et sachez comment revenir en arrière.
Considérons un scénario courant : une application signale qu'elle ne peut pas se connecter à une base de données PostgreSQL à db.internal.example.com. L'application s'exécute sur le même hôte et vous soupçonnez une mauvaise configuration DNS. Avant de modifier quoi que ce soit, vérifiez la résolution et la connectivité actuelles.
Tout d'abord, testez la résolution DNS avec une requête en lecture seule :
getent hosts db.internal.example.com
La sortie attendue inclut une adresse IP :
10.0.1.15 db.internal.example.com
Si la commande ne renvoie rien ou une erreur comme Name or service not known, le DNS ne résout pas le nom. Vérifiez /etc/hosts et /etc/resolv.conf, et testez la résolution en amont avec dig ou nslookup si disponible.
Supposons que vous découvriez que /etc/resolv.conf pointe vers un serveur de noms qui n'existe plus. Vous décidez de passer à un résolveur connu et fiable comme 1.1.1.1 de Cloudflare. Il s'agit d'un changement à portée unique avec un retour en arrière facile.
- Sauvegardez le fichier actuel :
cp /etc/resolv.conf /etc/resolv.conf.bak.$(date +%Y%m%d)
- Vérifiez si
/etc/resolv.confest un lien symbolique (courant sur les systèmes utilisantsystemd-resolvedou NetworkManager). Si c'est le cas, modifiez le fichier cible ou utilisez l'outil approprié (resolvectlpour systemd-resolved,nmclipour NetworkManager) pour éviter que vos modifications ne soient écrasées.
- Effectuez une modification minimale. Si vous modifiez directement le fichier, remplacez la ligne
nameserverpar :
nameserver 1.1.1.1
nameserver 8.8.8.8
- Vérifiez immédiatement la résolution :
getent hosts db.internal.example.com
- Si le nom ne se résout toujours pas, restaurez la sauvegarde :
cp /etc/resolv.conf.bak.20240115 /etc/resolv.conf
Ce schéma en cinq étapes – observer, sauvegarder, changement minimal, vérifier, revenir en arrière – s'applique à la plupart des modifications de configuration. Ne modifiez jamais plusieurs paramètres réseau à la fois, car si le service échoue, vous ne saurez pas quel changement a causé le problème.
Pour les services gérés par systemd, utilisez systemctl edit plutôt que de modifier directement les fichiers d'unité lorsque c'est possible. Par exemple, pour ajouter une variable d'environnement à un service sans toucher au fichier d'unité empaqueté :
systemctl edit myapp.service
Ajoutez ensuite :
[Service]
Environment="MYAPP_DNS=1.1.1.1"
Rechargez et redémarrez uniquement ce service :
systemctl daemon-reload
systemctl restart myapp.service
Vérifiez avec systemctl status myapp.service et en consultant les journaux de l'application pour un message de démarrage réussi. Si le service échoue, systemctl revert myapp.service supprime la surcharge et revient aux valeurs par défaut empaquetées.
Vérification et diagnostics
La vérification ne consiste pas simplement à vérifier qu'une commande s'est exécutée sans erreur. Une commande peut se terminer avec succès tout en masquant une mauvaise configuration. Vous devez comparer la sortie observée à un résultat attendu, adapté à la version.
Vérification DNS
Utilisez dig pour des requêtes DNS détaillées et scriptables. dig fait partie du paquet bind-utils sur les dérivés de Red Hat et dnsutils sur Debian/Ubuntu.
dig +short db.internal.example.com
La sortie attendue est une adresse IP brute :
10.0.1.15
Si vous n'obtenez aucune sortie ou un délai d'attente, exécutez la requête complète pour voir le code de réponse :
dig db.internal.example.com
Regardez les sections status et ANSWER. Un statut SERVFAIL signifie que le serveur faisant autorité n'a pas pu répondre ; NXDOMAIN signifie que le nom n'existe définitivement pas ; NOERROR avec zéro réponse signifie que le nom existe mais n'a pas d'enregistrement A.
Lors du débogage d'un domaine public, vous pouvez interroger un résolveur spécifique pour isoler les problèmes :
dig @1.1.1.1 example.com A
Si cela fonctionne mais que le résolveur par défaut du système échoue, le problème vient de la configuration DNS locale, pas du domaine lui-même.
Vérification des ports
Pour vérifier si un service local écoute réellement sur le port attendu, ss est l'outil standard.
ss -lntp | grep ':5432'
Exemple de sortie pour PostgreSQL :
LISTEN 0 4096 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=1500,fd=7))
Si la ligne est absente, le service n'écoute pas du tout. S'il indique 127.0.0.1:5432, il est lié uniquement à localhost, donc les clients distants seront refusés. S'il indique 0.0.0.0:5432, il accepte les connexions sur toutes les interfaces.
Pour tester du point de vue du client, utilisez nc (netcat) ou telnet :
nc -zv 10.0.1.15 5432
Le drapeau -z analyse sans envoyer de données, -v le rend verbeux. Une connexion réussie imprime quelque chose comme :
Connection to 10.0.1.15 5432 port [tcp/postgresql] succeeded!
Un échec n'imprime rien ou Connection refused. Rappelez-vous que Connection refused signifie que le paquet a atteint l'hôte mais que rien n'écoutait, tandis qu'un délai d'attente indique souvent un pare-feu qui abandonne silencieusement les paquets.
Vérification de la connectivité
ping est utile pour la joignabilité de base, mais l'ICMP peut être bloqué alors que les services TCP fonctionnent toujours. Ne vous fiez pas uniquement à ping. Utilisez traceroute ou tracepath pour voir la route, et mtr pour une vue combinée continue.
traceroute -n 10.0.1.15
Le drapeau -n empêche les recherches DNS inverses, qui peuvent bloquer la sortie. Chaque ligne de saut montre le temps d'aller-retour vers ce routeur. Une ligne d'astérisques indique un routeur qui ne répond pas à l'ICMP, mais les sauts suivants peuvent encore apparaître.
Pour un test rapide d'un port TCP spécifique en cours de route, utilisez nc avec un délai d'attente :
nc -zvw 5 10.0.1.15 443
Le -w 5 définit un délai de cinq secondes. Si la connexion réussit, le port est ouvert et joignable.
Modes de défaillance et récupération
Reconnaître les schémas de défaillance courants accélère le diagnostic et évite les corrections malavisées.
Échec DNS : Name or service not known
Pourquoi cela arrive : le résolveur ne peut pas mapper le nom d'hôte à une adresse IP. Les causes incluent une entrée /etc/hosts manquante, un serveur de noms injoignable ou le nom n'existant réellement pas.
Comment diagnostiquer :
getent hosts db.internal.example.com
cat /etc/resolv.conf
ping -c 1 1.1.1.1
Si /etc/resolv.conf pointe vers une IP injoignable, ping vers cette IP échouera alors que ping 1.1.1.1 réussira. Corrigez en modifiant /etc/resolv.conf comme décrit précédemment, ou en reconfigurant le gestionnaire de réseau.
Vérification de la récupération : getent hosts renvoie une IP et dig affiche un statut NOERROR.
Échec de port : Connection refused
Pourquoi cela arrive : le port cible n'est pas ouvert sur l'hôte de destination. Soit aucun processus n'écoute, le service est lié à une interface différente (par exemple, localhost uniquement), soit un pare-feu rejette activement la connexion.
Comment diagnostiquer :
ss -lntp | grep ':5432' # sur le serveur
nc -zv 10.0.1.15 5432 # depuis le client
Si ss montre le service écoutant sur 127.0.0.1:5432, modifiez la configuration du service pour écouter sur 0.0.0.0 ou l'IP spécifique du serveur. Pour PostgreSQL, éditez postgresql.conf et définissez listen_addresses = '*', puis redémarrez PostgreSQL. Si ss ne montre aucun auditeur, le service ne fonctionne pas ; vérifiez systemctl status postgresql et démarrez-le.
Vérification de la récupération : nc -zv depuis un hôte distant réussit.
Échec de connectivité : délai d'attente
Pourquoi cela arrive : les paquets sont abandonnés, généralement par un pare-feu, ou la route est incorrecte.
Comment diagnostiquer :
traceroute -n 10.0.1.15
iptables -L -n -v # ou nft list ruleset
ip route show
Si traceroute s'arrête à un certain saut et n'atteint jamais la destination, inspectez les règles de pare-feu sur ce saut. Pour l'hôte local, vérifiez iptables -L -n -v pour les règles DROP ou REJECT affectant le port de destination. Une erreur courante est une politique de refus par défaut d'ufw :
ufw status verbose
Si ufw est actif et que le port n'est pas autorisé, ajoutez une règle :
ufw allow 5432/tcp
Vérification de la récupération : le test de port depuis le client renvoie maintenant succeeded.
Échec d'interface : ip link affiche DOWN
Pourquoi cela arrive : le câble réseau est débranché, l'interface virtuelle est administrativement désactivée, ou le pilote n'a pas réussi à s'initialiser.
Comment diagnostiquer :
ip link show eth0
dmesg | tail -20
Si l'état est DOWN, essayez de l'activer administrativement :
ip link set eth0 up
Vérifiez ensuite à nouveau. S'il reste DOWN, inspectez dmesg pour des erreurs de pilote telles que link is not ready ou failed to allocate. Pour les machines virtuelles, vérifiez que l'adaptateur réseau virtuel de l'hyperviseur est connecté.
Vérification de la récupération : ip -brief address affiche UP et une adresse IP.
Liste de contrôle opérationnelle
Une liste de contrôle transforme la réponse aux incidents en un processus systématique. Utilisez les étapes suivantes dans l'ordre et documentez la sortie de chaque commande dans vos notes d'incident.
1. Inventaire de référence (Propriétaire : ingénieur d'astreinte, examiné au début de l'incident)
cat /etc/os-release
uname -r
ip -brief address
cat /etc/resolv.conf
ss -lntup
Enregistrez la sortie. Cela vous indique avec quoi vous travaillez et évite toute confusion ultérieure.
2. Reproduire la défaillance (Propriétaire : ingénieur d'astreinte, examiné dès qu'elle est signalée)
Exécutez la commande exacte que l'application ou l'utilisateur signale comme étant en échec. Notez le message d'erreur exact. Par exemple :
nc -zv db.internal.example.com 5432
S'il échoue avec Connection refused, vous avez un problème de port. S'il se bloque et expire, vous avez un problème de joignabilité.
3. Isoler la couche (Propriétaire : ingénieur réseau si escaladé, examiné après reproduction)
- DNS :
dig +short db.internal.example.com– renvoie-t-il une IP ? - Port :
ss -lntp | grep 5432sur le serveur – le service écoute-t-il ? - Route :
ip route get 10.0.1.15– quelle interface et passerelle sont utilisées ? - Pare-feu :
iptables -L -n -v | grep 5432– des règles DROP ?
4. Effectuer un seul changement ciblé (Propriétaire : ingénieur d'astreinte, examiné avant exécution)
Si le DNS est en cause, modifiez /etc/resolv.conf après sauvegarde. Si le port est fermé, ajustez la configuration du service. Documentez le changement exact dans le journal d'incident.
5. Vérifier et revenir en arrière (Propriétaire : ingénieur d'astreinte, examiné immédiatement après le changement)
Exécutez le même diagnostic de l'étape 3. Si le résultat est toujours en échec, annulez le changement en utilisant la sauvegarde ou systemctl revert. Si le résultat est réussi, surveillez pendant au moins cinq minutes pour assurer la stabilité.
6. Revue post-incident (Propriétaire : responsable d'ingénierie, examinée dans les 48 heures)
Demandez : Quelle était la cause racine ? Quelle commande ou vérification aurait permis de détecter cela avant que les utilisateurs ne le remarquent ? Ajoutez cette vérification à votre surveillance ou à votre runbook.
Cette liste de contrôle doit être revue après chaque incident ou au moins tous les trimestres pour rester à jour avec les changements de votre infrastructure.
Pièges courants et comment les éviter
Même les opérateurs expérimentés commettent ces erreurs. Les reconnaître fait gagner du temps et évite les pannes.
1. Modifier /etc/resolv.conf et perdre les modifications après le redémarrage
Pourquoi cela arrive : sur de nombreux systèmes, /etc/resolv.conf est géré par NetworkManager, systemd-resolved ou DHCP. Une modification manuelle est écrasée.
Comment éviter : vérifiez si le fichier est un lien symbolique avec ls -l /etc/resolv.conf. Si c'est le cas, utilisez l'outil de gestion approprié. Pour NetworkManager, utilisez nmcli con mod "Wired connection 1" ipv4.dns "1.1.1.1 8.8.8.8" puis nmcli con up "Wired connection 1". Pour systemd-resolved, modifiez /etc/systemd/resolved.conf et définissez DNS=1.1.1.1 8.8.8.8.
2. Tester la connectivité uniquement avec ping
Pourquoi cela arrive : ping est le premier outil qui vient à l'esprit, mais l'ICMP est souvent bloqué alors que les ports TCP sont ouverts.
Comment éviter : testez toujours le port de service réel avec nc ou telnet. Si l'ICMP est bloqué, ping échouera même si le service fonctionne.
3. Vérifier la mauvaise interface
Pourquoi cela arrive : un hôte peut avoir plusieurs interfaces, et le service peut être lié à une autre que celle que vous pensez.
Comment éviter : utilisez ss -lntp pour voir l'adresse de liaison exacte. Comparez-la avec ip -brief address pour savoir à quelle interface cette adresse appartient. Si l'adresse de liaison est 127.0.0.1, les clients distants seront toujours refusés.
4. Supposer qu'aucun pare-feu n'est présent
Pourquoi cela arrive : de nombreuses images cloud et installations minimales ont des règles iptables ou nftables par défaut, et ufw ou firewalld peuvent être actifs à l'insu de l'opérateur.
Comment éviter : vérifiez toujours l'état du pare-feu : ufw status ou firewall-cmd --state ou iptables -L -n. Si des politiques existent, examinez-les avant de blâmer le DNS ou l'application.
5. Se connecter à la production et effectuer plusieurs changements à la fois
Pourquoi cela arrive : la pression pour réparer rapidement conduit à modifier simultanément le DNS, le pare-feu et la configuration du service.
Comment éviter : changez une chose à la fois. Après chaque changement, vérifiez. Si le problème persiste, annulez ce changement avant d'essayer le suivant. Cela isole la cause et rend la récupération prévisible.
Conclusion
Le dépannage réseau sous Linux est une compétence qui récompense la discipline. Les commandes elles-mêmes ne sont pas difficiles ; le défi est de savoir quelle sortie attendre, d'interpréter correctement les sorties inattendues et d'apporter des modifications qui peuvent être annulées.
Commencez par un inventaire complet : version du système d'exploitation, noyau, interfaces, résolveur DNS et ports en écoute. Reproduisez la défaillance avec la commande exacte qui échoue. Isolez le problème à une seule couche - DNS, port, route ou pare-feu. Effectuez un seul changement ciblé avec un plan de sauvegarde ou de retour en arrière. Vérifiez avec une commande dont vous avez défini la sortie attendue avant d'effectuer le changement. Documentez ensuite l'incident et mettez à jour votre runbook.
Choisir une vérification à faible risque à automatiser est une bonne première étape après avoir lu ce guide. Par exemple, créez une tâche cron qui exécute nc -zv db.internal.example.com 5432 > /dev/null 2>&1 || echo "DB port check failed at $(date)" >> /var/log/db-port-check.log toutes les cinq minutes. Cela rend la défaillance visible avant qu'une application ne la signale.
Un flux de travail fiable rend la défaillance visible, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force une décision précipitée. Avec ces pratiques, vous pouvez résoudre les problèmes réseau en toute confiance et maintenir la disponibilité de vos systèmes.