Cours Linux / Diagnostiquer les problèmes de connexion réseau par étapes

Pour diagnostiquer une connexion Linux, examinez successivement l’interface et ses adresses, la route, la résolution du nom, la connexion au port et la réponse applicative. Chaque consultation établit un fait limité : un ping réussi ne valide pas un service web, et un ping sans réponse ne prouve pas que le web est indisponible. Conservez les conditions du test et changez une seule hypothèse à la fois.

Les exemples visent une machine virtuelle Ubuntu 26.04 LTS ou Rocky Linux 9. Le cours sur les adresses IP, le DNS et les ports explique les rôles des différentes couches. Avant toute intervention pouvant couper l’accès, préparez une console dans votre environnement de pratique Linux. Les premières commandes consultent l’état ; l’atelier final lance uniquement un serveur temporaire sur la boucle locale.

Définir le problème et les conditions de comparaison

Notez depuis quelle machine vous contactez quel nom, quelle adresse et quel port, à quelle heure, avec quel message exact. « Internet ne fonctionne pas » peut désigner une absence d’adresse, un nom introuvable, une connexion refusée ou une page HTTP d’erreur ; ces situations ne se corrigent pas au même endroit.

  • Comparez un seul site à plusieurs sites, puis un client à un autre dans le même réseau.
  • Relevez la famille IPv4 ou IPv6, le réseau de la machine virtuelle et les éventuels proxy ou VPN, c’est-à-dire réseaux privés virtuels.
  • Conservez les changements récents, le moment où le problème a commencé et les résultats exacts de chaque essai.
  • Sur un serveur distant, gardez un autre accès de gestion avant de redémarrer le réseau ou un service de connexion.

La comparaison n’est utile que si l’on sait ce qui diffère. Un navigateur utilisant un proxy et curl en connexion directe ne testent pas nécessairement le même parcours. Une machine invitée et son hôte peuvent aussi avoir des routes et des résolveurs différents.

Vérifier les interfaces, les adresses et les routes

ip -brief link
ip -brief address
ip route
ip -6 route

Relevez l’interface réelle de la machine, sans supposer qu’elle s’appelle eth0. Dans les informations de lien, le drapeau UP traduit l’activation administrative ; LOWER_UP renseigne sur la couche inférieure signalée par le pilote. Un état ou un drapeau favorable ne démontre pas que le service distant répond. Consultez ensemble le lien, l’adresse attendue et la route de la bonne famille.

Pour une machine virtuelle, vérifiez aussi dans les paramètres de l’hyperviseur que la carte virtuelle est connectée et que le mode, par exemple traduction d’adresses ou pont, correspond au réseau voulu. Une adresse de boucle locale seule ne remplace pas une adresse utilisable pour atteindre une destination extérieure. Le manuel ip link décrit les objets et paramètres de lien.

Après avoir obtenu une adresse IPv4 réelle de la destination, ip route get suivi de cette adresse montre le chemin choisi par le noyau, notamment l’interface, le prochain saut éventuel et l’adresse source. Remplacez l’argument par l’adresse effectivement observée ; n’utilisez pas une adresse de documentation comme faux serveur de test. Pour IPv6, la forme correspondante utilise ip -6 route get.

Une erreur « Network is unreachable » conduit d’abord à examiner la sélection de route, tandis qu’une route affichée ne prouve pas la réponse du prochain routeur ou du serveur. Le manuel ip route explique la consultation get. Ces outils ne doivent pas être remplacés par une modification improvisée des routes tant que le constat n’est pas compris.

Utiliser ping comme un indice précis

ping -c 3 -w 5 127.0.0.1
ping -c 3 -w 5 example.com

Avec le ping Linux d’iputils, -c limite le nombre de demandes et -w fixe une échéance de 5 secondes pour l’échange. ICMP signifie Internet Control Message Protocol ; les requêtes Echo servent ici à rechercher des réponses, pas à tester HTTP. La première destination est la boucle locale, la seconde implique d’abord la résolution d’un nom et une adresse sélectionnée.

Une réponse de la boucle locale ne valide ni la carte physique ni le routeur. Pour la destination distante, relevez aussi l’adresse effectivement choisie. Le serveur ou un équipement intermédiaire peut filtrer ces messages tout en laissant passer un service web. Inversement, une réponse Echo ne dit rien du certificat HTTPS, de l’authentification ou de la page demandée. Le manuel iputils de ping précise ces options, différentes de celles du ping Windows.

