Paillasse/portail/public/js/contenus-reseau-2.js
Adam Belkacemi 30e14b1c54 ajoute le portail Laravel : connexion prof/élève, session unique, gestion de classe, salle d'attente
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 02:01:58 +02:00

230 lines
90 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Cours complets · Réseaux lot 2 : DNS, NAT/PAT, routage statique
(function () {
var K = 'stroke="#000" stroke-width="3"', F = 'font-family="Archivo,sans-serif" font-weight="800"', M = 'font-family="IBM Plex Mono,monospace" font-weight="600"';
var bx = function (x, y, w, h, c, t, fs) { return '<rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" fill="' + c + '" ' + K + '/><text x="' + (x + w / 2) + '" y="' + (y + h / 2 + 5) + '" text-anchor="middle" ' + F + ' font-size="' + (fs || 15) + '">' + t + '</text>'; };
var ln = function (x1, y1, x2, y2) { return '<line x1="' + x1 + '" y1="' + y1 + '" x2="' + x2 + '" y2="' + y2 + '" ' + K + '/>'; };
var tx = function (x, y, s, fs, mono) { return '<text x="' + x + '" y="' + y + '" ' + (mono ? M : F) + ' font-size="' + (fs || 14) + '">' + s + '</text>'; };
var svg = function (w, h, b) { return '<svg viewBox="0 0 ' + w + ' ' + h + '" class="h-auto w-full" role="img">' + b + '</svg>'; };
var Y = '#FFD23F', G = '#7CF2C0', P = '#FF6FB5', L = '#C4B5FD', N = '#F6F5F1', W = '#fff';
var reg = function (c) {
(window.CONTENUS_PRO = window.CONTENUS_PRO || []).unshift(c.cours);
(window.CONTENUS_PLUS = window.CONTENUS_PLUS || {})[c.cours.id] = c.plus;
(window.CONTENUS_EXEMPLES = window.CONTENUS_EXEMPLES || {})[c.cours.id] = c.exemples;
(window.CONTENUS_LONG = window.CONTENUS_LONG || {})[c.cours.id] = c.long;
(window.CONTENUS_SCHEMAS = window.CONTENUS_SCHEMAS || {})[c.cours.id] = c.schemas;
};
// ================= DNS =================
reg({
cours: { id: 'dns', match: /DNS : résolution|zones, enregistrements|Bind/i,
titre: 'DNS : résolution de noms, zones, enregistrements et serveur Bind9', duree: '',
niveau: 'BTS SIO SISR · BTS CIEL IR · BUT R&T S2-S3 · TSSR / AIS',
prerequis: ['Modèle TCP/IP, UDP et TCP', 'Adressage IPv4', 'Diagnostic réseau en ligne de commande'],
competences: ['BTS SIO SISR · Bloc 2 · Installer, configurer et administrer un service d’infrastructure', 'BTS SIO · Bloc 1 · Répondre aux incidents', 'BTS CIEL · C04 · Installer un service réseau', 'BUT R&T · Compétence « Administrer les réseaux et l’Internet »'],
intro: '« Ce n’est jamais le DNS. C’était le DNS. » Cette plaisanterie d’administrateurs résume une réalité de production : une part considérable des incidents qualifiés de « panne réseau » est en fait une panne de résolution de noms. L’annuaire Active Directory, la messagerie, les certificats HTTPS, les mises à jour, l’ENT : tout repose sur la capacité à traduire un nom en adresse. Un DNS lent rend tout lent, un DNS faux rend tout faux, un DNS absent arrête un établissement. Ce module décrit le fonctionnement interne du protocole, la structure des zones et des enregistrements, la mise en œuvre d’un serveur Bind9 faisant autorité et d’un résolveur, et la méthode de diagnostic avec dig.',
cm: [
{ t: 'Un annuaire distribué et hiérarchique', d: '', html: 'Le DNS (Domain Name System, RFC 1034 et 1035) est une base de données distribuée à l’échelle mondiale. Aucun serveur ne connaît tous les noms : chacun fait <b>autorité</b> sur une portion de l’arbre, appelée <b>zone</b>, et sait à qui déléguer le reste.<br><br>L’arbre part de la <b>racine</b>, notée par un point final implicite. Sous la racine se trouvent les <b>domaines de premier niveau</b> (TLD) : génériques comme .com et .org, nationaux comme .fr, géré par l’Afnic. Sous .fr, chaque organisation enregistre son domaine, par exemple lycee-exemple.fr, puis y crée librement des sous-domaines et des noms d’hôtes : www, ent, mail, intranet.<br><br>Un nom complet, de l’hôte jusqu’à la racine, s’appelle un <b>FQDN</b> (Fully Qualified Domain Name) : <code>ent.lycee-exemple.fr.</code> avec le point final. Chaque étiquette est limitée à 63 caractères et le nom complet à 253.' },
{ t: 'Résolveur récursif et serveur faisant autorité', d: '', html: 'Il faut distinguer deux rôles, souvent confondus. Le <b>serveur faisant autorité</b> (authoritative) détient les données officielles d’une zone et répond uniquement sur cette zone ; il pose le drapeau <b>aa</b> dans ses réponses. Le <b>résolveur récursif</b> (recursive resolver) reçoit les questions des clients, part à la recherche de la réponse en interrogeant les serveurs faisant autorité, puis la garde en <b>cache</b> pendant la durée indiquée par le <b>TTL</b>.<br><br>Sur un poste, un troisième acteur intervient : le <b>stub resolver</b> de la bibliothèque système, qui se contente de transmettre la question au résolveur configuré. Sous Debian récent, systemd-resolved sert souvent de résolveur local à l’adresse 127.0.0.53 ; le fichier <code>/etc/resolv.conf</code> pointe alors vers lui, et <code>resolvectl status</code> montre les vrais serveurs utilisés.<br><br>Mélanger les deux rôles sur un même serveur exposé à Internet est une faute : un résolveur ouvert à tous est exploité pour des <b>attaques par amplification</b>, où de petites requêtes à l’adresse source usurpée provoquent de grosses réponses vers la victime.' },
{ t: 'Le parcours d’une résolution', d: '', html: 'Quand un élève tape ent.lycee-exemple.fr et que rien n’est en cache, le résolveur procède par <b>requêtes itératives</b>. Il interroge un des 13 ensembles de <b>serveurs racine</b> (a.root-servers.net à m.root-servers.net, répliqués en anycast dans le monde entier), dont il connaît les adresses grâce au fichier d’amorçage (root hints). La racine ne connaît pas la réponse mais renvoie une <b>délégation</b> : la liste des serveurs de .fr. Le résolveur interroge alors un serveur de .fr, qui délègue à son tour vers les serveurs de lycee-exemple.fr. Ceux-ci, faisant autorité, donnent enfin l’adresse.<br><br>Le client, lui, n’a posé qu’une seule question, dite <b>récursive</b> (drapeau RD, recursion desired), et reçoit une réponse complète. Toutes les réponses intermédiaires sont mises en cache : la question suivante sur un autre nom en .fr évitera l’interrogation de la racine.<br><br>Le transport se fait en <b>UDP port 53</b> pour la plupart des requêtes. Si la réponse dépasse la taille autorisée (512 octets historiquement, environ 1 232 octets avec EDNS0), le serveur renvoie une réponse tronquée (drapeau TC) et le client recommence en <b>TCP port 53</b>. Les transferts de zone utilisent toujours TCP.', exemple: '$ dig +trace ent.lycee-exemple.fr\n. 518400 IN NS a.root-servers.net.\n;; Received 811 bytes from 127.0.0.53#53\nfr. 172800 IN NS d.nic.fr.\n;; Received 1217 bytes from 198.41.0.4#53(a.root-servers.net)\nlycee-exemple.fr. 3600 IN NS ns1.lycee-exemple.fr.\n;; Received 402 bytes from 194.0.9.1#53(d.nic.fr)\nent.lycee-exemple.fr. 300 IN A 203.0.113.40\n;; Received 65 bytes from 203.0.113.2#53(ns1.lycee-exemple.fr)' },
{ t: 'Les types d’enregistrements', d: '', html: 'Une zone est une liste d’<b>enregistrements de ressources</b> (RR), chacun composé d’un nom, d’un TTL, d’une classe (IN, pour Internet) d’un type et d’une valeur. Il faut connaître les types suivants par cœur, et surtout leurs pièges.<br><br>Un <b>CNAME</b> est un alias : il redirige un nom vers un autre nom. Un nom qui porte un CNAME ne peut porter aucun autre enregistrement, ce qui interdit un CNAME à l’apex de la zone (le nom du domaine lui-même). Un <b>MX</b> désigne un serveur de messagerie avec une priorité : la plus petite valeur est essayée en premier. Il doit pointer vers un nom qui a un enregistrement A, jamais vers un CNAME ni une adresse IP. Les <b>TXT</b> portent des informations textuelles, aujourd’hui essentiellement la politique anti-usurpation de la messagerie (SPF, DKIM, DMARC) et les preuves de propriété de domaine.', table: [['Type', 'Rôle', 'Exemple de valeur'], ['A', 'nom → adresse IPv4', '203.0.113.40'], ['AAAA', 'nom → adresse IPv6', '2001:db8:40::10'], ['CNAME', 'alias vers un autre nom', 'ent.lycee-exemple.fr.'], ['MX', 'serveur de messagerie + priorité', '10 mx1.lycee-exemple.fr.'], ['NS', 'serveurs faisant autorité de la zone', 'ns1.lycee-exemple.fr.'], ['SOA', 'paramètres de la zone', 'ns1… hostmaster… 2026093001 …'], ['PTR', 'adresse → nom (zone inverse)', 'ent.lycee-exemple.fr.'], ['TXT', 'texte libre, SPF, DKIM, DMARC', '"v=spf1 mx -all"'], ['SRV', 'localiser un service (AD, SIP)', '0 100 389 dc1.lycee.local.'], ['CAA', 'autorités autorisées à émettre un certificat', '0 issue "letsencrypt.org"']] },
{ t: 'Anatomie d’un fichier de zone', d: '', html: 'Le fichier de zone commence par la directive <code>$TTL</code>, puis l’enregistrement <b>SOA</b> (Start of Authority), obligatoire et unique. Il contient le serveur primaire, l’adresse de l’administrateur (le premier point remplace le @), puis cinq valeurs qui pilotent la réplication.<br><br>Le <b>serial</b> est un numéro de version. Les serveurs secondaires ne récupèrent la zone que s’il a augmenté ; la convention AAAAMMJJnn (date plus numéro de modification du jour) évite les erreurs. <b>Refresh</b> fixe l’intervalle de vérification des secondaires, <b>retry</b> le délai avant une nouvelle tentative en cas d’échec, <b>expire</b> la durée au bout de laquelle un secondaire sans nouvelles cesse de répondre, et le dernier champ le <b>TTL négatif</b>, durée de mise en cache d’une réponse « ce nom n’existe pas ».<br><br>Dans le fichier, <code>@</code> désigne le nom de la zone, et tout nom qui ne se termine pas par un point est complété par ce nom. C’est la source de l’erreur la plus fréquente : écrire <code>mx1.lycee-exemple.fr</code> sans point final produit <code>mx1.lycee-exemple.fr.lycee-exemple.fr.</code>', exemple: '$TTL 3600\n@ IN SOA ns1.lycee-exemple.fr. hostmaster.lycee-exemple.fr. (\n 2026093001 ; serial AAAAMMJJnn\n 7200 ; refresh\n 900 ; retry\n 1209600 ; expire (14 jours)\n 300 ) ; TTL négatif\n IN NS ns1.lycee-exemple.fr.\n IN NS ns2.lycee-exemple.fr.\n IN MX 10 mx1.lycee-exemple.fr.\n IN TXT "v=spf1 mx -all"\n@ IN A 203.0.113.40\nns1 IN A 203.0.113.2\nns2 IN A 198.51.100.2\nmx1 IN A 203.0.113.25\nent IN A 203.0.113.40\nwww IN CNAME ent', attention: 'Oublier d’incrémenter le serial après une modification est l’erreur classique : le primaire répond avec les nouvelles données, les secondaires avec les anciennes, et le comportement devient aléatoire selon le serveur interrogé.' },
{ t: 'Zones inverses', d: '', html: 'La résolution inverse traduit une adresse en nom grâce aux enregistrements <b>PTR</b>. Elle est placée sous le domaine spécial <b>in-addr.arpa</b>, avec les octets de l’adresse écrits à l’envers, car le DNS lit les noms de droite à gauche du plus général au plus précis, alors qu’une adresse IP se lit de gauche à droite. Le réseau 10.62.40.0/24 correspond à la zone <code>40.62.10.in-addr.arpa</code>.<br><br>Les zones inverses ne sont pas un luxe. Les serveurs de messagerie refusent souvent le courrier d’une adresse sans PTR cohérent, les journaux deviennent lisibles, SSH et certains outils d’administration l’utilisent, et Active Directory en dépend. Pour les adresses publiques, la zone inverse est gérée par l’opérateur ou l’hébergeur, à qui l’on demande la création du PTR.', exemple: '; /etc/bind/db.10.62.40\n$TTL 3600\n@ IN SOA ns1.lycee.local. hostmaster.lycee.local. ( 2026093001 7200 900 1209600 300 )\n IN NS ns1.lycee.local.\n10 IN PTR ns1.lycee.local.\n20 IN PTR ent.lycee.local.' },
{ t: 'Mettre en œuvre Bind9', d: '', html: '<b>Bind9</b>, maintenu par l’ISC, reste la référence au programme des BTS et dans de nombreuses infrastructures. On le configure dans <code>/etc/bind/named.conf.options</code> pour le comportement général (récursivité, redirecteurs, listes d’accès) et dans <code>named.conf.local</code> pour déclarer les zones.<br><br>La récursivité doit être <b>limitée aux réseaux internes</b> par une ACL. Les <b>forwarders</b> permettent de faire suivre les requêtes externes vers les résolveurs de l’opérateur ou du rectorat plutôt que de partir de la racine. Pour la redondance, on déclare un serveur <b>secondaire</b> (type secondary, anciennement slave) qui récupère la zone par <b>transfert AXFR/IXFR</b>, le primaire l’autorisant explicitement avec allow-transfer et le prévenant par un NOTIFY à chaque changement de serial.<br><br>Deux outils valident la configuration avant tout rechargement : <code>named-checkconf</code> pour la syntaxe générale et <code>named-checkzone</code> pour chaque fichier de zone. On recharge ensuite sans coupure avec <code>rndc reload</code>.', exemple: '// named.conf.options\nacl interne { 10.62.0.0/16; 127.0.0.1; };\noptions {\n directory "/var/cache/bind";\n recursion yes;\n allow-recursion { interne; };\n allow-query { any; };\n forwarders { 1.1.1.1; 9.9.9.9; };\n dnssec-validation auto;\n listen-on { 10.62.40.10; 127.0.0.1; };\n};\n\n// named.conf.local\nzone "lycee.local" {\n type primary;\n file "/etc/bind/db.lycee.local";\n allow-transfer { 10.62.40.11; };\n also-notify { 10.62.40.11; };\n};\nzone "40.62.10.in-addr.arpa" {\n type primary;\n file "/etc/bind/db.10.62.40";\n};' },
{ t: 'Cache, TTL et propagation', d: '', html: 'Chaque réponse est mise en cache par le résolveur pendant la durée de son <b>TTL</b>. C’est ce qui rend le DNS rapide et résistant, mais c’est aussi ce qui explique qu’une modification ne soit pas visible partout immédiatement. On parle de « propagation », alors qu’il ne se propage rien : les caches expirent simplement les uns après les autres.<br><br>La conséquence opérationnelle est capitale : avant une migration de serveur, on <b>abaisse le TTL</b> de l’enregistrement concerné (par exemple de 86 400 à 300 secondes) au moins une durée de l’ancien TTL à l’avance. Le jour J, le changement d’adresse est pris en compte en cinq minutes. Une fois la migration validée, on remonte le TTL.<br><br>Les réponses négatives sont aussi mises en cache : si un nom a été demandé avant sa création, les clients continueront à recevoir NXDOMAIN pendant la durée du TTL négatif du SOA. On vide le cache d’un résolveur Bind avec <code>rndc flushname nom</code>, celui de systemd-resolved avec <code>resolvectl flush-caches</code>.' },
{ t: 'Sécurité du DNS', d: '', html: 'Le DNS d’origine n’authentifie rien. Un attaquant capable d’injecter une fausse réponse dans un cache (<b>empoisonnement de cache</b>, rendu célèbre par l’attaque Kaminsky en 2008) redirige tous les utilisateurs vers le serveur de son choix. Les parades sont la randomisation du port source et de l’identifiant de requête, désormais systématique, et surtout <b>DNSSEC</b>, qui signe cryptographiquement les enregistrements : le résolveur vérifie une chaîne de confiance depuis la racine et rejette toute réponse falsifiée (drapeau <b>ad</b> dans la réponse validée). L’Afnic signe la zone .fr depuis 2010.<br><br>La confidentialité est un autre sujet : les requêtes DNS classiques circulent en clair et révèlent tous les sites consultés. <b>DoT</b> (DNS over TLS, port 853) et <b>DoH</b> (DNS over HTTPS, port 443) les chiffrent. Sur un réseau d’établissement, DoH configuré directement dans les navigateurs contourne le filtrage imposé par le cadre réglementaire ; il se maîtrise par une politique de configuration des navigateurs.<br><br>Enfin, on restreint les <b>transferts de zone</b> aux seuls secondaires : un AXFR ouvert livre la cartographie complète du réseau à n’importe qui.' }
],
synthese: ['Serveur faisant autorité (drapeau aa) ≠ résolveur récursif avec cache', 'Résolution itérative : racine → TLD → domaine, réponses mises en cache selon le TTL', 'UDP 53, TCP 53 pour les grosses réponses et les transferts', 'A, AAAA, CNAME, MX, NS, SOA, PTR, TXT, SRV : connaître rôle et pièges', 'Point final obligatoire dans les zones, serial incrémenté à chaque modification', 'Abaisser le TTL avant une migration', 'Récursivité limitée par ACL, transferts restreints, DNSSEC validé'],
qcm: [
['Quel drapeau indique qu’une réponse vient d’un serveur faisant autorité ?', ['rd', 'ra', 'aa', 'ad'], 2, 'aa = authoritative answer.'],
['Dans quel cas le DNS utilise-t-il TCP ?', ['Jamais', 'Réponse tronquée et transferts de zone', 'Pour les requêtes MX', 'Toujours en IPv6'], 1, 'TC = 1 ou AXFR/IXFR.'],
['Pourquoi ne peut-on pas mettre un CNAME sur lycee-exemple.fr lui-même ?', ['Trop long', 'Un nom avec CNAME ne peut porter aucun autre enregistrement, or l’apex porte SOA et NS', 'Interdit par l’Afnic', 'Les CNAME sont obsolètes'], 1, 'Règle de la RFC 1034.'],
['Vers quoi doit pointer un enregistrement MX ?', ['Une adresse IP', 'Un nom qui possède un enregistrement A ou AAAA', 'Un CNAME', 'Un TXT'], 1, 'Jamais vers une IP ni un alias.'],
['La zone inverse de 192.168.5.0/24 s’appelle :', ['192.168.5.in-addr.arpa', '5.168.192.in-addr.arpa', '192.168.5.rev', 'arpa.5.168.192'], 1, 'Octets inversés.'],
['Un secondaire ne récupère pas la nouvelle version de la zone. Cause la plus probable ?', ['Le TTL est trop long', 'Le serial n’a pas été incrémenté', 'Le MX est faux', 'DNSSEC est actif'], 1, 'Le secondaire compare les serials.'],
['Dans un fichier de zone, « mail IN A 10.0.0.5 » dans la zone lycee.local crée :', ['mail.', 'mail.lycee.local.', 'mail.local.', 'une erreur'], 1, 'Le nom est complété par l’origine.'],
['Pourquoi abaisser le TTL avant une migration ?', ['Pour accélérer la résolution', 'Pour que les caches expirent vite quand l’adresse change', 'Pour DNSSEC', 'Pour réduire la charge'], 1, 'Sinon les anciens clients gardent l’ancienne adresse jusqu’à l’expiration.'],
['Quel est le risque d’un résolveur ouvert à tout Internet ?', ['Aucun', 'Utilisation pour des attaques par amplification', 'Perte des zones', 'Il devient faisant autorité'], 1, 'Réponses volumineuses vers une IP usurpée.'],
['Que garantit DNSSEC ?', ['La confidentialité des requêtes', 'L’authenticité et l’intégrité des réponses', 'La rapidité', 'La disponibilité'], 1, 'Signature, pas chiffrement.'],
['Quelle commande vérifie un fichier de zone avant rechargement ?', ['named-checkconf', 'named-checkzone lycee.local /etc/bind/db.lycee.local', 'rndc check', 'dig +check'], 1, 'named-checkconf vérifie la configuration générale.'],
['Un poste Debian a nameserver 127.0.0.53 dans resolv.conf. Comment voir le vrai serveur DNS ?', ['cat /etc/hosts', 'resolvectl status', 'ip route', 'dig 127.0.0.53'], 1, 'systemd-resolved fait office de relais local.']
],
td: [
{ n: 'Échauffement', c: 'Pour chaque besoin, donner le type d’enregistrement : (a) faire pointer intranet vers 10.62.40.20, (b) faire de www un alias de ent, (c) déclarer le serveur de messagerie, (d) prouver la propriété du domaine à un fournisseur, (e) retrouver le nom de 10.62.40.20.', r: '(a) A · (b) CNAME · (c) MX (+ A du serveur) · (d) TXT · (e) PTR dans la zone inverse' },
{ n: 'Échauffement', c: 'Repérer les trois erreurs de ce fragment de zone : « @ IN MX 10 203.0.113.25 » ; « mx1 IN CNAME serveur » ; « ent IN A 203.0.113.40 » suivi de « ent IN CNAME web ».', r: 'MX vers une IP (il faut un nom) · MX qui mènerait à un CNAME · ent porte à la fois un A et un CNAME' },
{ n: 'Application', c: 'Rédiger le fichier de zone complet de lycee.local : deux serveurs de noms (10.62.40.10 et .11), un serveur de messagerie en priorité 10, l’ENT en 10.62.40.20, un alias www vers l’ENT, et un enregistrement SPF qui n’autorise que le MX.', r: '$TTL 3600\n@ IN SOA ns1.lycee.local. hostmaster.lycee.local. ( 2026093001 7200 900 1209600 300 )\n IN NS ns1.lycee.local.\n IN NS ns2.lycee.local.\n IN MX 10 mx1.lycee.local.\n IN TXT "v=spf1 mx -all"\nns1 IN A 10.62.40.10\nns2 IN A 10.62.40.11\nmx1 IN A 10.62.40.25\nent IN A 10.62.40.20\nwww IN CNAME ent' },
{ n: 'Application', c: 'Configurer Bind9 pour qu’il fasse autorité sur lycee.local, qu’il ne serve la récursivité qu’au réseau 10.62.0.0/16, qu’il fasse suivre les requêtes externes vers 1.1.1.1, et que seul 10.62.40.11 puisse transférer la zone.', r: 'acl interne { 10.62.0.0/16; 127.0.0.1; };\noptions { recursion yes; allow-recursion { interne; }; forwarders { 1.1.1.1; }; };\nzone "lycee.local" { type primary; file "/etc/bind/db.lycee.local"; allow-transfer { 10.62.40.11; }; also-notify { 10.62.40.11; }; };' },
{ n: 'Application', c: 'L’ENT doit migrer de 203.0.113.40 vers 203.0.113.80 samedi à 8 h. Le TTL actuel est de 86 400 s. Établir le rétroplanning des opérations DNS.', r: 'Au plus tard vendredi 8 h : TTL de ent à 300, serial +1, rndc reload.\nSamedi 8 h : A de ent → 203.0.113.80, serial +1, reload ; vérifier avec dig @ns1 et @ns2.\nAprès validation (lundi) : TTL remonté à 3600 ou 86400.' },
{ n: 'Approfondissement', c: 'Expliquer pourquoi un nom créé à 10 h, mais demandé par erreur à 9 h 58, reste introuvable pour certains postes jusqu’à 10 h 03. Comment l’éviter ?', r: 'La réponse NXDOMAIN de 9 h 58 a été mise en cache pour la durée du TTL négatif du SOA (300 s). Éviter de tester avant publication, ou vider le cache du résolveur : rndc flushname nom.' },
{ n: 'Approfondissement', c: 'Montrer avec dig que la zone d’un domaine public est signée par DNSSEC et que votre résolveur valide les signatures.', r: 'dig +dnssec lycee-exemple.fr SOA → présence d’un enregistrement RRSIG\nflags de la réponse contenant ad (authenticated data) → le résolveur a validé la chaîne\ndig +cd … permet de comparer sans validation' }
],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Deux VM Bind9 (primaire et secondaire) et un client, vérifications par dig dans la VM.', etapes: ['Installer bind9 et bind9-dnsutils', 'Créer la zone directe lycee.local et la zone inverse', 'Valider avec named-checkconf et named-checkzone', 'Configurer le secondaire et vérifier le transfert', 'Restreindre la récursivité et tester depuis un réseau non autorisé', 'Provoquer puis corriger un oubli de serial'] },
plusLoin: [['RFC 1034 · DNS concepts', 'https://www.rfc-editor.org/rfc/rfc1034'], ['RFC 1035 · DNS implementation', 'https://www.rfc-editor.org/rfc/rfc1035'], ['Documentation Bind9 (ISC)', 'https://bind9.readthedocs.io/'], ['Afnic · DNSSEC et la zone .fr', 'https://www.afnic.fr/'], ['ANSSI · Bonnes pratiques pour l’acquisition et l’exploitation de noms de domaine', 'https://cyber.gouv.fr/publications/bonnes-pratiques-pour-lacquisition-et-lexploitation-de-noms-de-domaine']] },
plus: {
cas: { titre: 'Incident · « Plus personne ne se connecte à l’ENT »', texte: '' },
resolu: { enonce: 'Mardi 8 h 10 : depuis tous les postes du lycée, ent.lycee.local ne s’ouvre plus (« Impossible de trouver l’adresse du serveur »). Le serveur de l’ENT fonctionne. La veille au soir, un collègue a ajouté un enregistrement dans la zone. Diagnostiquer et rétablir.', etapes: [
['1 · Isoler la couche', 'ping -c 2 10.62.40.20\n2 packets transmitted, 2 received, 0% packet loss\ndig ent.lycee.local\n;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL\n→ Le serveur de l’ENT répond par son adresse : le réseau fonctionne. La résolution échoue avec SERVFAIL, et non NXDOMAIN : le résolveur n’a pas pu obtenir de réponse valide. Le problème est dans le DNS.'],
['2 · Interroger chaque serveur séparément', 'dig @10.62.40.10 ent.lycee.local +short\n(aucune réponse, SERVFAIL)\ndig @10.62.40.11 ent.lycee.local +short\n10.62.40.20\n→ Le secondaire répond correctement, le primaire non. Les postes qui interrogent d’abord le primaire échouent. On se concentre sur ns1.'],
['3 · Lire les journaux du primaire', 'sudo journalctl -u named --since "yesterday 18:00" | grep -i lycee\nzone lycee.local/IN: loading from master file /etc/bind/db.lycee.local failed: bad dotted quad\nzone lycee.local/IN: not loaded due to errors.\n→ Bind a refusé de charger la zone après le rechargement d’hier soir. Il ne fait donc plus autorité sur lycee.local et renvoie SERVFAIL.'],
['4 · Localiser l’erreur', 'sudo named-checkzone lycee.local /etc/bind/db.lycee.local\n/etc/bind/db.lycee.local:21: bad dotted quad\nzone lycee.local/IN: loading from master file failed: bad dotted quad\nsed -n 21p /etc/bind/db.lycee.local\nimprimante-cdi IN A 10.62.40.2O\n→ Ligne 21, l’adresse se termine par la lettre O au lieu du chiffre 0. Une faute de frappe a mis hors service la zone entière.'],
['5 · Corriger, incrémenter le serial, valider, recharger', 'sudo sed -i "21s/10.62.40.2O/10.62.40.200/" /etc/bind/db.lycee.local\n(serial 2026092901 → 2026093001)\nsudo named-checkzone lycee.local /etc/bind/db.lycee.local\nzone lycee.local/IN: loaded serial 2026093001\nOK\nsudo rndc reload lycee.local\nzone reload queued\n→ La zone se charge. Le nouveau serial déclenche un NOTIFY vers le secondaire, qui récupérera la version corrigée.'],
['6 · Vérifier et prévenir', 'dig @10.62.40.10 ent.lycee.local +short\n10.62.40.20\ndig @10.62.40.11 lycee.local SOA +short\nns1.lycee.local. hostmaster.lycee.local. 2026093001 7200 900 1209600 300\n→ Les deux serveurs répondent et le secondaire est au nouveau serial. Compte rendu : cause (faute de frappe non validée), impact (ENT inaccessible de 18 h 30 à 8 h 25 pour la moitié des postes), correction, et action préventive : named-checkzone obligatoire avant rndc reload, dans un script de publication.']
] },
erreurs: ['Oublier le point final d’un nom dans un fichier de zone', 'Modifier une zone sans incrémenter le serial', 'Mettre un CNAME à l’apex ou à côté d’un autre enregistrement', 'Faire pointer un MX vers une adresse IP ou un CNAME', 'Laisser la récursivité ouverte à Internet', 'Autoriser les transferts de zone à tous', 'Changer une adresse sans avoir abaissé le TTL à l’avance', 'Recharger Bind sans named-checkzone'],
memo: [['Commande', 'Usage en production'], ['dig nom', 'réponse complète : status, flags, TTL, serveur interrogé'], ['dig +short nom', 'la valeur seule, pour un script'], ['dig @serveur nom', 'interroger un serveur précis (primaire, secondaire, public)'], ['dig nom MX / NS / SOA / TXT', 'interroger un type précis'], ['dig -x 10.62.40.20', 'résolution inverse (PTR)'], ['dig +trace nom', 'suivre la délégation depuis la racine'], ['dig +dnssec nom', 'voir les signatures RRSIG et le drapeau ad'], ['resolvectl status', 'serveurs DNS réellement utilisés par le poste'], ['resolvectl flush-caches', 'vider le cache local systemd-resolved'], ['named-checkconf', 'valider la configuration Bind'], ['named-checkzone zone fichier', 'valider un fichier de zone'], ['rndc reload [zone]', 'recharger sans coupure'], ['rndc flushname nom', 'retirer un nom du cache du résolveur'], ['journalctl -u named', 'journaux de Bind']],
examen: { titre: 'Sujet type · 20 points', q: ['Décrire le parcours complet d’une résolution de ent.lycee-exemple.fr sans cache, en distinguant requêtes récursive et itératives. (4 pts)', 'Rédiger la zone directe et la zone inverse d’un petit réseau fourni. (6 pts)', 'Configurer un serveur Bind9 primaire et un secondaire, avec récursivité restreinte. (5 pts)', 'Analyser une sortie dig fournie : status, flags, TTL, section AUTHORITY. (3 pts)', 'Expliquer le rôle de DNSSEC et la différence avec DoH. (2 pts)'], r: ['Client → résolveur (RD) ; résolveur → racine → .fr → domaine (itératif) ; mise en cache', 'SOA, NS, A, MX, CNAME ; PTR dans x.y.z.in-addr.arpa', 'type primary / secondary, allow-transfer, also-notify, allow-recursion', 'Selon la sortie', 'DNSSEC : authenticité ; DoH : confidentialité'] },
prof: { deroule: [['Ouverture', 'Démonstration : couper le DNS d’un poste et constater que « plus rien ne marche » alors que le ping par IP fonctionne'], ['Cours', 'Hiérarchie, rôles, parcours d’une résolution avec dig +trace projeté'], ['Cours', 'Enregistrements et fichier de zone, lecture d’une zone réelle'], ['Pratique', 'Lab Bind9 primaire, secondaire, zone inverse'], ['Incident', 'Panne injectée (serial, point final, faute de frappe) à diagnostiquer'], ['Clôture', 'Quiz flash, puis rédaction du compte rendu d’incident']], diff: 'Élèves en difficulté : fichier de zone à compléter, fiche mémo dig. Élèves avancés : DNSSEC avec signature automatique dans Bind, vues (split horizon), comparaison avec Unbound et PowerDNS.', eval: 'Étapes du lab vérifiées par dig dans la VM, compte rendu d’incident, sujet type sur 20.' }
},
exemples: [
['Lire une réponse dig complète', 'Un utilisateur signale que le site met du temps à s’ouvrir.', 'dig ent.lycee-exemple.fr', ';; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41872\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n\n;; ANSWER SECTION:\nent.lycee-exemple.fr. 247 IN A 203.0.113.40\n\n;; Query time: 1 msec\n;; SERVER: 10.62.40.10#53(10.62.40.10) (UDP)', 'status NOERROR, une réponse, drapeaux rd ra (récursivité demandée et disponible) sans aa : c’est le résolveur interne qui répond depuis son cache, comme le confirment le TTL décroissant (247 s restantes) et le temps de 1 ms. La résolution n’est pas en cause ; on cherche ailleurs.'],
['Distinguer NXDOMAIN et SERVFAIL', 'Deux utilisateurs ne joignent pas deux sites différents.', 'dig +short nexistepas.lycee.local ; dig nexistepas.lycee.local | grep status\ndig panne.exemple | grep status', 'status: NXDOMAIN\nstatus: SERVFAIL', 'NXDOMAIN est une réponse valide : le serveur faisant autorité affirme que le nom n’existe pas (faute de frappe, enregistrement oublié). SERVFAIL signifie que le résolveur n’a pas réussi à obtenir de réponse fiable : serveurs faisant autorité injoignables, zone qui ne se charge pas, ou signature DNSSEC invalide. Les deux ne se diagnostiquent pas du tout de la même façon.'],
['Comparer primaire et secondaire', 'Le comportement change selon les postes après une modification.', 'for s in 10.62.40.10 10.62.40.11; do dig @$s lycee.local SOA +short; done', 'ns1.lycee.local. hostmaster.lycee.local. 2026093002 7200 900 1209600 300\nns1.lycee.local. hostmaster.lycee.local. 2026093001 7200 900 1209600 300', 'Les serials diffèrent : le secondaire n’a pas récupéré la dernière version. Vérifier sur le primaire allow-transfer et also-notify, puis dans les journaux du secondaire les messages « transfer of lycee.local … failed ». On force le transfert avec rndc retransfer lycee.local sur le secondaire.'],
['Vérifier la configuration de messagerie', 'Des courriels du lycée arrivent en spam chez les parents.', 'dig +short lycee-exemple.fr MX\ndig +short lycee-exemple.fr TXT\ndig +short -x 203.0.113.25', '10 mx1.lycee-exemple.fr.\n"v=spf1 mx -all"\n(aucune réponse)', 'Le MX et la politique SPF sont corrects, mais l’adresse du serveur d’envoi n’a pas d’enregistrement PTR. Beaucoup de fournisseurs pénalisent un expéditeur sans résolution inverse cohérente. On demande à l’hébergeur la création du PTR 203.0.113.25 → mx1.lycee-exemple.fr, et on ajoute DKIM et DMARC.'],
['Tester la récursivité depuis l’extérieur', 'Audit de sécurité du serveur DNS exposé.', 'dig @203.0.113.2 www.wikipedia.org', ';; ->>HEADER<<- opcode: QUERY, status: REFUSED\n;; flags: qr rd; QUERY: 1, ANSWER: 0\n;; WARNING: recursion requested but not available', 'Depuis Internet, le serveur refuse de résoudre un domaine qui n’est pas le sien (REFUSED, pas de drapeau ra) : il n’est pas un résolveur ouvert. Il doit en revanche répondre avec aa pour dig @203.0.113.2 lycee-exemple.fr.'],
['Trouver le vrai serveur DNS d’un poste', 'Un poste Debian résout différemment des autres.', 'cat /etc/resolv.conf | grep nameserver ; resolvectl status ens18 | grep -A2 "DNS Servers"', 'nameserver 127.0.0.53\nCurrent DNS Server: 192.168.1.1\n DNS Servers: 192.168.1.1', 'resolv.conf ne montre que le relais local systemd-resolved. resolvectl révèle que le poste utilise 192.168.1.1, une box et non le DNS du lycée : il a probablement été configuré à la main ou reçoit un bail d’un faux serveur DHCP. On corrige la configuration réseau du poste.']
],
long: { figure: svg(720, 250, bx(20, 100, 120, 50, Y, 'Poste', 15) + ln(140, 125, 200, 125) + bx(200, 95, 150, 60, L, 'Résolveur', 15) + [['Racine .', N, 20], ['.fr', G, 95], ['lycee-exemple.fr', P, 170]].map(function (r) { return ln(350, 125, 460, r[2] + 25) + bx(460, r[2], 240, 50, r[1], r[0], 14); }).join('') + tx(20, 200, '1 requête récursive', 13) + tx(360, 245, '3 requêtes itératives, réponses en cache', 13)), legende: 'Le poste pose une seule question ; le résolveur descend l’arbre et garde les réponses en cache.', photo: 'Photo : écran d’administration montrant une sortie dig ou une zone Bind',
lecture: ['Personne ne tape d’adresse IP pour aller sur l’ENT : on tape un nom. Entre le moment où l’on appuie sur Entrée et celui où la page commence à se charger, le navigateur a d’abord demandé à un résolveur quelle adresse correspondait à ce nom. Tant que cette réponse n’est pas arrivée, rien d’autre ne peut commencer. C’est pourquoi un DNS lent ralentit tout, et un DNS en panne donne l’impression que tout le réseau est coupé, alors que les câbles, les switchs et les serveurs fonctionnent parfaitement.', 'La force du DNS est sa décentralisation. Aucun organisme ne gère tous les noms : la racine délègue .fr à l’Afnic, qui délègue lycee-exemple.fr au lycée, qui gère ses propres noms. Chaque niveau n’a besoin de connaître que le suivant. Cette architecture a permis au système de passer de quelques milliers de noms dans les années 1980 à des centaines de millions aujourd’hui, avec le même protocole.', 'Sa faiblesse est symétrique : puisque chacun gère sa part, une erreur locale est immédiatement visible par tout le monde. Une faute de frappe dans un fichier de zone, un serial oublié, un TTL mal choisi avant une migration, et des milliers d’utilisateurs sont touchés. Un bon administrateur DNS est avant tout quelqu’un de méthodique : il valide chaque fichier, versionne ses zones, et teste chaque serveur séparément.', 'Enfin, le DNS est devenu un enjeu de sécurité majeur. Il sert à détourner des utilisateurs vers de faux sites, à exfiltrer des données par des requêtes camouflées, à amplifier des attaques par déni de service. DNSSEC, la restriction de la récursivité et la surveillance des requêtes font désormais partie du socle de sécurité recommandé par l’ANSSI pour tout système d’information.'] },
schemas: { termes: ['DNS', 'FQDN', 'TTL', 'SOA', 'serial', 'NS', 'MX', 'CNAME', 'PTR', 'TXT', 'SRV', 'AAAA', 'NXDOMAIN', 'SERVFAIL', 'NOERROR', 'REFUSED', 'dig', 'dig +trace', 'dig +short', 'resolvectl', 'named-checkzone', 'named-checkconf', 'rndc reload', 'Bind9', 'forwarders', 'allow-recursion', 'allow-transfer', 'AXFR', 'IXFR', 'NOTIFY', 'DNSSEC', 'RRSIG', 'DoH', 'DoT', 'in-addr.arpa', 'SPF', 'DKIM', 'DMARC', 'UDP 53'],
figs: [[4, 'Les cinq valeurs du SOA', svg(720, 110, [['serial', Y], ['refresh', G], ['retry', G], ['expire', L], ['TTL négatif', P]].map(function (v, i) { return bx(10 + i * 142, 30, 132, 50, v[1], v[0], 14); }).join('') + tx(10, 105, 'le secondaire ne transfère la zone que si le serial augmente', 13))]] }
});
// ================= NAT / PAT =================
reg({
cours: { id: 'nat', match: /NAT et PAT|masquerade/i,
titre: 'NAT et PAT : traduction d’adresses, masquerade et redirection de ports avec nftables', duree: '',
niveau: 'BTS SIO SISR · BTS CIEL IR · BUT R&T S2-S3 · TSSR',
prerequis: ['Adressage IPv4, adresses privées', 'TCP et UDP, ports', 'Routage statique (conseillé)'],
competences: ['BTS SIO SISR · Bloc 2 · Concevoir une solution d’infrastructure réseau', 'BTS SIO · Bloc 3 · Cybersécurité des services informatiques', 'BTS CIEL · C08 · Sécuriser un réseau', 'BUT R&T · Compétence « Connecter les entreprises »'],
intro: 'Les 1 500 appareils d’un lycée utilisent des adresses privées en 10.x.x.x, qui ne sont pas routées sur Internet. Pourtant, chacun consulte des sites, télécharge des mises à jour et joint des services en ligne. C’est la traduction d’adresses, le NAT, qui rend cela possible : à la sortie, le routeur ou le pare-feu remplace l’adresse privée par une adresse publique et garde la trace de chaque connexion pour renvoyer les réponses au bon poste. Dans l’autre sens, c’est encore le NAT qui publie un serveur interne sur Internet. Comprendre son fonctionnement dans le noyau, savoir le configurer avec nftables et le dépanner avec conntrack est indispensable à quiconque administre une passerelle.',
cm: [
{ t: 'Pourquoi traduire les adresses', d: '', html: 'L’espace IPv4 compte environ 4,3 milliards d’adresses, et les registres régionaux ont épuisé leurs réserves (le RIPE NCC, qui couvre l’Europe, a distribué ses derniers blocs /22 en 2019). Les adresses privées de la RFC 1918 ont permis de continuer à connecter des milliards d’appareils, à condition de <b>traduire</b> leurs adresses à la frontière avec Internet.<br><br>Le NAT (Network Address Translation, RFC 3022) modifie les champs d’adresse, et éventuellement de port, des en-têtes IP, TCP et UDP des paquets qui traversent un équipement, puis recalcule les sommes de contrôle. Il ne s’agit pas d’un mécanisme de sécurité en soi, mais il a un effet de bord apprécié : sans règle explicite, aucune connexion initiée depuis Internet ne peut atteindre un poste interne, puisque le routeur ne saurait pas à qui la transmettre.' },
{ t: 'Les formes de NAT', d: '', html: 'On distingue les traductions selon le champ modifié et le sens. Le <b>SNAT</b> (source NAT) modifie l’adresse source des paquets sortants : c’est lui qui permet aux postes de naviguer. Le <b>DNAT</b> (destination NAT) modifie l’adresse de destination des paquets entrants : c’est lui qui publie un serveur interne (redirection de port, port forwarding).<br><br>Le NAT <b>statique</b> associe une adresse privée à une adresse publique, un pour un, dans les deux sens. Le <b>PAT</b> (Port Address Translation), appelé aussi NAT surchargé ou NAPT, fait partager une seule adresse publique à des milliers de postes en traduisant aussi le port source : chaque connexion sortante reçoit un port source unique sur l’adresse publique, ce qui permet de distinguer les réponses. C’est ce que fait toute box domestique et la passerelle de presque tous les établissements.<br><br>Le <b>masquerade</b> est un SNAT dont l’adresse de remplacement est prise automatiquement sur l’interface de sortie. On l’utilise quand cette adresse est attribuée dynamiquement par l’opérateur.', table: [['Forme', 'Champ modifié', 'Sens', 'Usage'], ['SNAT', 'adresse source', 'sortant', 'accès Internet des postes'], ['Masquerade', 'adresse source (auto)', 'sortant', 'IP publique dynamique'], ['PAT / NAPT', 'adresse et port source', 'sortant', 'des milliers de postes derrière une IP'], ['DNAT', 'adresse (et port) destination', 'entrant', 'publier un serveur interne'], ['NAT statique 1:1', 'adresse, dans les deux sens', 'les deux', 'serveur avec IP publique dédiée']] },
{ t: 'Le suivi de connexions : conntrack', d: '', html: 'Sous Linux, le NAT repose sur le <b>suivi de connexions</b> du noyau (netfilter conntrack). Au premier paquet d’une connexion, le noyau crée une entrée qui mémorise le quintuplet d’origine (protocole, adresse et port source, adresse et port destination) et le quintuplet traduit. Les règles de NAT ne sont évaluées que pour ce <b>premier paquet</b> ; tous les paquets suivants, dans les deux sens, sont traduits directement grâce à l’entrée conntrack.<br><br>Chaque entrée a un état (NEW, ESTABLISHED, RELATED) et une durée de vie qui dépend du protocole : environ cinq jours pour une connexion TCP établie, 30 secondes pour un flux UDP sans réponse. La table a une taille maximale (<code>net.netfilter.nf_conntrack_max</code>) ; lorsqu’elle est pleine, le noyau écrit « nf_conntrack: table full, dropping packet » dans les journaux et rejette les nouvelles connexions. C’est un incident classique sur les passerelles d’établissement lors d’une journée d’examens en ligne.', exemple: '$ sudo conntrack -L -p tcp --dport 443 | head -2\ntcp 6 431987 ESTABLISHED src=10.62.20.57 dst=142.250.75.227 sport=51544 dport=443 src=142.250.75.227 dst=203.0.113.10 sport=443 dport=51544 [ASSURED] mark=0 use=1\n\n$ sudo conntrack -C\n18342\n$ sysctl net.netfilter.nf_conntrack_max\nnet.netfilter.nf_conntrack_max = 262144' },
{ t: 'Où agit le NAT : les crochets netfilter', d: '', html: 'Netfilter définit des points d’accroche (hooks) dans le parcours d’un paquet. Le <b>DNAT</b> intervient au crochet <b>prerouting</b>, avant la décision de routage : il faut changer la destination avant que le noyau ne choisisse où envoyer le paquet. Le <b>SNAT</b> intervient au crochet <b>postrouting</b>, juste avant la sortie, une fois l’interface de sortie connue. Entre les deux, le paquet traverse le crochet <b>forward</b>, où le pare-feu doit l’autoriser.<br><br>Cet ordre a une conséquence pratique qui piège souvent : dans la chaîne forward, on voit un paquet redirigé par DNAT avec sa <b>nouvelle</b> adresse de destination (le serveur interne), mais un paquet sortant avec son adresse source <b>d’origine</b> (le poste interne), puisque le SNAT n’a pas encore eu lieu. Les règles de filtrage s’écrivent donc avec les adresses privées.', exemple: 'entrée ─► prerouting (DNAT) ─► routage ─► forward (filtrage) ─► postrouting (SNAT) ─► sortie\n └─► input (vers la machine elle-même)' },
{ t: 'Configurer une passerelle avec nftables', d: '', html: '<b>nftables</b> est le cadre de filtrage par défaut de Debian depuis la version 10 ; il remplace iptables, dont les commandes sont encore présentes sous forme de couche de compatibilité. Une table de type <b>ip nat</b> contient les chaînes prerouting et postrouting. Il faut aussi activer le routage IP, sans quoi le noyau ne transmettra aucun paquet entre les interfaces.<br><br>La configuration permanente se place dans <code>/etc/nftables.conf</code>, chargée au démarrage par le service nftables. On la valide avec <code>nft -c -f</code> avant de l’appliquer : une erreur de syntaxe laisse sinon la passerelle sans règle.', exemple: '# Activer le routage de façon permanente\necho "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-routage.conf\nsudo sysctl --system\n\n# /etc/nftables.conf (extrait)\ntable ip nat {\n chain prerouting {\n type nat hook prerouting priority dstnat;\n iifname "wan0" tcp dport 443 dnat to 10.62.40.20:443\n }\n chain postrouting {\n type nat hook postrouting priority srcnat;\n oifname "wan0" ip saddr 10.62.0.0/16 masquerade\n }\n}\ntable inet filtre {\n chain forward {\n type filter hook forward priority filter; policy drop;\n ct state established,related accept\n iifname "lan0" oifname "wan0" accept\n iifname "wan0" ip daddr 10.62.40.20 tcp dport 443 ct state new accept\n }\n}\n\nsudo nft -c -f /etc/nftables.conf && sudo systemctl reload nftables' },
{ t: 'Publier un serveur : DNAT et hairpin', d: '', html: 'Pour rendre l’ENT interne accessible depuis Internet, on crée un DNAT de l’adresse publique, port 443, vers l’adresse privée du serveur, et une règle de forward qui autorise ce flux. Le serveur interne doit avoir la passerelle comme route par défaut, sinon ses réponses partiraient ailleurs et ne seraient pas re-traduites.<br><br>Un cas particulier surprend souvent : un poste <b>interne</b> qui tente de joindre le serveur par son adresse <b>publique</b>. Le DNAT s’applique, le paquet est envoyé au serveur, mais celui-ci répond directement au poste, qui est sur le même réseau, sans repasser par la passerelle. Le poste reçoit une réponse venant d’une adresse qu’il n’a pas contactée et l’ignore. C’est le problème du <b>hairpin NAT</b> (NAT loopback). Deux solutions : ajouter un SNAT pour ce flux afin de forcer le retour par la passerelle, ou, mieux, utiliser un <b>DNS interne</b> (split horizon) qui renvoie l’adresse privée aux clients internes.' },
{ t: 'Limites et effets de bord du NAT', d: '', html: 'Le NAT casse le principe de bout en bout d’IP. Les protocoles qui transportent des adresses IP dans leurs données (FTP en mode actif, SIP pour la téléphonie, certains jeux) ne fonctionnent qu’avec des modules d’aide (conntrack helpers) ou des mécanismes de traversée (STUN, TURN). IPsec en mode transport s’accommode mal de la modification des en-têtes, d’où l’encapsulation NAT-T en UDP 4500.<br><br>Côté opérateurs, le manque d’adresses a conduit au <b>CGNAT</b> (Carrier-Grade NAT, plage 100.64.0.0/10) : l’abonné lui-même reçoit une adresse privée, traduite une seconde fois chez l’opérateur. Il devient impossible d’héberger un service chez soi, et la traçabilité impose aux opérateurs de journaliser les ports attribués. La vraie solution est <b>IPv6</b>, où chaque appareil dispose d’adresses globales et où la sécurité repose sur le pare-feu, pas sur la traduction.<br><br>Enfin, le NAT a des obligations légales : en France, l’organisme qui fournit un accès à Internet doit pouvoir identifier l’utilisateur à l’origine d’une connexion. Sur une passerelle NAT, cela suppose de conserver les journaux de connexions (adresse interne, port source traduit, horodatage) pendant la durée prévue par la réglementation.', attention: 'Le NAT n’est pas un pare-feu. Une règle DNAT publiée sans filtrage associé, ou un pare-feu en policy accept, expose le serveur interne à tout Internet. Chaque redirection doit s’accompagner d’une règle forward explicite et d’un serveur à jour.' }
],
synthese: ['SNAT/masquerade en postrouting pour sortir, DNAT en prerouting pour publier', 'PAT : des milliers de postes derrière une IP grâce à la traduction du port source', 'Le NAT repose sur conntrack : les règles ne s’appliquent qu’au premier paquet', 'Activer net.ipv4.ip_forward et filtrer dans forward avec les adresses privées', 'Hairpin NAT : préférer un DNS interne', 'Le NAT n’est pas un pare-feu ; IPv6 rend la traduction inutile'],
qcm: [
['À quel crochet netfilter s’applique le DNAT ?', ['postrouting', 'prerouting', 'forward', 'output uniquement'], 1, 'Avant la décision de routage.'],
['Quelle forme de NAT utilise une passerelle dont l’IP publique change à chaque reconnexion ?', ['DNAT', 'NAT statique', 'Masquerade', 'Hairpin'], 2, 'L’adresse est lue sur l’interface de sortie.'],
['Comment le PAT distingue-t-il les réponses destinées à deux postes qui joignent le même site ?', ['Par l’adresse MAC', 'Par le port source traduit', 'Par le TTL', 'Il ne peut pas'], 1, 'Chaque connexion reçoit un port unique sur l’IP publique.'],
['Sans net.ipv4.ip_forward=1, que se passe-t-il ?', ['Rien', 'Le noyau ne transmet pas les paquets entre les interfaces', 'Le NAT devient statique', 'Le DNS s’arrête'], 1, 'La machine n’agit pas comme routeur.'],
['Dans la chaîne forward, un paquet sortant d’un poste interne a pour adresse source :', ['l’IP publique', 'l’IP privée du poste', '0.0.0.0', 'l’IP de la passerelle'], 1, 'Le SNAT intervient après, en postrouting.'],
['Que signifie « nf_conntrack: table full, dropping packet » ?', ['Le disque est plein', 'La table de suivi de connexions est saturée', 'Le pare-feu est désactivé', 'Le DNS est lent'], 1, 'Augmenter nf_conntrack_max et chercher la cause.'],
['Un poste interne ne joint pas le serveur publié par l’adresse publique, alors que l’extérieur y parvient. Problème ?', ['DNS externe', 'Hairpin NAT', 'MTU', 'Serial DNS'], 1, 'La réponse revient sans être re-traduite.'],
['Quelle plage est utilisée par le CGNAT des opérateurs ?', ['10.0.0.0/8', '100.64.0.0/10', '169.254.0.0/16', '192.0.2.0/24'], 1, 'RFC 6598.'],
['Quelle commande liste les connexions suivies ?', ['nft list ruleset', 'conntrack -L', 'ss -nat', 'ip route'], 1, 'Paquet conntrack.'],
['Pourquoi le NAT n’est-il pas une mesure de sécurité suffisante ?', ['Il chiffre mal', 'Il ne filtre rien : une redirection sans règle forward expose le serveur', 'Il est lent', 'Il est interdit'], 1, 'Le filtrage relève du pare-feu.']
],
td: [
{ n: 'Échauffement', c: 'Pour chaque besoin, indiquer SNAT, masquerade, DNAT ou NAT statique : (a) les postes naviguent derrière une IP fixe, (b) la box obtient son IP par DHCP de l’opérateur, (c) publier le serveur web interne sur le port 443, (d) donner une IP publique dédiée à un serveur de visioconférence.', r: '(a) SNAT · (b) masquerade · (c) DNAT · (d) NAT statique 1:1' },
{ n: 'Échauffement', c: 'Remplir la table de traduction PAT : deux postes 10.62.20.5:50001 et 10.62.20.9:50001 joignent 93.184.216.34:443 via l’IP publique 203.0.113.10.', r: '10.62.20.5:50001 ↔ 203.0.113.10:50001 (ou autre port libre)\n10.62.20.9:50001 ↔ 203.0.113.10:61234 (port réécrit pour éviter la collision)' },
{ n: 'Application', c: 'Écrire la configuration nftables complète d’une passerelle : LAN 10.62.0.0/16 sur lan0, WAN sur wan0 en IP dynamique, sortie Internet pour tout le LAN, filtrage forward en politique drop.', r: 'table ip nat { chain postrouting { type nat hook postrouting priority srcnat; oifname "wan0" ip saddr 10.62.0.0/16 masquerade } }\ntable inet filtre { chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept; iifname "lan0" oifname "wan0" accept } }\n+ net.ipv4.ip_forward=1' },
{ n: 'Application', c: 'Publier le serveur SSH interne 10.62.40.30 sur le port externe 2222, en limitant l’accès à l’adresse du rectorat 198.51.100.50.', r: 'prerouting : iifname "wan0" ip saddr 198.51.100.50 tcp dport 2222 dnat to 10.62.40.30:22\nforward : iifname "wan0" ip saddr 198.51.100.50 ip daddr 10.62.40.30 tcp dport 22 ct state new accept' },
{ n: 'Application', c: 'Le serveur publié répond aux tests depuis la passerelle mais pas depuis Internet. conntrack montre des entrées [UNREPLIED]. Proposer deux causes et leurs vérifications.', r: 'Route par défaut du serveur qui ne passe pas par la passerelle (ip route sur le serveur).\nRègle forward manquante ou pare-feu local du serveur (nft list ruleset, tcpdump sur l’interface LAN de la passerelle).' },
{ n: 'Approfondissement', c: 'Expliquer le problème du hairpin NAT et comparer les deux solutions (SNAT de retour et DNS split horizon).', r: 'Le serveur répond directement au poste interne, qui rejette la réponse. SNAT de retour : fonctionne mais le serveur voit toutes les connexions internes venir de la passerelle (journaux moins utiles). Split horizon : le DNS interne renvoie l’IP privée, le trafic ne passe plus par la passerelle ; solution recommandée.' },
{ n: 'Approfondissement', c: 'Une passerelle d’établissement de 3 000 utilisateurs rejette des connexions le jour du bac blanc en ligne. Chiffrer la taille nécessaire de la table conntrack et proposer les réglages.', r: 'Environ 100 à 200 connexions simultanées par appareil actif en navigation moderne : 3 000 × 150 ≈ 450 000 entrées. nf_conntrack_max à 524288 (mémoire ≈ 300 octets par entrée ≈ 150 Mo), réduire nf_conntrack_tcp_timeout_established de 5 jours à quelques heures, superviser conntrack -C.' }
],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Une passerelle Debian à deux interfaces, un client LAN et un serveur web interne.', etapes: ['Activer le routage IP', 'Écrire la table nat avec masquerade', 'Filtrer forward en politique drop', 'Publier le serveur web par DNAT', 'Observer les traductions avec conntrack -E', 'Résoudre le hairpin NAT par un DNS interne'] },
plusLoin: [['RFC 3022 · Traditional NAT', 'https://www.rfc-editor.org/rfc/rfc3022'], ['RFC 6598 · plage 100.64.0.0/10', 'https://www.rfc-editor.org/rfc/rfc6598'], ['Wiki nftables · Performing NAT', 'https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT)'], ['Debian Wiki · nftables', 'https://wiki.debian.org/nftables']] },
plus: {
cas: { titre: '', texte: '' },
resolu: { enonce: 'Lundi 9 h : le serveur de visioconférence interne (10.62.40.50), publié la semaine dernière sur l’adresse publique 203.0.113.10 port 443, fonctionne pour les élèves à la maison mais pas pour les professeurs dans le lycée, qui utilisent le même lien https://visio.lycee-exemple.fr. Diagnostiquer et corriger.', etapes: [
['1 · Reproduire depuis l’intérieur et l’extérieur', 'Depuis un poste interne :\ncurl -sI --max-time 5 https://visio.lycee-exemple.fr\ncurl: (28) Connection timed out after 5001 milliseconds\nDepuis un smartphone en 4G : la page s’ouvre.\n→ Le service fonctionne depuis Internet. Seul le trafic interne vers l’adresse publique échoue : ce n’est ni le serveur ni la redirection de base.'],
['2 · Vérifier la résolution', 'dig +short visio.lycee-exemple.fr\n203.0.113.10\n→ Le poste interne reçoit l’adresse publique : il envoie donc ses paquets à la passerelle, qui applique le DNAT vers 10.62.40.50.'],
['3 · Observer la passerelle', 'sudo conntrack -L -d 203.0.113.10 | grep 10.62.20\ntcp 6 118 SYN_SENT src=10.62.20.57 dst=203.0.113.10 sport=52011 dport=443 [UNREPLIED] src=10.62.40.50 dst=10.62.20.57 sport=443 dport=52011\n→ La traduction est bien faite (réponse attendue de 10.62.40.50), mais la connexion reste en SYN_SENT et [UNREPLIED] : la passerelle ne voit jamais la réponse.'],
['4 · Observer le serveur', 'Sur 10.62.40.50 :\nsudo tcpdump -ni ens18 -c 2 host 10.62.20.57 and port 443\nIP 10.62.20.57.52011 > 10.62.40.50.443: Flags [S]\nIP 10.62.40.50.443 > 10.62.20.57.52011: Flags [S.]\n→ Le serveur reçoit le SYN venant du poste (source non traduite) et lui répond directement, sans passer par la passerelle. Le poste reçoit un SYN-ACK de 10.62.40.50 alors qu’il attendait 203.0.113.10 : il l’ignore. C’est un problème de hairpin NAT.'],
['5 · Corriger par un DNS interne (split horizon)', 'Sur le résolveur interne Bind9, ajout d’une vue ou d’une zone locale :\nzone "visio.lycee-exemple.fr" { type primary; file "/etc/bind/db.visio-interne"; };\n; db.visio-interne : @ IN A 10.62.40.50\nsudo named-checkzone visio.lycee-exemple.fr /etc/bind/db.visio-interne && sudo rndc reload\ndig +short visio.lycee-exemple.fr (depuis un poste interne)\n10.62.40.50\n→ Les clients internes reçoivent l’adresse privée et joignent le serveur directement ; l’extérieur continue de recevoir l’adresse publique.'],
['6 · Vérifier et documenter', 'curl -sI https://visio.lycee-exemple.fr | head -1\nHTTP/2 200\n→ Service rétabli pour l’interne. Compte rendu : symptôme (timeout interne uniquement), preuve (conntrack UNREPLIED + tcpdump sur le serveur), cause (hairpin NAT), correction (split horizon), à noter : le certificat HTTPS reste valide car le nom est identique. Alternative écartée : SNAT de retour, qui masquerait les adresses des postes dans les journaux du serveur.']
] },
erreurs: ['Oublier d’activer net.ipv4.ip_forward', 'Écrire le filtrage forward avec l’adresse publique au lieu de l’adresse privée', 'Publier un DNAT sans règle forward correspondante, ou avec une politique accept', 'Oublier que le serveur publié doit avoir la passerelle comme route par défaut', 'Tester la publication depuis l’intérieur et conclure à une panne (hairpin)', 'Laisser la table conntrack à sa taille par défaut sur une grosse passerelle', 'Appliquer /etc/nftables.conf sans nft -c et se retrouver sans règles', 'Considérer le NAT comme une protection suffisante'],
memo: [['Commande', 'Usage en production'], ['sysctl net.ipv4.ip_forward', 'vérifier que la machine route'], ['nft list ruleset', 'voir toutes les règles, NAT et filtrage'], ['nft list table ip nat', 'voir uniquement les traductions'], ['nft -c -f /etc/nftables.conf', 'valider la configuration sans l’appliquer'], ['systemctl reload nftables', 'appliquer la configuration permanente'], ['conntrack -L', 'lister les connexions suivies et leurs traductions'], ['conntrack -E', 'suivre en direct la création des traductions'], ['conntrack -C', 'nombre d’entrées dans la table'], ['sysctl net.netfilter.nf_conntrack_max', 'taille maximale de la table'], ['conntrack -D -s <ip>', 'supprimer les entrées d’un poste après un changement de règle'], ['tcpdump -ni wan0 port 443', 'voir les paquets après traduction côté WAN'], ['curl ifconfig.me', 'connaître l’IP publique de sortie']],
examen: { titre: 'Sujet type · 20 points', q: ['Expliquer le fonctionnement du PAT à l’aide d’une table de traduction pour trois connexions. (4 pts)', 'Situer SNAT, DNAT et le filtrage dans le parcours netfilter et en déduire les adresses visibles en forward. (4 pts)', 'Écrire la configuration nftables d’une passerelle avec sortie Internet et publication d’un serveur web. (7 pts)', 'Diagnostiquer un cas de hairpin NAT à partir de sorties conntrack et tcpdump fournies. (3 pts)', 'Expliquer pourquoi IPv6 rend le NAT inutile et ce qui assure alors la sécurité. (2 pts)'], r: ['Quintuplets d’origine et traduits, ports réécrits', 'prerouting DNAT → forward (adresses privées) → postrouting SNAT', 'table ip nat (prerouting dnat, postrouting masquerade) + table inet filtre forward policy drop', 'UNREPLIED côté passerelle, réponse directe côté serveur', 'Adresses globales pour tous ; pare-feu à état'] },
prof: { deroule: [['Ouverture', 'curl ifconfig.me sur tous les postes : tout le monde a la même adresse, pourquoi ?'], ['Cours', 'Pénurie IPv4, formes de NAT, PAT et table de traduction'], ['Cours', 'Netfilter, conntrack, ordre des crochets'], ['Pratique', 'Lab passerelle : masquerade, filtrage, DNAT'], ['Incident', 'Hairpin NAT injecté à diagnostiquer'], ['Clôture', 'Quiz flash et discussion IPv6']], diff: 'Élèves en difficulté : configuration nftables à compléter, schéma du parcours netfilter imprimé. Élèves avancés : NAT et IPv6 (NPTv6), dimensionnement conntrack, journalisation légale des traductions.', eval: 'Étapes du lab validées, analyse de l’incident, sujet type.' }
},
exemples: [
['Vérifier que la passerelle route', 'Aucun poste n’accède à Internet après le redémarrage de la passerelle.', 'sysctl net.ipv4.ip_forward', 'net.ipv4.ip_forward = 0', 'Le routage a été activé à la main avec sysctl -w mais jamais rendu permanent : il a disparu au redémarrage. Correction : fichier /etc/sysctl.d/99-routage.conf contenant net.ipv4.ip_forward=1, puis sysctl --system.'],
['Lire les traductions en cours', 'Qui, dans le lycée, se connecte à ce serveur externe signalé par le CERT ?', 'sudo conntrack -L -d 185.220.101.4', 'tcp 6 431998 ESTABLISHED src=10.62.20.114 dst=185.220.101.4 sport=49822 dport=9001 src=185.220.101.4 dst=203.0.113.10 sport=9001 dport=49822 [ASSURED]', 'La première moitié de la ligne est le flux d’origine, la seconde le flux traduit vu depuis Internet. Le poste interne 10.62.20.114 est à l’origine de la connexion. Sans la table conntrack ou ses journaux, l’adresse publique 203.0.113.10 seule ne permettrait pas d’identifier le poste.'],
['Suivre les traductions en direct', 'Vérifier qu’une nouvelle redirection de port est bien utilisée.', 'sudo conntrack -E -p tcp --dport 443 -d 203.0.113.10', '[NEW] tcp 6 120 SYN_SENT src=198.51.100.7 dst=203.0.113.10 sport=60412 dport=443 [UNREPLIED] src=10.62.40.20 dst=198.51.100.7 sport=443 dport=60412\n[UPDATE] tcp 6 60 SYN_RECV …\n[UPDATE] tcp 6 432000 ESTABLISHED … [ASSURED]', 'Le DNAT est appliqué dès le premier paquet (réponse attendue de 10.62.40.20). La connexion passe de SYN_SENT à ESTABLISHED : le serveur répond et le filtrage laisse passer. Une connexion bloquée en [UNREPLIED] aurait orienté vers le filtrage ou la route du serveur.'],
['Détecter une table conntrack saturée', 'Le jour d’un examen en ligne, des connexions échouent au hasard.', 'sudo dmesg | grep conntrack | tail -1 ; sudo conntrack -C ; sysctl -n net.netfilter.nf_conntrack_max', 'nf_conntrack: nf_conntrack: table full, dropping packet\n65536\n65536', 'La table est pleine : chaque nouvelle connexion est rejetée. On augmente immédiatement la limite (sysctl -w net.netfilter.nf_conntrack_max=524288), puis on la rend permanente et on réduit la durée de vie des connexions établies inactives.'],
['Afficher les règles de NAT', 'Audit de la passerelle avant la rentrée.', 'sudo nft list table ip nat', 'table ip nat {\n chain prerouting {\n type nat hook prerouting priority dstnat; policy accept;\n iifname "wan0" tcp dport 3389 dnat to 10.62.10.15:3389\n iifname "wan0" tcp dport 443 dnat to 10.62.40.20:443\n }\n chain postrouting {\n type nat hook postrouting priority srcnat; policy accept;\n oifname "wan0" ip saddr 10.62.0.0/16 masquerade\n }\n}', 'Une redirection du bureau à distance (RDP, port 3389) vers un poste de l’administration a été oubliée depuis un dépannage. C’est une exposition directe à Internet d’un service très attaqué. On la supprime et on passe par un VPN pour les accès à distance.'],
['Connaître son adresse de sortie', 'Le prestataire demande l’IP à autoriser sur son service.', 'curl -s https://ifconfig.me ; echo ; ip -br addr show wan0', '203.0.113.10\nwan0 UP 203.0.113.10/29', 'Les deux valeurs concordent : les postes sortent bien par l’adresse de l’interface WAN. Si curl avait renvoyé une adresse en 100.64.x.x ou différente de celle de wan0, on serait derrière un CGNAT ou un autre équipement de traduction.']
],
long: { figure: svg(720, 220, bx(20, 30, 180, 44, Y, '10.62.20.5:50001', 14) + bx(20, 90, 180, 44, Y, '10.62.20.9:50001', 14) + ln(200, 52, 280, 90) + ln(200, 112, 280, 112) + bx(280, 70, 160, 80, L, 'Passerelle PAT', 15) + ln(440, 110, 510, 110) + bx(510, 30, 190, 44, G, '203.0.113.10:50001', 13) + bx(510, 90, 190, 44, G, '203.0.113.10:61234', 13) + tx(20, 190, 'Une seule adresse publique, un port source unique par connexion', 14)), legende: 'Le PAT fait partager une adresse publique en réécrivant le port source.', photo: 'Photo : pare-feu ou routeur de bordure dans une baie',
lecture: ['Le NAT est l’un de ces mécanismes que tout le monde utilise sans le voir. Chaque smartphone, chaque ordinateur d’élève, chaque imprimante d’un établissement a une adresse privée ; tous sortent sur Internet par la même adresse publique. Pour les sites consultés, un lycée de 1 500 personnes n’est qu’une seule machine qui ouvre beaucoup de connexions.', 'Techniquement, c’est un tour de passe-passe réalisé par le noyau du système de la passerelle. Il réécrit l’adresse, souvent le port, recalcule les sommes de contrôle, et note tout dans une table pour faire l’opération inverse au retour. Cette table est la clé du fonctionnement, et donc du dépannage : quand un flux ne passe pas, c’est en lisant les entrées conntrack que l’on voit si la traduction a eu lieu et si la réponse est revenue.', 'Il faut garder en tête que le NAT a été inventé comme un pis-aller, en attendant IPv6. Il complique les applications, empêche d’héberger simplement des services, et oblige à conserver des journaux pour pouvoir identifier un utilisateur. Sa réputation de protection vient uniquement du fait qu’il bloque par défaut les connexions entrantes ; c’est le pare-feu qui doit assurer ce rôle de façon explicite.', 'Enfin, chaque redirection de port est une porte ouverte vers l’intérieur du réseau. Les audits de sécurité trouvent régulièrement des redirections oubliées vers des bureaux à distance, des caméras ou des interfaces d’administration. Une bonne pratique consiste à documenter chaque règle DNAT avec son demandeur et sa date, et à les revoir à chaque rentrée.'] },
schemas: { termes: ['NAT', 'PAT', 'SNAT', 'DNAT', 'NAPT', 'masquerade', 'conntrack', 'netfilter', 'nftables', 'nft', 'prerouting', 'postrouting', 'forward', 'ip_forward', 'nf_conntrack_max', 'ESTABLISHED', 'UNREPLIED', 'SYN_SENT', 'hairpin NAT', 'split horizon', 'CGNAT', '100.64.0.0/10', 'RFC 1918', 'IPv6', 'port forwarding'],
figs: [[3, 'Le parcours d’un paquet dans netfilter', svg(720, 110, [['prerouting · DNAT', Y], ['routage', N], ['forward · filtrage', L], ['postrouting · SNAT', G]].map(function (c, i) { return bx(10 + i * 178, 30, 168, 50, c[1], c[0], 13) + (i < 3 ? ln(178 + i * 178, 55, 188 + i * 178, 55) : ''); }).join(''))]] }
});
// ================= Routage statique =================
reg({
cours: { id: 'routage', match: /Routage statique|table de routage|route par défaut|Deux LAN et un routeur/i,
titre: 'Routage statique : table de routage, route par défaut et interconnexion de réseaux', duree: '',
niveau: 'BTS SIO SISR · BTS CIEL IR · BUT R&T S2 · TSSR',
prerequis: ['Adressage IPv4 et sous-réseaux', 'Diagnostic réseau en ligne de commande'],
competences: ['BTS SIO SISR · Bloc 2 · Concevoir et mettre en œuvre une solution d’infrastructure réseau', 'BTS CIEL · C03 · Configurer un réseau', 'BUT R&T · Compétence « Connecter » · niveau 1'],
intro: 'Dès qu’un établissement compte plus d’un réseau, il faut des routeurs, et chaque routeur doit savoir où envoyer les paquets. Le routage statique consiste à écrire soi-même ces chemins. C’est la forme de routage la plus simple, la plus prévisible, et celle qu’on trouve partout : route par défaut de chaque poste, liaison entre deux sites, accès à un réseau de laboratoire derrière un routeur Linux. C’est aussi la base indispensable pour comprendre les protocoles dynamiques comme OSPF : un routeur, dynamique ou non, ne fait qu’une chose, chercher dans sa table la route la plus précise vers la destination.',
cm: [
{ t: 'Ce que fait un routeur', d: '', html: 'Un routeur reçoit un paquet sur une interface, lit l’<b>adresse IP de destination</b>, cherche dans sa <b>table de routage</b> la meilleure route vers cette destination, décrémente le TTL, puis réémet le paquet dans une nouvelle trame vers le <b>prochain saut</b> (next hop). Il ne connaît jamais le chemin complet : il sait seulement à quel voisin confier le paquet. Chaque routeur prend sa décision indépendamment, saut par saut.<br><br>Toute machine IP, y compris un simple poste, possède une table de routage et fait ce raisonnement pour chaque paquet qu’elle émet. La différence est qu’un poste ne transmet pas les paquets qui ne lui sont pas destinés, alors qu’un routeur le fait : sous Linux, c’est le paramètre <code>net.ipv4.ip_forward</code> qui fait basculer une machine d’un rôle à l’autre.' },
{ t: 'La table de routage', d: '', html: 'Chaque entrée associe un <b>préfixe de destination</b> à une <b>interface de sortie</b> et, si la destination n’est pas directement connectée, à une <b>passerelle</b> (next hop). On y trouve trois sortes de routes. Les routes <b>connectées</b> sont créées automatiquement quand une adresse est configurée sur une interface : le réseau de l’interface est joignable directement. Les routes <b>statiques</b> sont ajoutées par l’administrateur. Les routes <b>dynamiques</b> sont apprises par un protocole de routage.<br><br>Sous Linux, <code>ip route</code> affiche la table principale. Le champ <code>proto kernel</code> désigne une route connectée, <code>proto static</code> une route ajoutée à la main ou par la configuration, <code>scope link</code> une destination joignable sans passerelle.', exemple: '$ ip route\ndefault via 10.62.0.1 dev ens18 proto static\n10.62.0.0/24 dev ens18 proto kernel scope link src 10.62.0.254\n10.62.40.0/24 dev ens19 proto kernel scope link src 10.62.40.1\n172.20.0.0/16 via 10.62.40.2 dev ens19 proto static' },
{ t: 'La règle de la correspondance la plus longue', d: '', html: 'Une destination peut correspondre à plusieurs routes : une route par défaut 0.0.0.0/0 correspond à tout, une route 10.62.0.0/16 à tout le réseau de l’établissement, une route 10.62.40.0/24 au seul réseau des serveurs. Le routeur choisit toujours la route dont le préfixe est le <b>plus long</b> (longest prefix match), c’est-à-dire la plus précise.<br><br>À longueur égale, il départage par la <b>distance administrative</b> (la confiance accordée à la source de la route : 0 pour une route connectée, 1 pour une statique chez Cisco, 110 pour OSPF) puis par la <b>métrique</b>. Sous Linux, c’est la métrique qui départage directement : la plus faible l’emporte.<br><br>Cette règle permet des configurations élégantes : une route par défaut vers Internet, et quelques routes plus précises vers les réseaux internes, sans conflit.', exemple: 'Destination 10.62.40.25\n 0.0.0.0/0 via 10.62.0.1 correspond (0 bit)\n 10.62.0.0/16 via 10.62.0.2 correspond (16 bits)\n 10.62.40.0/24 dev ens19 correspond (24 bits) ← choisie\n\n$ ip route get 10.62.40.25\n10.62.40.25 dev ens19 src 10.62.40.1' },
{ t: 'La route par défaut', d: '', html: 'La route <b>par défaut</b>, notée <code>default</code> ou 0.0.0.0/0, est utilisée quand aucune autre route ne correspond. Sur un poste, c’est la seule route utile en plus du réseau local : tout ce qui n’est pas local part vers la passerelle. Sur un routeur de bordure, elle pointe vers l’opérateur.<br><br>Une machine sans route par défaut ne joint que les réseaux qu’elle connaît explicitement. Le message d’erreur est alors immédiat et caractéristique : <code>connect: Network is unreachable</code>, émis localement sans qu’aucun paquet ne sorte. À ne pas confondre avec un « Destination Host Unreachable » renvoyé par un routeur ou par la machine elle-même quand une résolution ARP échoue.' },
{ t: 'Ajouter des routes sous Linux', d: '', html: 'La commande <code>ip route add</code> ajoute une route immédiatement, mais <b>de façon non persistante</b> : elle disparaît au redémarrage ou lors d’un redémarrage de l’interface. La persistance dépend du gestionnaire réseau : ifupdown (<code>/etc/network/interfaces</code>, directive post-up ou routes dans le bloc de l’interface), systemd-networkd (section [Route] d’un fichier .network) ou NetworkManager (<code>nmcli connection modify … +ipv4.routes</code>).<br><br>La passerelle indiquée doit être <b>directement joignable</b> par une route connectée ; sinon le noyau refuse la route avec « Nexthop has invalid gateway ».', exemple: '# Immédiat, non persistant\nsudo ip route add 172.20.0.0/16 via 10.62.40.2 dev ens19\nsudo ip route replace default via 10.62.0.1\nsudo ip route del 172.20.0.0/16\n\n# Persistant avec ifupdown : /etc/network/interfaces\nauto ens19\niface ens19 inet static\n address 10.62.40.1/24\n up ip route add 172.20.0.0/16 via 10.62.40.2\n down ip route del 172.20.0.0/16 via 10.62.40.2\n\n# Persistant avec systemd-networkd : /etc/systemd/network/ens19.network\n[Route]\nDestination=172.20.0.0/16\nGateway=10.62.40.2' },
{ t: 'Routes statiques sur un routeur Cisco', d: '', html: 'Sur les routeurs des laboratoires de BTS, la syntaxe est <code>ip route réseau masque prochain-saut</code>. On peut aussi indiquer l’interface de sortie, utile sur les liaisons point à point, et une distance administrative en fin de commande pour créer une <b>route flottante</b> : une route de secours qui ne s’installe dans la table que si la route principale disparaît.', exemple: 'R1(config)# ip route 172.20.0.0 255.255.0.0 10.62.40.2\nR1(config)# ip route 0.0.0.0 0.0.0.0 203.0.113.1\nR1(config)# ip route 0.0.0.0 0.0.0.0 198.51.100.1 250 ! route flottante de secours\nR1# show ip route static\nS* 0.0.0.0/0 [1/0] via 203.0.113.1\nS 172.20.0.0/16 [1/0] via 10.62.40.2' },
{ t: 'Le chemin retour', d: '', html: 'L’erreur la plus fréquente en routage statique n’est pas l’aller mais le <b>retour</b>. Une communication fonctionne seulement si chaque routeur du chemin connaît aussi le réseau d’origine. Ajouter sur R1 une route vers le réseau derrière R2 ne suffit pas : R2 doit avoir une route vers le réseau derrière R1, sinon les réponses partent vers sa route par défaut et se perdent.<br><br>Le symptôme typique : un tcpdump sur la machine de destination montre les requêtes qui arrivent et les réponses qui partent, mais l’émetteur ne reçoit rien. On vérifie alors la table de chaque routeur <b>dans les deux sens</b>.<br><br>Un piège voisin est le <b>routage asymétrique</b> : l’aller et le retour empruntent des chemins différents. Cela fonctionne pour le routage pur, mais un pare-feu à état sur un seul des deux chemins ne voit qu’une moitié de la connexion et la rejette.', attention: 'Linux applique par défaut un filtrage anti-usurpation, rp_filter : il rejette un paquet dont l’adresse source ne serait pas routée par l’interface d’arrivée. En cas de routage asymétrique légitime, les paquets disparaissent sans message. On le vérifie avec sysctl net.ipv4.conf.all.rp_filter.' },
{ t: 'Statique ou dynamique ?', d: '', html: 'Le routage statique est sûr, lisible, sans consommation de ressources et sans risque qu’un voisin mal configuré annonce de fausses routes. Il convient parfaitement aux petites topologies, aux sites terminaux qui n’ont qu’une sortie (stub networks) et aux routes par défaut.<br><br>Il devient ingérable dès que le réseau grandit : chaque ajout de réseau impose de modifier tous les routeurs, et une panne de lien n’est pas contournée automatiquement, sauf route flottante. Au-delà de quelques routeurs ou dès qu’il y a des chemins redondants, on passe à un protocole de routage dynamique comme <b>OSPF</b>, qui recalcule les chemins en quelques secondes après une panne. Dans la pratique, les deux coexistent : protocole dynamique en cœur de réseau, routes statiques en bordure.' }
],
synthese: ['Un routeur choisit le prochain saut à partir de l’adresse de destination, saut par saut', 'Routes connectées, statiques, dynamiques', 'Correspondance la plus longue, puis distance administrative, puis métrique', 'Route par défaut 0.0.0.0/0 ; « Network is unreachable » sans elle', 'ip route add est volatile : rendre persistant dans la configuration réseau', 'Toujours vérifier le chemin retour', 'Statique pour les petites topologies et les bordures, dynamique au-delà'],
qcm: [
['Quelle information du paquet le routeur utilise-t-il pour décider ?', ['Adresse MAC source', 'Adresse IP de destination', 'Port TCP', 'TTL'], 1, 'Il cherche la route vers la destination.'],
['Pour 10.62.40.25, quelle route est choisie entre 0.0.0.0/0, 10.62.0.0/16 et 10.62.40.0/24 ?', ['0.0.0.0/0', '10.62.0.0/16', '10.62.40.0/24', 'Aucune'], 2, 'Préfixe le plus long.'],
['Que signifie « connect: Network is unreachable » ?', ['Le serveur a refusé', 'Aucune route, pas même par défaut, ne correspond', 'Le DNS est en panne', 'Le câble est coupé'], 1, 'Erreur locale, aucun paquet envoyé.'],
['Une route ajoutée avec ip route add :', ['est permanente', 'disparaît au redémarrage', 'est propagée aux voisins', 'remplace la route par défaut'], 1, 'Il faut l’écrire dans la configuration réseau.'],
['Que marque proto kernel dans ip route ?', ['Une route statique', 'Une route connectée créée avec l’adresse de l’interface', 'Une route OSPF', 'Une route par défaut'], 1, 'Générée automatiquement.'],
['R1 a une route vers le LAN de R2, mais les pings échouent. Hypothèse prioritaire ?', ['DNS', 'R2 n’a pas de route retour vers le LAN de R1', 'MTU', 'Câble'], 1, 'Toujours vérifier le retour.'],
['Qu’est-ce qu’une route flottante ?', ['Une route qui change de passerelle', 'Une route de secours avec une distance administrative plus élevée', 'Une route IPv6', 'Une route temporaire'], 1, 'Elle ne s’installe qu’en cas de perte de la principale.'],
['Pourquoi le noyau refuse-t-il « ip route add 172.20.0.0/16 via 192.0.2.9 » avec « Nexthop has invalid gateway » ?', ['Le réseau n’existe pas', 'La passerelle n’est pas sur un réseau directement connecté', 'Il manque sudo', 'La route existe déjà'], 1, 'Le prochain saut doit être joignable directement.'],
['Quel paramètre fait d’une machine Linux un routeur ?', ['net.ipv4.rp_filter', 'net.ipv4.ip_forward', 'net.core.somaxconn', 'net.ipv4.tcp_syncookies'], 1, 'Transmission entre interfaces.'],
['Quand préférer OSPF au routage statique ?', ['Pour une seule route par défaut', 'Dès qu’il y a plusieurs routeurs et des chemins redondants', 'Jamais', 'Pour un poste client'], 1, 'Reconvergence automatique.']
],
td: [
{ n: 'Échauffement', c: 'Pour la table suivante — default via 10.0.0.1 ; 10.0.0.0/24 dev eth0 ; 192.168.5.0/24 via 10.0.0.2 ; 192.168.5.128/25 via 10.0.0.3 — donner le prochain saut pour 192.168.5.10, 192.168.5.200, 10.0.0.77 et 8.8.8.8.', r: '10.0.0.2 · 10.0.0.3 (préfixe /25 plus long) · direct sur eth0 · 10.0.0.1' },
{ n: 'Application', c: 'Topologie : LAN A 10.1.0.0/24 — R1 (.1 / 10.255.0.1) — lien 10.255.0.0/30 — R2 (10.255.0.2 / .1) — LAN B 10.2.0.0/24. Écrire toutes les routes nécessaires sur R1, R2 et un poste de chaque LAN pour que A et B communiquent.', r: 'R1 : ip route add 10.2.0.0/24 via 10.255.0.2\nR2 : ip route add 10.1.0.0/24 via 10.255.0.1\nPoste A : default via 10.1.0.1 · Poste B : default via 10.2.0.1\nip_forward=1 sur R1 et R2' },
{ n: 'Application', c: 'Rendre persistante sur R1 (Debian, ifupdown) la route vers 10.2.0.0/24, puis la vérifier après redémarrage de l’interface.', r: 'Dans le bloc iface de l’interface du lien : up ip route add 10.2.0.0/24 via 10.255.0.2\nsudo ifdown ens19 && sudo ifup ens19 ; ip route | grep 10.2.0.0' },
{ n: 'Application', c: 'Un traceroute de A vers B affiche 10.1.0.1 puis 10.255.0.2, puis des étoiles, et la machine B voit arriver les paquets. Diagnostiquer.', r: 'L’aller fonctionne jusqu’à B. B répond mais la réponse ne revient pas : route par défaut absente ou erronée sur B, ou route retour manquante sur R2. Vérifier ip route sur B et R2.' },
{ n: 'Approfondissement', c: 'Un site a deux accès Internet : fibre principale (203.0.113.1) et ADSL de secours (198.51.100.1). Proposer la configuration Cisco et Linux d’une bascule automatique avec des routes statiques.', r: 'Cisco : ip route 0.0.0.0 0.0.0.0 203.0.113.1 et ip route 0.0.0.0 0.0.0.0 198.51.100.1 250 (flottante), idéalement avec un suivi IP SLA.\nLinux : deux routes par défaut avec métriques 100 et 200 ; la seconde n’est utilisée que si la première disparaît (lien down).' },
{ n: 'Approfondissement', c: 'Résumer les routes vers 172.20.0.0/24, 172.20.1.0/24, 172.20.2.0/24 et 172.20.3.0/24, toutes derrière 10.62.40.2, en une seule route. Quel est le risque si 172.20.3.0/24 est déplacé derrière un autre routeur ?', r: 'ip route add 172.20.0.0/22 via 10.62.40.2. Si 172.20.3.0/24 part ailleurs, ajouter une route plus précise 172.20.3.0/24 via le nouveau routeur : la correspondance la plus longue la fera primer sur le résumé.' }
],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Deux LAN, deux routeurs Linux et un lien de transit.', etapes: ['Adresser les quatre machines', 'Activer ip_forward sur les routeurs', 'Ajouter les routes aller', 'Constater l’échec, ajouter les routes retour', 'Valider avec traceroute dans les deux sens', 'Rendre la configuration persistante et redémarrer'] },
plusLoin: [['man ip-route', 'https://man7.org/linux/man-pages/man8/ip-route.8.html'], ['RFC 1812 · Requirements for IPv4 Routers', 'https://www.rfc-editor.org/rfc/rfc1812'], ['systemd.network · section [Route]', 'https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html']] },
plus: {
cas: { titre: '', texte: '' },
resolu: { enonce: 'Mercredi 14 h : après l’installation d’un routeur Linux pour le nouveau laboratoire de BTS (réseau 172.20.0.0/24), les élèves du labo accèdent à Internet mais pas au serveur de fichiers de l’établissement (10.62.40.10), alors que les postes du labo et le serveur se « pingent » depuis le routeur du labo. Diagnostiquer et corriger.', etapes: [
['1 · Reproduire et qualifier', 'Depuis un poste du labo :\nping -c 2 10.62.40.10\n2 packets transmitted, 0 received, 100% packet loss\ntraceroute -n 10.62.40.10\n 1 172.20.0.1 0.4 ms\n 2 10.62.0.1 1.1 ms\n 3 * * *\n→ Le paquet sort par le routeur du labo (172.20.0.1), puis part vers la passerelle principale 10.62.0.1. Il faut comprendre pourquoi il ne va pas plus loin.'],
['2 · Regarder côté serveur', 'Sur 10.62.40.10 :\nsudo tcpdump -ni ens18 -c 4 icmp\nIP 172.20.0.23 > 10.62.40.10: ICMP echo request, id 7, seq 1\nIP 10.62.40.10 > 172.20.0.23: ICMP echo reply, id 7, seq 1\n→ Les requêtes arrivent et le serveur répond. L’aller fonctionne ; c’est le retour qui se perd.'],
['3 · Suivre le chemin retour', 'Sur le serveur :\nip route get 172.20.0.23\n172.20.0.23 via 10.62.40.1 dev ens18 src 10.62.40.10\nSur la passerelle du réseau serveurs (10.62.40.1) :\nip route get 172.20.0.23\n172.20.0.23 via 203.0.113.1 dev wan0 src 203.0.113.10\n→ La passerelle ne connaît pas 172.20.0.0/24 : elle envoie la réponse vers sa route par défaut, c’est-à-dire vers Internet, où elle est perdue.'],
['4 · Identifier le prochain saut correct', 'Sur le routeur du labo :\nip -br addr\nens18 UP 10.62.0.20/24\nens19 UP 172.20.0.1/24\n→ Le routeur du labo est joignable sur le réseau d’infrastructure en 10.62.0.20. C’est ce prochain saut que la passerelle doit utiliser pour 172.20.0.0/24.'],
['5 · Ajouter la route retour, puis la rendre persistante', 'Sur la passerelle :\nsudo ip route add 172.20.0.0/24 via 10.62.0.20\nping -c 2 172.20.0.23\n2 packets transmitted, 2 received, 0% packet loss\nPersistance dans /etc/network/interfaces, bloc de l’interface 10.62.0.1 :\n up ip route add 172.20.0.0/24 via 10.62.0.20\n→ La passerelle sait désormais renvoyer vers le labo. On l’écrit dans la configuration pour survivre au prochain redémarrage.'],
['6 · Valider dans les deux sens et documenter', 'Depuis un poste du labo :\ntraceroute -n 10.62.40.10\n 1 172.20.0.1 0.4 ms\n 2 10.62.0.1 0.9 ms\n 3 10.62.40.10 1.2 ms\n→ Accès rétabli. On note que l’aller passe encore par la passerelle principale : il serait plus direct d’ajouter sur le routeur du labo une route 10.62.0.0/16 via 10.62.0.1, ce qui est déjà le cas par la route par défaut. Compte rendu : cause (route retour absente lors de l’ajout d’un réseau), correction, mise à jour du schéma réseau et de la liste de contrôle « nouveau réseau » : ajouter la route sur tous les routeurs concernés, dans les deux sens.']
] },
erreurs: ['Oublier la route retour', 'Oublier ip_forward sur le routeur Linux', 'Ajouter des routes avec ip route add sans les rendre persistantes', 'Indiquer un prochain saut qui n’est pas sur un réseau directement connecté', 'Oublier la route par défaut d’un poste', 'Confondre « Network is unreachable » (pas de route locale) et « Host Unreachable » (échec ARP ou message d’un routeur)', 'Créer un routage asymétrique à travers un pare-feu à état', 'Laisser rp_filter bloquer un chemin asymétrique légitime'],
memo: [['Commande', 'Usage en production'], ['ip route', 'afficher la table principale'], ['ip route get <ip>', 'route, interface et source réellement utilisées'], ['ip route add <réseau> via <ip>', 'ajouter une route (volatile)'], ['ip route replace default via <ip>', 'changer la route par défaut'], ['ip route del <réseau>', 'supprimer une route'], ['ip route add … metric 200', 'route de secours de moindre priorité'], ['sysctl net.ipv4.ip_forward', 'vérifier le rôle de routeur'], ['sysctl net.ipv4.conf.all.rp_filter', 'vérifier le filtrage anti-usurpation'], ['traceroute -n <ip>', 'suivre le chemin aller'], ['tcpdump -ni <if> icmp', 'voir si les réponses repartent'], ['show ip route (Cisco)', 'table d’un routeur Cisco'], ['ip route 0.0.0.0 0.0.0.0 <ip> 250 (Cisco)', 'route flottante de secours']],
examen: { titre: 'Sujet type · 20 points', q: ['Expliquer la règle de la correspondance la plus longue sur trois routes fournies. (3 pts)', 'Écrire les routes de quatre routeurs pour une topologie donnée, dans les deux sens. (8 pts)', 'Rendre ces routes persistantes sous Debian. (3 pts)', 'Diagnostiquer un problème de route retour à partir de sorties traceroute et tcpdump. (4 pts)', 'Comparer routage statique et dynamique. (2 pts)'], r: ['Préfixe le plus long, puis distance, puis métrique', 'Chaque routeur connaît tous les réseaux distants', 'post-up / up dans /etc/network/interfaces ou [Route]', 'Réponse partant vers la route par défaut', 'Simplicité et contrôle contre reconvergence et passage à l’échelle'] },
prof: { deroule: [['Ouverture', 'Jeu de rôle : chaque élève est un routeur et ne connaît que ses voisins'], ['Cours', 'Table de routage, correspondance la plus longue, route par défaut'], ['Démonstration', 'ip route get sur plusieurs destinations'], ['Pratique', 'Lab deux LAN et deux routeurs, routes aller puis retour'], ['Incident', 'Route retour manquante à diagnostiquer'], ['Clôture', 'Quiz flash, ouverture vers OSPF']], diff: 'Élèves en difficulté : schéma de topologie annoté, routes aller données. Élèves avancés : route flottante, routage par politique (ip rule), résumé de routes.', eval: 'Étapes du lab validées automatiquement, analyse de l’incident, sujet type.' }
},
exemples: [
['Savoir par où part un paquet', 'Un serveur a deux interfaces et il faut savoir laquelle est utilisée pour joindre la sauvegarde.', 'ip route get 172.20.0.15', '172.20.0.15 via 10.62.40.2 dev ens19 src 10.62.40.1 uid 0\n cache', 'La commande ne fait qu’interroger la table : elle indique la route retenue, l’interface et l’adresse source. C’est le moyen le plus fiable de vérifier une hypothèse de routage sans générer de trafic.'],
['Diagnostiquer l’absence de route par défaut', 'Une VM fraîchement installée ne joint pas Internet.', 'ping -c 1 1.1.1.1 ; ip route', 'ping: connect: Network is unreachable\n10.62.40.0/24 dev ens18 proto kernel scope link src 10.62.40.33', 'Erreur immédiate et locale : aucune route ne correspond à 1.1.1.1, faute de route par défaut. Correction : sudo ip route add default via 10.62.40.1, puis gateway 10.62.40.1 dans /etc/network/interfaces.'],
['Ajouter une route vers un réseau de laboratoire', 'Le réseau 172.20.0.0/24 est derrière le routeur 10.62.0.20.', 'sudo ip route add 172.20.0.0/24 via 10.62.0.20\nip route | grep 172.20', '172.20.0.0/24 via 10.62.0.20 dev ens18', 'La route apparaît sans proto static explicite car ajoutée à la main. Elle sera perdue au redémarrage tant qu’elle n’est pas écrite dans la configuration réseau.'],
['Refus d’une passerelle non joignable', 'Faute de frappe dans l’adresse du prochain saut.', 'sudo ip route add 172.20.0.0/24 via 10.62.1.20', 'Error: Nexthop has invalid gateway.', 'Le prochain saut 10.62.1.20 n’appartient à aucun réseau directement connecté ; le noyau ne saurait pas l’atteindre. Le prochain saut doit toujours être sur un réseau d’une interface locale.'],
['Préparer une route de secours', 'Le site a une fibre et une 4G de secours.', 'sudo ip route add default via 203.0.113.1 metric 100\nsudo ip route add default via 192.168.8.1 metric 200\nip route show default', 'default via 203.0.113.1 dev wan0 metric 100\ndefault via 192.168.8.1 dev lte0 metric 200', 'Deux routes par défaut coexistent ; la métrique la plus faible l’emporte. Si l’interface wan0 tombe, sa route disparaît et la 4G prend le relais. Attention : si la fibre reste « up » mais que l’opérateur est en panne, la bascule n’a pas lieu ; il faut alors une supervision active.'],
['Détecter un rejet par rp_filter', 'Des paquets arrivent sur une interface mais ne sont jamais traités.', 'sysctl net.ipv4.conf.ens19.rp_filter ; sudo sysctl -w net.ipv4.conf.all.log_martians=1 ; sudo dmesg | tail -1', 'net.ipv4.conf.ens19.rp_filter = 1\nIPv4: martian source 10.62.40.10 from 172.20.0.23, on dev ens19', 'Le filtre anti-usurpation strict rejette un paquet dont la source ne serait pas routée par ens19 : c’est la signature d’un routage asymétrique. On corrige le routage si possible, sinon on passe rp_filter en mode souple (2) sur cette interface.']
],
long: { figure: svg(720, 200, bx(10, 70, 130, 50, Y, 'LAN A 10.1.0.0/24', 12) + ln(140, 95, 200, 95) + bx(200, 70, 90, 50, L, 'R1', 16) + ln(290, 95, 430, 95) + tx(300, 85, '10.255.0.0/30', 12, 1) + bx(430, 70, 90, 50, L, 'R2', 16) + ln(520, 95, 580, 95) + bx(580, 70, 130, 50, G, 'LAN B 10.2.0.0/24', 12) + tx(160, 160, 'R1 : 10.2.0.0/24 via 10.255.0.2', 13, 1) + tx(400, 185, 'R2 : 10.1.0.0/24 via 10.255.0.1', 13, 1)), legende: 'Chaque routeur doit connaître le réseau distant : une route à l’aller, une au retour.', photo: 'Photo : routeurs de laboratoire reliés par des câbles',
lecture: ['Le routage, c’est la capacité d’Internet à acheminer un paquet d’un bout à l’autre de la planète sans qu’aucun équipement ne connaisse le chemin complet. Chaque routeur ne prend qu’une décision locale : à quel voisin confier ce paquet. La somme de ces décisions construit le chemin.', 'Le routage statique est la forme la plus directe de cette décision : l’administrateur écrit lui-même les règles. Il ne se passe rien d’autre, aucune négociation, aucune surprise. C’est ce qui en fait l’outil idéal pour les situations simples, et un excellent terrain d’apprentissage : quand une route statique ne marche pas, la cause est toujours dans ce que l’on a écrit, ou oublié d’écrire.', 'Ce qu’on oublie le plus souvent, c’est le retour. Un paquet qui atteint sa destination n’est que la moitié du travail ; la réponse doit refaire le chemin inverse, et chaque routeur sur ce chemin doit savoir où renvoyer. Prendre l’habitude de raisonner systématiquement dans les deux sens évite l’immense majorité des pannes de routage.', 'Enfin, le routage statique a ses limites. Dans un réseau de campus avec des liens redondants, écrire et maintenir les routes à la main devient source d’erreurs, et aucune panne n’est contournée automatiquement. C’est la raison d’être des protocoles dynamiques comme OSPF, étudiés ensuite, qui reposent exactement sur les mêmes principes de table et de correspondance la plus longue.'] },
schemas: { termes: ['table de routage', 'route par défaut', 'prochain saut', 'next hop', 'longest prefix match', 'correspondance la plus longue', 'distance administrative', 'métrique', 'route flottante', 'ip route', 'ip route get', 'ip route add', 'ip_forward', 'rp_filter', 'proto kernel', 'scope link', 'Network is unreachable', 'traceroute', 'OSPF', 'route retour'],
figs: [[2, 'Correspondance la plus longue', svg(720, 130, bx(10, 20, 220, 44, N, '0.0.0.0/0 · 0 bit', 14) + bx(245, 20, 220, 44, W, '10.62.0.0/16 · 16 bits', 14) + bx(480, 20, 230, 44, G, '10.62.40.0/24 · 24 bits ✓', 14) + tx(10, 100, 'destination 10.62.40.25 : la route la plus précise l’emporte', 14))]] }
});
})();