## Introduction

Les requêtes REST API traversent plusieurs couches : client, DNS, routes réseau, pare-feux, terminaison TLS, proxys inverses et le service API lui-même. Quand quelque chose casse, les symptômes peuvent sembler similaires alors que la cause se trouve ailleurs. Ce guide praticien parcourt une approche sûre, par couches, pour isoler et corriger les problèmes réseau liés aux API REST. Vous apprendrez à :

- Inventorier versions, points de terminaison et topologie avant toute modification.

- Lancer des diagnostics sûrs, en lecture seule, pour cibler DNS, port, routage, pare-feu ou TLS.

- Valider les correctifs avec des résultats attendus clairs.

- Reconnaître les modes de défaillance courants et revenir proprement en arrière.

- Appliquer une liste de contrôle opérationnelle reproductible.

Les exemples construits sont clairement identifiés et utilisent des hôtes hypothétiques comme api.example.test et 10.0.1.20 .

### Correspondance rapide symptôme-couche

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Symptôme</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Couche probable</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Premier test</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Le nom résout vers une mauvaise IP</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">DNS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">dig +short api.example.test</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Échec de la négociation TLS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">TLS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl s_client -connect api.example.test:443 -servername api.example.test</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Délai de connexion</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Routage/Pare-feu</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">nc -vz api.example.test 443</code> ou <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">Test-NetConnection -Port 443</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Connexion refusée</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Service/Port</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ss -lntp</code> ou <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">netstat -ano</code> pour confirmer l&#39;écoute</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">200 en local, échec via LB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Proxy/LB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">curl -v https://lb.example.test/health</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">5xx intermittents en pointe</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Capacité/Limite de débit</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">journaux et métriques serveur</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Erreur CORS dans le navigateur</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Application/En-têtes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">curl -I https://api.example.test/route</code></td></tr></tbody>
</table>
</div>

## Inventaire versions et environnement

Avant de changer quoi que ce soit, notez les faits sur lesquels vous testerez. Cela réduit les conjectures et évite de poursuivre plusieurs variables à la fois.

- Inventaire des points de terminaison

- URL de base de l'API : ex. https://api.example.test

- Routes de santé : ex. /health ou /status

- Protocole attendu : HTTP ou HTTPS

- Port(s) attendu(s) : 80/443 en externe ; ports internes (ex. 3000 pour Express) si pertinent

- Proxys inverses ou répartiteurs de charge sur le chemin : ex. nginx à lb.example.test

- Esquisse de topologie (texte suffit)

Client -> DNS -> Internet/Réseau d'entreprise -> LB/Proxy -> Hôte API -> Dépendances (ex. MongoDB) 

- Versions

- OS : ex. Ubuntu 22.04, Windows 11, macOS 14

- Exécution : ex. Node.js 18.x pour une API Express (exemple construit)

- TLS : où se fait la terminaison (proxy vs application)

- Données DNS

- Zone autoritative : qui possède api.example.test

- Type(s) d'enregistrement : A/AAAA/CNAME

- IP résolues actuelles et TTL

- Contrôles d'accès

- Règles de groupes de sécurité/pare-feu censées autoriser certaines plages sources et ports

- Fenêtre de changement connue

- Changements récents au DNS, certificats, routage ou déploiements

 Prérequis pour exécuter les étapes de ce guide :

- Accès shell sur un client pouvant atteindre le chemin réseau de l'API.

- Outils de base installés ou disponibles :

- Linux/macOS : dig (ou nslookup ), curl , nc (netcat), traceroute , openssl , ss (ou netstat )

- Windows : nslookup , curl.exe , tracert , Test-NetConnection (PowerShell), netstat ; openssl si installé

- Accès en lecture aux journaux du serveur API si possible.

## Chemin de configuration sûr

Travaillez du moins invasif au plus invasif, et du local au distant. Gardez les changements circonscrits et réversibles.

### 1. Prouver que le service fonctionne localement (exemple construit)

Sur l'hôte API, confirmez que le service écoute sur l'adresse et le port prévus.

# Linux
ss -lntp | grep ":3000"

# macOS (peut utiliser lsof)
lsof -nP -iTCP:3000 -sTCP:LISTEN

# Windows
netstat -ano | findstr LISTENING | findstr :3000 
 Attendu : un écouteur lié à 127.0.0.1:3000 ou 0.0.0.0:3000 (ou votre port configuré). Si rien n'écoute, corrigez le service avant de tester le réseau.

Interrogez un point de terminaison de santé local depuis l'hôte API.

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3000/health 
 Attendu : 200 . Sinon, vérifiez les journaux et la configuration de l'application.