Utilisez de petits nombres de requêtes sur un hôte autorisé. example.com est un domaine de documentation dont le service est fourni au mieux, selon la politique de l’IANA ; une absence de réponse ne constitue pas un étalon universel de panne réseau.

Distinguer résolution du nom, connexion et réponse HTTP

getent ahosts example.com

Sur ces systèmes utilisant la bibliothèque GNU C, getent suit les sources de noms configurées. Un résultat peut provenir du DNS, d’un fichier local ou d’un cache ; ce n’est pas une preuve de nouvelle requête DNS sur le réseau. Un résultat vide demande d’examiner les sources de noms et leur configuration, sans démontrer à lui seul une panne du serveur web. Le manuel de getent définit ce parcours.

Demandez ensuite une réponse HTTPS avec des détails de connexion et relevez immédiatement l’état de curl :

curl -I -v --connect-timeout 5 --max-time 15 https://example.com/
printf 'exit=%s\n' "$?"

-I demande les en-têtes par la méthode HEAD et -v affiche des détails de l’échange. La limite de connexion est 5 secondes et le transfert est limité à 15 secondes. Lisez l’adresse sélectionnée, le passage à la connexion, l’échange TLS, c’est-à-dire Transport Layer Security, puis la réponse HTTP, pour Hypertext Transfer Protocol. Un proxy peut ajouter ses propres étapes.

Les états curl 6, 7, 28 et 60 orientent respectivement vers la résolution de l’hôte, l’établissement de la connexion, un délai dépassé ou la validation du certificat. Ils ne remplacent pas les diagnostics détaillés et le contexte. L’état doit être capturé avant une autre commande, qui remplacerait $?. Le manuel officiel de curl répertorie les options et états.

Une réponse HTTP 404 ou 500 peut arriver avec un état curl 0 lorsque le transfert lui-même a réussi. Pour traiter un code HTTP d’erreur comme un échec, --fail ou, si disponible, --fail-with-body modifient cette politique ; le code HTTP et l’état du programme restent deux informations distinctes. Un refus de HEAD peut aussi être propre à cette méthode et ne signifie pas que la résolution a échoué.

Une erreur de certificat appelle la vérification du nom demandé, de la chaîne de confiance et de l’heure, pas l’ajout automatique d’une règle réseau ou le remplacement du DNS. Désactiver la vérification ne répare pas la cause. Avant de partager une sortie détaillée, retirez les cookies, jetons, en-têtes d’authentification ou adresses internes qu’elle pourrait contenir.

Sur le serveur, examiner l’écoute et le processus concerné

Exécutez les consultations suivantes sur le serveur que vous administrez pour connaître ses propres sockets. Elles ne dressent pas la liste des ports d’une autre machine :

ss -lnt
ss -lnu
sudo ss -lntp

La première sélectionne les sockets TCP en écoute avec des numéros, la deuxième les sockets UDP sélectionnés par ces options, et la dernière ajoute les informations de processus visibles avec les droits administratifs autorisés. TCP signifie Transmission Control Protocol et UDP User Datagram Protocol. Une ligne UDP n’a pas le sens d’une connexion TCP établie et ne garantit pas une réponse applicative. Le manuel de ss décrit ces filtres.

Une écoute 127.0.0.1:8080 concerne la boucle locale IPv4 ; 0.0.0.0:8080 couvre les interfaces IPv4 dans le contexte réseau du service. Avec [::]:8080, l’acceptation d’IPv4 dépend notamment de l’option du socket et de la politique système. La documentation réseau du noyau explique bindv6only ; ne modifiez pas ce réglage global simplement pour essayer une hypothèse.

Si le port n’est pas présent, vérifiez le service, sa définition et ses messages dans le cours sur systemd et le journal de démarrage. S’il est présent, distinguez encore l’adresse d’écoute, le filtrage local, les règles d’un fournisseur distant, les routes et une traduction d’adresses éventuelle. Une écoute locale ne prouve pas l’accès de bout en bout.

Relier les observations à une modification ciblée

