Modèle TCP/IP, IP, Ports, DNS, Pare-feu
Utilisez les flèches, cliquez ou glissez pour naviguer
1. Comprendre les 4 couches TCP/IP
Application, Transport, Internet, Liaison
2. TCP vs UDP
Connexion fiable vs datagrammes rapides
3. Adressage IP & Ports
Publique/privée, localhost, 0.0.0.0, ports courants
4. DNS & Diagnostic réseau
Résolution de noms, curl, ping, ss, dig
5. Configurer un pare-feu avec UFW
Règles de base pour sécuriser un serveur
Rappel : du code HTTP aux couches réseau
Quand tu fais fetch(), chaque couche est impliquée
Le modèle TCP/IP en 4 couches
Application, Transport, Internet, Liaison
TCP vs UDP
Connexion fiable vs datagrammes rapides
Adressage IP & Ports
IPv4, sous-réseaux, localhost, 0.0.0.0, ports courants
DNS : résolution de noms
/etc/hosts, nslookup, dig
Outils de diagnostic
curl, ping, ss, traceroute
Pare-feu UFW
Règles de base sur Ubuntu
Tu connais HTTP côté applicatif — on descend dans les couches
// Ce que tu écris tous les jours :
fetch('http://api.com:3000/users')
// Chaque couche réseau est impliquée ↓
fetch('http://api.com:3000/users')
🟦 Application (HTTP)
Envoie une requête GET /users avec les headers
🟦 Transport (TCP)
Établit une connexion vers le port 3000, garantit la livraison
🟦 Internet (IP)
Résout api.com en adresse IP, route les paquets sur le réseau
🟦 Liaison (Ethernet/WiFi)
Transmet les bits sur le câble ou les ondes radio
4 couches, pas 7 — la version simplifiée du modèle OSI
Chaque couche a un rôle précis
Les données descendent puis remontent les couches
Application
HTTP, HTTPS, FTP, SSH, DNS — ce que ton code utilise
Transport
TCP (fiable) ou UDP (rapide) — ports & connexions
Internet
IP, routage, adresses — achemine les paquets
Liaison (Link)
Ethernet, WiFi, adresses MAC — le support physique
Chaque couche ajoute son propre header
🟦 Couche Application
Données HTTP : GET /users HTTP/1.1
🟦 Couche Transport
Ajoute le header TCP : port source (52341) → port dest (3000)
🟦 Couche Internet
Ajoute le header IP : IP source (192.168.1.10) → IP dest (93.184.216.34)
🟦 Couche Liaison
Ajoute le header Ethernet : MAC source → MAC dest (routeur)
💡 Au retour, chaque couche retire son header — comme emballer/déballer un colis
Fiable vs Rapide — deux philosophies de transport
TCP
Connexion fiable
UDP
Datagrammes rapides
Connexion fiable avec accusé de réception
1️⃣ Three-way handshake (SYN → SYN-ACK → ACK)
Le client et le serveur se mettent d'accord avant d'échanger
2️⃣ Accusés de réception (ACK)
Chaque segment reçu est confirmé — pas de perte silencieuse
3️⃣ Réordonnancement
Les paquets arrivent dans l'ordre, même si le réseau les mélange
4️⃣ Contrôle de flux
Ralentit si le récepteur est saturé
✅ Connexion établie ! Les données peuvent circuler
💡 Analogie : appeler quelqu'un → "Allô ?" → "Oui, j'écoute" → "Parfait, je parle"
Envoi rapide, sans garantie de livraison
❌ Pas de handshake
On envoie directement, pas de négociation préalable
❌ Pas d'accusé de réception
Si un paquet est perdu, on ne le retransmet pas
❌ Pas de réordonnancement
Les paquets arrivent dans l'ordre du réseau
✅ Mais : ultra rapide, faible latence
Idéal quand la vitesse compte plus que la fiabilité
TCP
✅ Fiable (aucune perte)
✅ Ordonné
✅ Contrôle de congestion
❌ Plus lent (handshake + ACK)
❌ Overhead plus important
HTTP, HTTPS, SSH, FTP, SMTP
PostgreSQL (5432)
UDP
✅ Rapide (pas de handshake)
✅ Faible latence
✅ Léger (peu d'overhead)
❌ Pas de garantie de livraison
❌ Pas d'ordre garanti
DNS (53), DHCP, Streaming vidéo
Jeux en ligne, VoIP
TCP — quand la donnée doit arriver
API REST
Un utilisateur manquant = bug
Transfert de fichier
Un bit manquant = fichier corrompu
SSH
Chaque commande doit arriver
UDP — quand la vitesse compte
Streaming vidéo
Une frame perdue = un saut, pas grave
Jeu en ligne
Latence = mort dans le jeu
DNS
Une petite requête, on réessaie si perdue
L'adresse de ta machine sur le réseau
192.168.1.42
4 octets séparés par des points — 32 bits en IPv4
192.168.1.42 / 24
192.168
Réseau (classe C privée)
.1
Sous-réseau
.42
Hôte (ta machine)
Le /24 signifie que les 24 premiers bits sont le réseau
Masque : 255.255.255.0 → 254 machines possibles (192.168.1.1 à 192.168.1.254)
IP Privée
Visible uniquement dans le réseau local
10.0.0.0 — 10.255.255.255
172.16.0.0 — 172.31.255.255
192.168.0.0 — 192.168.255.255
🏠 Ton ordi, ton téléphone, ton Raspberry Pi
IP Publique
Visible depuis Internet
93.184.216.34
142.250.179.46
🌍 Ton serveur, le site web, l'API
⚠️ Capital pour le déploiement : ton serveur a une IP publique, ton app tourne sur une IP privée dans le conteneur
127.0.0.1
localhost
Écoute uniquement sur l'interface de loopback
✅ curl http://localhost:3000 → OK
❌ curl http://192.168.1.10:3000 → Refused
Accessible uniquement depuis la machine elle-même
0.0.0.0
Toutes les interfaces
Écoute sur toutes les interfaces réseau
✅ curl http://localhost:3000 → OK
✅ curl http://192.168.1.10:3000 → OK
C'est ce qu'il faut utiliser dans un conteneur Docker !
Ton app écoute sur 127.0.0.1:3000 dans un conteneur Docker
Tu essaies d'y accéder depuis l'hôte → Connection refused!
❌ Dans le conteneur
app.listen(3000, '127.0.0.1')
Seul le conteneur peut y accéder
✅ Dans le conteneur
app.listen(3000, '0.0.0.0')
Accessible depuis l'hôte et le réseau
💡 Docker mappe les ports de l'hôte vers le conteneur, mais le conteneur doit écouter sur 0.0.0.0 pour recevoir le trafic
Comment plusieurs services cohabitent sur une même IP
Un port = une porte d'entrée sur la machine
0 à 65535 — 65536 portes possibles
0 — 1023 : Well-Known Ports
Réservés aux services système — nécessitent les droits root
22 = SSH | 80 = HTTP | 443 = HTTPS
21 = FTP | 25 = SMTP | 53 = DNS
1024 — 49151 : Registered Ports
Assignés par IANA à des applications connues
5432 = PostgreSQL | 3306 = MySQL | 6379 = Redis
27017 = MongoDB | 5432 = PostgreSQL
49152 — 65535 : Ephemeral Ports
Ports temporaires utilisés par le client pour la connexion
Ex: ton navigateur utilise le port 52341 pour se connecter au port 443
SSH
Connexion sécurisée à un serveur
HTTP
Web non chiffré
HTTPS
Web chiffré (TLS)
PostgreSQL
Base de données relationnelle
Dev Server
Node.js, React, Vite...
Redis
Cache in-memory
💡 Les ports < 1024 nécessitent root — c'est pour ça qu'on met Nginx (port 80) devant Node.js (port 3000)
Comment google.com devient 142.250.179.46
Les humains retiennent des noms
Les machines retiennent des IP
DNS fait le pont
1️⃣ Navigateur vérifie son cache
Déjà visité ? L'IP est en mémoire
2️⃣ OS vérifie /etc/hosts
Fichier local de correspondance nom → IP
3️⃣ Requête au DNS du routeur / FAI
Le routeur a son propre cache DNS
4️⃣ Serveur DNS racine → TLD → Serveur autoritaire
La chaîne complète : . → .com → google.com → IP
💡 DNS est du cache à plusieurs niveaux ! Chaque niveau peut avoir l'IP en cache
# Fichier /etc/hosts
127.0.0.1 localhost
192.168.1.50 mon-serveur.local
10.0.0.1 db.internal
✅ Priorité sur le DNS réseau — lu avant toute requête externe
💡 Utile en dev pour pointer api.local vers 127.0.0.1
💡 Docker ajoute automatiquement des entrées dans /etc/hosts des conteneurs
nslookup — requête simple
$ nslookup google.com
Server: 8.8.8.8
Name: google.com
Address: 142.250.179.46
dig — requête détaillée
$ dig google.com
;; ANSWER SECTION:
google.com. 300 IN A 142.250.179.46
;; Query time: 12 msec
💡 dig montre le TTL (durée de cache), le temps de réponse, et les enregistrements complets
Quand ça ne marche pas — comment comprendre pourquoi
Chaque outil teste une couche différente
Le bon outil = le bon diagnostic
$ ping google.com
PING google.com (142.250.179.46): 56 data bytes
64 bytes: icmp_seq=0 ttl=116 time=14.2 ms
64 bytes: icmp_seq=1 ttl=116 time=13.8 ms
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% loss
✅ ping réussi
La machine est joignable au niveau IP
❌ ping échoué
Problème réseau, pare-feu, ou machine éteinte
⚠️ ping teste ICMP, pas le port 80 ! Un serveur peut répondre au ping mais refuser les connexions HTTP
$ curl -v http://api.example.com:3000/users
* Connected to api.example.com (93.184.216.34) port 3000
> GET /users HTTP/1.1
> Host: api.example.com:3000
< HTTP/1.1 200 OK
[{"id": 1, "name": "Alice"}]
curl -I
Headers seulement (HEAD)
curl -v
Mode verbeux (connexion + headers)
curl -X POST -d
Envoyer des données
curl -w "%{http_code}"
Extraire le code HTTP
✅ curl teste la couche Application — c'est le vrai test HTTP
$ ss -tlnp
State Recv-Q Send-Q Local Address:Port
LISTEN 0 128 0.0.0.0:22 users:(("sshd",pid=1234))
LISTEN 0 511 0.0.0.0:80 users:(("nginx",pid=5678))
LISTEN 0 128 127.0.0.1:3000 users:(("node",pid=9012))
LISTEN 0 100 127.0.0.1:5432 users:(("postgres",pid=3456))
-t
TCP
-l
Listening
-n
Numérique
-p
Processus
⚠️ Node écoute sur 127.0.0.1:3000 — pas accessible depuis l'extérieur ! Il faudrait 0.0.0.0:3000
$ traceroute google.com
traceroute to google.com (142.250.179.46)
1 _gateway (192.168.1.1) 1.2 ms
2 10.0.0.1 5.4 ms
3 78.234.12.1 12.1 ms
4 google.core (142.250.179.46) 14.3 ms
Chaque ligne = un saut (hop) à travers un routeur
Si un hop montre *** *** *** → ce routeur ne répond pas (pare-feu ou filtrage)
💡 Utile pour voir où le réseau ralentit ou bloque
| Outil | Couche testée | Question que ça répond |
|---|---|---|
| ping | Internet (ICMP) | La machine est-elle joignable ? |
| curl | Application (HTTP) | Le service HTTP répond-il ? |
| ss | Transport (Ports) | Quels ports sont ouverts ? |
| dig | Application (DNS) | Quelle IP pour ce domaine ? |
| traceroute | Internet (Routage) | Où le réseau bloque-t-il ? |
Uncomplicated Firewall sur Ubuntu
Contrôler ce qui entre et sort de la machine
Par défaut : tout bloquer, puis ouvrir au besoin
# Vérifier le statut
$ sudo ufw status
# Activer le pare-feu
$ sudo ufw enable
# Politique par défaut : tout bloquer en entrée
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
⚠️ Toujours autoriser SSH avant d'activer le pare-feu !
$ sudo ufw allow 22
Sinon tu te lockes out de ton serveur !
# Autoriser SSH (OBLIGATOIRE en premier!)
$ sudo ufw allow 22/tcp
# Autoriser HTTP et HTTPS
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
# Autoriser un port spécifique (dev)
$ sudo ufw allow 3000/tcp
# Autoriser depuis une IP seulement
$ sudo ufw allow from 192.168.1.10 to any port 5432
# Supprimer une règle
$ sudo ufw delete allow 3000/tcp
✅ Vérifier les règles actives :
$ sudo ufw status numbered
Tu lances un service sur le port 3000...
Tu essaies d'y accéder → Connection refused ou timeout
Le pare-feu bloque le port !
❌ Oublier d'ouvrir le port
$ node server.js
# Le port 3000 est bloqué par UFW
✅ Ouvrir le port d'abord
$ sudo ufw allow 3000/tcp
$ node server.js
💡 Checklist : service lancé ? + bonne IP (0.0.0.0) ? + port ouvert dans UFW ?
❌ Confusion localhost vs 0.0.0.0
127.0.0.1 = que la machine locale | 0.0.0.0 = toutes les interfaces
✅ Fréquent quand on passe à Docker — toujours utiliser 0.0.0.0 dans un conteneur
❌ Oublier d'ouvrir le port dans le pare-feu
Le service tourne mais UFW bloque les connexions entrantes
✅ Après chaque nouveau service : sudo ufw allow <port>
❌ Penser que ping teste HTTP
ping utilise ICMP, pas le port 80 — un serveur peut répondre au ping mais refuser HTTP
✅ Utiliser curl pour tester HTTP, ping pour tester la connectivité IP
❌ Ignorer le cache DNS multi-niveaux
Navigateur → OS → routeur → FAI → serveur DNS — un changement peut mettre des heures à se propager
✅ dig @8.8.8.8 pour contourner le cache local
Quand un service ne répond pas, vérifier dans cet ordre :
Le service tourne-t-il ?
ss -tlnp | ps aux | grep node
Écoute-t-il sur la bonne IP ?
127.0.0.1 (local) vs 0.0.0.0 (toutes interfaces)
Le port est-il ouvert dans le pare-feu ?
sudo ufw status
La résolution DNS est-elle correcte ?
dig mon-domaine.com
Le chemin réseau est-il ouvert ?
ping puis curl -v
4 couches
Application → Transport → Internet → Liaison
TCP vs UDP
Fiable vs rapide — choisir selon le besoin
0.0.0.0 ≠ 127.0.0.1
Toutes interfaces vs loopback seulement
DNS = cache à niveaux
Navigateur → OS → Routeur → FAI → Autoritaire
Diagnostic = bon outil pour la bonne couche
ping (ICMP) | curl (HTTP) | ss (ports) | dig (DNS) | traceroute (route)
Pare-feu : SSH d'abord, puis ouvrir au besoin
ufw allow 22 → ufw allow 80 → ufw allow 443 → ufw enable
Le réseau n'est plus un mystère
Quand fetch() échoue → tu sais maintenant où chercher