### 2. Valider le DNS sans changer les enregistrements globaux

Résolvez le nom d'hôte visé pour confirmer les cibles actuelles.

# Linux/macOS
dig +short api.example.test

# Windows
nslookup api.example.test 
 Attendu : les IP que vous visez. Si ce n'est pas le cas, ne changez pas encore le DNS système. Faites plutôt un test ciblé.

Remplacement d'hôte ciblé pour curl avec --resolve (ne change pas le système).

# Tester HTTPS vers une IP spécifique tout en conservant l'en-tête SNI/Host
curl -v --resolve api.example.test:443:203.0.113.10 https://api.example.test/health 
 Attendu : 200 si le service à 203.0.113.10 est correct et le certificat TLS correspond à api.example.test .

### 3. Prouver la joignabilité TCP avant la logique HTTP

# Linux/macOS
nc -vz api.example.test 443

# Windows PowerShell
Test-NetConnection -ComputerName api.example.test -Port 443 
 Attendu : message de succès. Si délai, suspectez routage ou pare-feu. Si refusé, suspectez absence d'écouteur ou port fermé à destination.

### 4. Valider TLS tôt si HTTPS utilisé

openssl s_client -connect api.example.test:443 -servername api.example.test -tls1_2 -brief < /dev/null 
 Attendu : session établie, chaîne de certificats valide, SNI correspondant à api.example.test , protocole/chiffrement acceptables. Si la vérification échoue, corrigez TLS avant de déboguer les routes HTTP.

### 5. Alors seulement tester les flux HTTP complets

curl -v https://api.example.test/health 
 Attendu : 200 et en-têtes corrects. Comparez un appel direct à l'IP d'origine (via --resolve ) vs via le répartiteur de charge pour isoler les problèmes de proxy.

## Vérification et diagnostics

Lancez ces tests pour isoler chaque couche, avec résultats attendus et exemples de sorties. Remplacez hôtes, ports et IP par les vôtres.

### Correction DNS

# Enregistrements A/AAAA
dig +nocmd api.example.test A +noall +answer

dig +nocmd api.example.test AAAA +noall +answer

# Tracer le chemin de résolution
dig +trace api.example.test

# Windows
nslookup api.example.test 
 Attendu : enregistrements A/AAAA pointant vers les bonnes IP, trace montrant les serveurs autoritatifs sans SERVFAIL. Si DNS incorrect, corrigez l'enregistrement à la source et respectez les TTL.

### Connectivité TCP

# Tester la poignée de main TCP seulement
nc -vz api.example.test 443

# Windows
Test-NetConnection -ComputerName api.example.test -Port 443 | Select-Object -Property ComputerName, RemotePort, TcpTestSucceeded 
 Attendu : TcpTestSucceeded: True (Windows) ou "succeeded" (nc). Si bloqué, capturez le saut d'échec avec traceroute.

### Chemin de routage

# Linux/macOS
traceroute -n api.example.test

# Windows
tracert -d api.example.test 
 Attendu : chemin complet vers l'IP de destination. Délais ou boucles indiquent problèmes de routage ou ACL entre réseaux.

### Écouteurs local et distant

# Sur l'hôte API
ss -lntp | grep ":443\|:3000"

# Alternative
netstat -tulpen 2>/dev/null | grep ":443\|:3000"

# Windows (hôte API)
netstat -ano | findstr LISTENING | findstr ":443 :3000" 
 Attendu : le service (ex. node, nginx) lié à l'adresse et au port attendus. Une liaison à 127.0.0.1 pour un service externe est une cause fréquente de "connection refused" depuis des clients distants.

### Inspection TLS

openssl s_client -connect api.example.test:443 -servername api.example.test -showcerts < /dev/null | sed -n '1,15p' 
 À vérifier :

- Sujet du certificat et SAN incluent api.example.test .

- Certificat non expiré ; chaîne complète.

- Protocole négocié acceptable (ex. TLSv1.2 ou plus récent).

Si SNI requis et omis, le serveur peut présenter le mauvais certificat.

### Attentes HTTP

# Vérification du code seulement
curl -s -o /dev/null -w "%{http_code}\n" https://api.example.test/health

# En-têtes verbeux
curl -I -v https://api.example.test/health 
 Attendu :

- 200 OK pour santé.

- En-têtes Server et Date présents.

- Si derrière un proxy, possiblement en-têtes Via et X-Forwarded-* .

Comparez via répartiteur vs IP d'origine avec --resolve pour isoler les différences de proxy.

### CORS (symptôme navigateur uniquement)