Observation Vérifications prioritaires
Même la connexion locale au service échoue Processus, configuration, adresse d’écoute et port réellement utilisés
Essai local réussi, essai distant en échec Différence de destination, écoute, routes, pare-feu et règles du réseau ou de l’hébergeur
Connexion établie, validation du certificat en échec Nom demandé, certificat et chaîne de confiance, heure, intermédiaire éventuel
Réponse HTTP d’erreur reçue Méthode et chemin demandés, authentification, journaux du serveur et de l’application

Ces lignes orientent l’enquête sans établir seules une cause. Une règle locale peut aussi intervenir dans un essai local, et un intermédiaire peut répondre à la place de l’origine. Reproduisez le même client, le même nom, la même famille d’adresse et le même port autant que possible.

Avant de modifier un paramètre, notez sa valeur initiale et préparez le retour. Appliquez une seule modification justifiée, répétez le même essai et comparez. Si elle ne résout pas le problème, revenez à la valeur précédente avant de tester une autre hypothèse. Couper tout le pare-feu ou redémarrer tout le réseau risque de masquer la cause et de créer une nouvelle interruption.

Pratiquer localement la différence entre HTTP 404 et connexion refusée

Cet atelier fonctionne sans site distant. Il utilise Python 3.7 ou plus récent pour l’option --directory et curl. Vérifiez les programmes dans la machine virtuelle :

command -v python3
python3 --version
command -v curl
curl --version

Si un programme manque, installez le paquet prévu pour votre distribution après examen de la transaction, selon le cours APT et DNF. L’atelier crée un répertoire vide et un serveur temporaire lié seulement à 127.0.0.1. Ce serveur simple sert à comprendre HTTP, pas à héberger un service de production, comme l’indique la documentation de http.server.

Dans un premier terminal de la machine virtuelle, lancez :

lab=$(mktemp -d "$HOME/linux-http-check.XXXXXX") &&
printf 'Repertoire de pratique : %s\n' "$lab" &&
python3 -m http.server 18080 --bind 127.0.0.1 --directory "$lab"

Si la création du répertoire échoue, les opérateurs && empêchent le lancement avec un mauvais chemin. Après succès, le serveur reste au premier plan et affiche son adresse d’écoute. Si le port est déjà utilisé, arrêtez cette tentative et choisissez un autre port disponible dans la commande serveur et dans toutes les URL suivantes. N’arrêtez pas un processus inconnu pour libérer 18080.

Gardez ce terminal ouvert. Dans un second terminal de la même machine virtuelle, demandez un fichier absent du répertoire vide :

curl --show-error --connect-timeout 2 --max-time 5 -i http://127.0.0.1:18080/missing-file
printf 'exit=%s\n' "$?"

Vous devez voir une réponse HTTP 404, avec les détails de cette erreur. Sans option de traitement des erreurs HTTP, curl peut terminer avec exit=0 : le serveur a reçu une requête et renvoyé une réponse, même si le fichier n’existe pas. La connexion et la ressource demandée ne sont pas la même réussite.

Ne changez maintenant que la politique HTTP en ajoutant --fail :

curl --fail --show-error --connect-timeout 2 --max-time 5 -i http://127.0.0.1:18080/missing-file
printf 'exit=%s\n' "$?"

Le serveur renvoie encore 404, mais curl termine avec exit=22 et ne fournit pas le corps d’erreur comme un contenu réussi. Le serveur peut enregistrer les deux requêtes dans son premier terminal. En retirant --fail, vous retrouvez la politique précédente pour la même ressource absente.

Revenez au premier terminal et arrêtez ce serveur de pratique avec Ctrl+C. Quand son invite est revenue, répétez exactement la commande avec --fail dans le second terminal. Si aucun autre processus n’a repris le port, vous n’obtenez plus de réponse HTTP : l’état est généralement 7 pour un refus de connexion, ou peut être 28 si une attente dépasse la limite. Lisez le message précis au lieu d’attendre un faux code HTTP 404 d’un serveur arrêté.

Enfin, dans le premier terminal où la variable lab a été créée, retirez uniquement le répertoire vide :

rmdir -- "$lab"

rmdir refuse un répertoire non vide. Si vous y avez ajouté un fichier, examinez son contenu au lieu de remplacer cette commande par un effacement récursif. L’atelier a séparé trois observations : une réponse d’erreur HTTP reçue, la politique d’état de curl pour cette réponse, puis l’absence de serveur pour accepter la connexion.