Les échecs CORS sont des problèmes de couche application, pas de joignabilité réseau, mais souvent rapportés comme "l'API ne marche pas" depuis les frontends. Vérifiez les en-têtes avec curl :

curl -s -D - https://api.example.test/route -o /dev/null | grep -i "access-control-allow-" 
 Attendu : Access-Control-Allow-Origin avec l'origine correcte ou * . Ajustez seulement au niveau API ou proxy qui définit ces en-têtes ; ne changez pas DNS ou pare-feux pour erreurs CORS.

### Scénario minimal de bout en bout (construit)

- API Express interne sur 10.0.1.20:3000 derrière nginx terminant TLS sur 443 à 203.0.113.10 .

- Test origine directe : curl -v --resolve api.example.test:443:203.0.113.10 https://api.example.test/health

- Test via DNS : curl -v https://api.example.test/health

Si direct réussit mais chemin DNS échoue, le problème est jusqu'au répartiteur inclus (DNS, route, pare-feu, config proxy). Si les deux échouent, suspectez service d'origine ou pare-feu hôte.

### Diagnostics par tâche et OS

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Tâche</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Linux/macOS</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Windows</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Résoudre DNS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">dig api.example.test</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">nslookup api.example.test</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Test connexion TCP</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">nc -vz hôte port</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">Test-NetConnection -Port port -ComputerName hôte</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tracer route</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">traceroute hôte</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">tracert hôte</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier ports écoutés</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">ss -lntp</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">netstat -ano</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Détails TLS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl s_client -connect hôte:443 -servername hôte</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl</code> (si installé)</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Requête HTTP verbeuse</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">curl -v URL</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">curl.exe -v URL</code></td></tr></tbody>
</table>
</div>

## Modes de défaillance et récupération

Voici les défaillances réseau courantes pour API REST, comment les prouver, correctifs sûrs et retours arrière.

### 1. Cible DNS erronée ou TTL obsolète

- Symptôme : curl vers nom d'hôte atteint le mauvais serveur ; --resolve vers l'IP voulue fonctionne.

- Preuve : dig +short montre IP inattendues ; TTL élevé.

- Correctif : Mettez à jour enregistrements A/AAAA/CNAME au DNS autoritatif. Si bascule progressive, abaissez TTL au moins une période TTL à l'avance, puis mettez à jour.

- Retour arrière : Revenez aux valeurs d'enregistrement précédentes. Gardez une exportation de zone pré-changement. Vérifiez avec dig +trace et vidage cache client.

- Vérification : dig +short et curl -v montrent le bon chemin ; latence et en-têtes correspondent au backend visé.

### 2. Port fermé ou filtré par pare-feu/ACL

- Symptôme : nc / Test-NetConnection timeout ; traceroute atteint le réseau, mais poignée TCP échoue.

- Preuve : Règles pare-feu hôte refusent entrant 443 ; ou ACL réseau bloque CIDR sources.

- Correctif (hôte) : autorisez entrant vers port service depuis sources requises seulement.

Linux (exemple ufw ; adaptez à votre pare-feu) :

ufw allow proto tcp from 198.51.100.0/24 to any port 443 comment 'allow API clients'
ufw status numbered 
 Windows (PowerShell exemple ; exécutez comme admin) :

New-NetFirewallRule -DisplayName "Allow API 443" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow -RemoteAddress 198.51.100.0/24
Get-NetFirewallRule -DisplayName "Allow API 443" | Get-NetFirewallPortFilter 

- Retour arrière : supprimez la nouvelle règle et restaurez l'état antérieur. Documentez IDs ou noms d'affichage.

 Linux (ufw) :

ufw status numbered
ufw delete <numero-regle> 
 Windows :

Remove-NetFirewallRule -DisplayName "Allow API 443" 

- Vérification : Test-NetConnection / nc réussit ; curl renvoie code HTTP attendu.

### 3. Service écoutant sur loopback seulement

- Symptôme : curl 127.0.0.1:3000 sur l'hôte renvoie 200 , mais clients distants obtiennent "connection refused\).

- Preuve : ss / netstat montre 127.0.0.1:3000 , pas 0.0.0.0:3000 .

- Correctif : Mettez à jour l'adresse de liaison du service à 0.0.0.0 ou IP d'interface hôte ; redémarrez le service.

- Risque : Exposer un port interne en externe. Associez à un proxy inverse, règles pare-feu, ou déplacez terminaison TLS en conséquence.

- Retour arrière : Restaurez fichier config antérieur et redémarrez service.

- Vérification : ss / netstat montre bonne adresse de liaison ; nc et curl distants réussissent.

### 4. Inadéquation TLS ou certificat expiré

- Symptôme : curl -v montre échec vérification certificat ; navigateurs avertissent sur certificat.

- Preuve : openssl s_client montre mauvais CN/SAN ou cert expiré.

- Correctif : Installez certificat dont SAN inclut le nom d'hôte ; assurez-vous que SNI est utilisé si multiples certificats servis.

- Test local temporaire uniquement : curl --insecure pour une étape de vérification unique en dev pour confirmer le chemin, mais n'utilisez pas comme correctif permanent.

- Retour arrière : Réinstallez certificat fonctionnel précédent si le nouveau échoue, puis retentez renouvellement/émission.

- Vérification : openssl s_client montre chaîne valide ; curl sans --insecure réussit.

### 5. Mauvais routage par répartiteur ou proxy inverse

- Symptôme : Chemin origine direct (via --resolve ) fonctionne ; chemin LB échoue avec 502 / 503 .

- Preuve : curl -v montre en-têtes Via et 5xx ; journaux d'accès LB/proxy montrent erreurs connexion upstream.

- Correctif : Corrigez adresse/port upstream, vérifications de santé, mode terminaison TLS vs pass-through.

- Retour arrière : Revenez à la dernière config LB connue-bonne.

- Vérification : Vérifications santé passent au vert ; curl via LB renvoie 200 .

### 6. Asymétrie de route ou problèmes NAT

- Symptôme : SYN client atteint serveur mais réponses ne reviennent pas ; timeouts intermittents entre sous-réseaux.

- Preuve : Capture paquet sur serveur montre SYN reçu, SYN-ACK envoyé, mais client ne reçoit jamais. Table de routage montre mauvaise passerelle.

- Correctif : Corrigez passerelle par défaut ou routes spécifiques. Assurez-vous NAT et groupes sécurité autorisent trafic retour.

- Retour arrière : Restaurez table de routage antérieure ; évitez changements permanents sans contrôle de changement.

- Vérification : traceroute stable ; nc / Test-NetConnection réussit de façon constante.

### 7. Problèmes MTU/fragmentation (avancé)

- Symptôme : Petites requêtes réussissent ; grosses négociations TLS ou réponses bloquent.

- Preuve : Échec découverte MTU chemin ; tcpdump montre retransmissions répétées.

- Correctif : Réduisez MTU sur interface affectée ou corrigez segment réseau avec ICMP autorisé pour PMTU. Testez changements en fenêtre maintenance.

- Retour arrière : Restaurez MTU précédent.

- Vérification : Grosses réponses et négociations TLS complètent.

## Liste de contrôle opérationnelle

 Utilisez cette liste comme runbook reproductible. Ajustez noms d'hôtes et ports à votre environnement.

- Enregistrer les faits

- Nom d'hôte, IP attendue(s), port(s), protocole.

- Changements récents et TTL.

- DNS

- dig / nslookup le nom d'hôte ; confirmez A/AAAA.

- Si erroné, testez avec curl --resolve pour confirmer que la bonne cible fonctionne.

- Connectivité

- nc -vz ou Test-NetConnection vers le port. Si bloqué, investiguez pare-feu/ACL.

- Routage

- traceroute / tracert ; confirmez chemin propre sans boucles/timeouts.

- Écouteurs

- ss / netstat sur hôte API ; confirmez bonne adresse et port de liaison.

- TLS

- openssl s_client ; validez CN/SAN, expiration et SNI.

- Comportement HTTP

- curl -v route santé ; comparez via LB vs origine directe.

- Pour signalements navigateur, vérifiez en-têtes CORS via curl -I .

- Corriger en sécurité

- Appliquez le plus petit changement expliquant le symptôme.

- Gardez sauvegardes configs DNS/LB/pare-feu.

- Vérifier

- Relancez la requête exacte qui échouait et les vérifications couche-spécifiques.

- Retour arrière si nécessaire

- Revenez à la config antérieure connue-bonne ; revérifiez stabilité.

## Conclusion

Vous disposez maintenant d'une approche pratique, par couches, pour dépanner les problèmes réseau d'API REST. Commencez par un test étroit, mesurable, executable localement, vérifiez DNS et TCP avant la logique HTTP, et progressez vers l'extérieur : hôte, proxy, réseau. Pour chaque changement, connaissez le résultat attendu, comment le confirmer, et comment revenir en arrière en sécurité. Avec cette méthode et les commandes, exemples et liste de contrôle inclus, développeurs, consultants DevOps et équipes techniques de startups peuvent diagnostiquer et réparer les pannes réseau avec confiance et risque minimal.