IPsec était une bonne idée. Placez le chiffrement à la couche réseau, sous tout le reste, et chaque protocole qui passe sur IP hérite de la confidentialité et de l’intégrité sans qu’on le lui dise. Aucune bibliothèque à lier. Aucun certificat par application. Rien à réécrire dans ce que vous avez déjà livré. Le paquet part protégé et arrive protégé, et les routeurs intermédiaires le transportent sans savoir ni se soucier de ce qu’il contient.
Cette conception repose sur une hypothèse, et elle est écrite dans la norme plutôt que sous-entendue : l’adresse d’un paquet identifie la machine d’où il vient. Une association de sécurité se retrouve à partir de l’adresse de destination, du numéro de protocole et du SPI1. L’Authentication Header va plus loin et signe l’en-tête IP lui-même, source et destination comprises2. Pour IPsec, l’adresse n’est pas une métadonnée de routage. Elle fait partie de l’identité et partie du contrôle d’intégrité.
Puis ce secteur a passé trente ans à retirer l’adresse.
D’abord le NAT, pour faire tenir un bureau derrière une ligne. Puis le NAT d’opérateur, pour faire tenir plusieurs centaines de foyers derrière une adresse, parce qu’activer IPv6 était du travail et acheter un boîtier relevait des achats — c’est tout le sujet de Nous n’avons jamais manqué d’adresses. Nous avons manqué d’effort. et je n’y reviens pas ici. Ce qui compte pour ce billet, c’est la conséquence. La seule chose sur laquelle IPsec a été bâti est précisément celle que le réseau d’accès moderne ne fournit plus.
Alors IPsec a été rafistolé. Emballez le paquet chiffré dans de l’UDP pour qu’un traducteur ait un port à réécrire. Mettez la somme de contrôle à zéro pour que personne ne la revérifie. Envoyez un paquet d’un octet toutes les vingt secondes, pour toujours, pour qu’une table dans le matériel de quelqu’un d’autre n’oublie pas votre existence. Décollez l’identité de l’adresse et accrochez-la à un nom. Abandonnez l’Authentication Header, parce qu’il ne peut pas survivre par construction à un en-tête réécrit. Et quand un hôtel bloque l’UDP, emballez le tout dans du TCP en plus3.
Chacun de ces points est une solution réelle, normalisée, prise en charge par les constructeurs. Ensemble, ils forment un protocole tenu debout par son propre échafaudage. Et l’échafaudage, c’est l’argument : on ne passe pas un quart de siècle à étayer quelque chose parce que c’est fondamentalement sain.
La conclusion à laquelle je suis arrivé, c’est qu’IPsec doit être mis à la retraite en entier. Pas ajusté, pas reproposé avec de meilleurs chiffrements, pas conservé pour le site à site sous prétexte que cette partie fonctionne encore. Retiré, avec des dates, comme PPTP aurait dû l’être une décennie avant que quelqu’un s’en occupe. Ce qui suit, ce sont les preuves, les schémas, la documentation des constructeurs qui dit tout cela dans leurs propres mots, et — parce que la plupart de ceux qui lisent ceci doivent quand même faire tourner ces choses lundi — une méthode utilisable pour diagnostiquer les pannes IPsec en attendant.
Ce que cela vous coûte vraiment, en tickets
Avant les normes, voici la facture, dans l’ordre où vous la rencontrerez.
Le tunnel tombe à intervalle régulier. Toutes les heures, ou toutes les huit heures, ou après vingt minutes sans trafic. Il revient dès que quelqu’un ouvre un fichier, donc la moitié des utilisateurs ne le signale jamais et l’autre moitié le signale comme « le VPN est lent ». Personne n’a rien changé.
Deux personnes dans la même maison ne peuvent pas se connecter en même temps. La seconde monte, la première tombe. Elles appellent le service d’assistance séparément, donc les tickets ne se croisent jamais et personne ne repère le schéma pendant quinze jours.
Les petites choses marchent et les grandes bloquent. La connexion marche. Teams marche. Ping marche. Copier un fichier s’arrête chaque fois au même endroit, et ouvrir une grande page dans une application interne reste là jusqu’au délai d’expiration.
Le tunnel est monté et aucun trafic ne passe. Les deux bouts disent « établi ». Les deux bouts sont contents d’eux. Rien ne bouge.
Rien ne peut entrer. Le site à site vers l’agence passée chez un opérateur fibre alternatif ne s’établit plus dans le sens où il le faisait, et personne ne sait dire pourquoi, seulement que « leur IP a changé ».
Activer la QoS a cassé le chiffrement. Quelqu’un a priorisé la voix, et maintenant le bout distant jette des paquets comme s’il s’agissait de rejeux.
Aucun de ces cas n’est une erreur de configuration au sens ordinaire. Chacun est IPsec qui rencontre le réseau tel qu’il est aujourd’hui. Le reste de ce billet explique pourquoi, dans l’ordre, et comment prouver lequel vous avez.
IPsec n’est pas transporté par le réseau. Il est le réseau.
Commençons par ce qu’il était, parce que la conception est réellement bonne et que les défaillances ne prennent sens que par rapport à elle.
ESP n’est pas un protocole qui tourne au-dessus de TCP ou d’UDP. Il est un protocole de transport, numéro de protocole IP 50, posé directement sur IP, dans l’emplacement même où se trouvent TCP et UDP. AH est le protocole 51. Aucun des deux n’a de champ de port, parce qu’aucun n’en a besoin : sur l’internet pour lequel IPsec a été conçu, l’adresse de destination désigne déjà exactement une machine, et le SPI dans l’en-tête ESP désigne quelle association de sécurité sur cette machine. Adresse plus protocole plus SPI. Ce triplet, c’est la recherche1.
Regardez ce que cela apporte. Aucun port de négociation à exposer, aucune couche de session à rater, aucune application qui doive donner son accord. L’un ou l’autre bout peut commencer. Le milieu du réseau est bête, et c’est exactement ce que doit être le milieu d’un réseau. Un routeur achemine le protocole 50 comme il achemine le protocole 6, et le fait qu’il ne puisse pas lire la charge utile est le but plutôt qu’une limite.
C’est une conception propre. C’est aussi, en 2026, la description d’un internet que la plupart de ceux qui lisent ceci ne peuvent pas acheter.
Puis quelqu’un a mis un traducteur sur chaque chemin
Un NAT réécrit l’adresse source, et souvent le port source, pour que plusieurs machines partagent une adresse. C’est tout ce qu’il fait. Contre IPsec, c’est à peu de chose près une démolition complète, et l’IETF a été assez franche pour publier un document entier qui en liste les morceaux : RFC 3715, IPsec-Network Address Translation (NAT) Compatibility Requirements4. Seize incompatibilités distinctes. Voici celles qui comptent.
AH est fini, par construction. Dans les mots mêmes de la RFC 3715 : « Since the AH header incorporates the IP source and destination addresses in the keyed message integrity check, NAT or reverse NAT devices making changes to address fields will invalidate the message integrity check. »4 — l’en-tête AH inclut les adresses source et destination dans le contrôle d’intégrité, donc toute modification d’adresse l’invalide. Il n’y a pas de correctif, et il n’allait jamais y en avoir. Un protocole qui signe l’en-tête ne peut pas traverser un boîtier dont le métier est de réécrire l’en-tête. AH n’a pas été contourné. Il a été abandonné.
Il n’y a pas de ports à traduire. Un NAT qui fait de la traduction de ports a besoin d’un port. ESP n’en a pas. Cisco l’écrit sans détour dans le guide de configuration Catalyst : « If PAT found a legislative IP address and port, it would drop the Encapsulating Security Payload (ESP) packet. »5 Le paquet n’est pas rejeté sur décision de politique. Il est jeté parce que le boîtier n’a nulle part où écrire ce qu’il doit écrire.
L’identité cesse de correspondre au paquet. Toujours dans la RFC 3715 : « Where IP addresses are used as identifiers in Internet Key Exchange Protocol (IKE) Phase 1 or Phase 2, modification of the IP source or destination addresses by NATs or reverse NATs will result in a mismatch between the identifiers and the addresses in the IP header. »4 — lorsque les adresses servent d’identifiants, la traduction crée un désaccord entre l’identifiant et l’en-tête. Un schéma d’identité qui nomme les machines par adresse ne survit pas à un équipement qui renomme les machines pour gagner sa vie.
Deux machines peuvent choisir le même SPI. Le SPI est choisi par le destinataire et n’a besoin d’être unique que chez lui. Mettez deux hôtes derrière une adresse et le traducteur a deux associations sans rien pour les distinguer.
Rien ne peut entrer en premier. Un NAT construit sa table à partir des paquets sortants. Il n’y a pas de paquet sortant tant que personne ne commence, et sur une ligne en NAT seul l’intérieur peut commencer. La moitié de la symétrie du protocole a disparu.
Le correctif était réel, et chacune de ses pièces a coûté quelque chose
La traversée de NAT fonctionne. Ce n’est pas contesté et je ne vais pas faire semblant du contraire. J’ai exploité beaucoup de tunnels à travers beaucoup de NAT. Ce que je veux consigner, c’est la facture, parce qu’elle est payée chaque jour par tout le monde et que presque personne ne la détaille.
Le mécanisme est la RFC 3948 : détecter un traducteur pendant l’échange de clés, puis placer tout le paquet ESP dans un datagramme UDP sur le port 4500 pour que le traducteur ait quelque chose qu’il comprend6. La description du format sur le fil par Cisco est exacte : après chiffrement, « a UDP header and a non-IKE marker (which is 8 bytes in length) are inserted between the original IP header and ESP header »5 — un en-tête UDP et un marqueur non-IKE de huit octets sont insérés entre l’en-tête IP d’origine et l’en-tête ESP. Celle de Juniper est plus courte et dit la même chose : « NAT-T encapsulates both IKE and ESP traffic within UDP with port 4500 used as both the source and destination port. »7
Maintenant la facture détaillée.
L’Authentication Header a disparu. Pas poliment déprécié. Inutilisable. La RFC 8221 dit désormais clairement qu’utiliser ESP avec AH est NOT RECOMMENDED8, et la raison honnête est que la seule chose qu’AH faisait et qu’ESP ne fait pas est précisément celle que le NAT détruit.
La somme de contrôle UDP est délibérément mise à zéro. La RFC 3948 l’exige : avec des adresses réécrites, une somme calculée dessus échouerait, donc la réponse de la norme est d’arrêter de la calculer. « If the protocol header after the ESP header is a UDP header, set the checksum field to zero in the UDP header. »6 Une couche de détection d’erreur retirée pour qu’une couche de réécriture d’adresses continue de fonctionner.
Vous envoyez désormais des paquets pour garder une table au chaud. La RFC 3948 définit un keepalive comme un octet, 0xFF, envoyé quand rien d’autre n’est sorti pendant un intervalle configurable dont la valeur par défaut est vingt secondes6. Juniper en donne la raison sans fioriture : « Because NAT devices age out stale UDP translations, keepalive messages are required between the peers. »7 Un portable dans un train, qui ne fait strictement rien, émet donc toutes les vingt secondes, pour toujours, parce qu’une table dans un boîtier qui n’appartient à aucun des deux bouts oublierait sinon son existence. Multipliez par une flotte. C’est la radio qui se réveille, la batterie qui descend, et le réseau mobile qui transporte du trafic dont le seul but est d’empêcher l’oubli.
Vous filtrez désormais deux ports au lieu d’un protocole, et la liste de restrictions de Cisco exige des règles de traduction statiques pour 500 et 4500 avant que quoi que ce soit fonctionne5.
Et lisez le reste de cette liste de restrictions, parce que c’est le constructeur qui vous décrit la forme de la chose. Politiques de NAT dynamique : non prises en charge. Trafic IPv6 : incompatible avec la fonction. IPsec et NAT sur le même équipement : les deux ne peuvent pas fonctionner ensemble5. Ce n’est pas un guide de configuration. C’est la liste des endroits où l’échafaudage n’atteint pas.
Rien de tout cela n’est élégant, et ce n’est la faute de personne en particulier. C’est ce qui arrive quand on maintient en vie un protocole de couche 3 sur un réseau qui a cessé d’honorer la couche 3.
Le NAT d’opérateur a retiré ce qui restait
Le NAT ordinaire a pris l’adresse à la machine pour la donner au site. Le traducteur vous appartenait encore, vous pouviez donc rediriger un port, figer une association, allonger une minuterie ou mettre le concentrateur devant.
Le NAT d’opérateur prend l’adresse au site et la donne à plusieurs centaines d’inconnus, et le traducteur appartient à votre fournisseur d’accès. Tout ce que vous pouviez faire auparavant, vous ne le pouvez plus.
Et soyez clair sur ce qui se trouve réellement sur le chemin, parce que c’est le point que les gens ratent. Le routeur de la maison fait toujours du NAT. Il n’a pas été désactivé. Il traduit toujours votre portable en 192.168.1.20 vers l’adresse que porte la ligne — sauf que la ligne porte désormais 100.64.12.7, de l’espace partagé, pas une adresse publique. L’opérateur traduit ensuite une seconde fois. Le paquet traverse donc deux traducteurs avant d’atteindre l’internet, et c’est le cas ordinaire, pas une curiosité.
Vous êtes en double NAT, et une seule des tables est la vôtre. Deux traductions veulent dire deux tables d’association, deux minuteries de vieillissement et deux occasions que l’association disparaisse. Votre keepalive doit battre celle qui expire en premier, et vous ne pouvez en lire qu’une seule. Pire, les deux interagissent : le routeur de la maison a peut-être ses propres idées sur IPsec et essaie d’aider avec une passerelle applicative, si bien que le port source que votre client croit utiliser n’est ni celui qui sort de la maison ni celui qui sort de chez l’opérateur.
La redirection de port fonctionne toujours, et ne fait absolument rien. C’est le ticket qui mange le plus de temps. Quelqu’un redirige UDP 500 et 4500 sur le routeur domestique, le routeur l’accepte, la page de réglages dit que la règle est active — et rien ne peut s’en servir, parce qu’elle redirige depuis une adresse que l’internet ne peut pas atteindre. UPnP et PCP se comportent pareil : le client demande une association, le routeur l’accorde, et le port s’ouvre sur un couloir. Tout signale un succès et rien ne fonctionne. Le boîtier vous racontera ce que vous voulez entendre.
Le moyen le plus rapide de trancher ne coûte rien. Lisez l’adresse WAN dans le routeur. Si elle commence par 100.64, c’est l’espace partagé réservé par la RFC 6598, vous êtes derrière un NAT d’opérateur, et la moitié de cette page de réglages est décorative.
Le rôle de répondeur n’existe plus. Un équipement derrière un CGNAT ne peut pas être le bout que l’on appelle. Le site à site entre deux agences sur de la fibre grand public — normal, bon marché, et exactement ce que veut une petite entreprise — exige qu’au moins un bout détienne une adresse réelle, ou un tiers au milieu pour les présenter. Ce tiers est une entreprise dont vous dépendez désormais parce que votre fournisseur d’accès n’a pas voulu vous donner une adresse.
La minuterie appartient à quelqu’un d’autre. La RFC 4787 dit aux opérateurs de NAT qu’une association UDP « MUST NOT expire in less than two minutes » et en recommande cinq ou plus9. C’est le plancher et le conseil, pas une promesse, et vous ne pouvez pas inspecter ce que votre opérateur fait réellement. De ce fait, le keepalive cesse d’être un réglage. Il est porteur, sur une minuterie que vous devinez.
L’identité de votre pair ne peut pas être son adresse. Plusieurs abonnés atteignent le bout distant sous une seule adresse. Quoi que le concentrateur utilise pour les distinguer, ce n’est pas l’en-tête IP — et c’est justement ce qu’IPsec devait utiliser.
Il y a un plafond dur, et les constructeurs le publient. Juniper documente que sur SRX5400, SRX5600 et SRX5800, « the total number of tunnels from a given public translated IP cannot exceed 1000 tunnels »7. Lisez cela en exploitant et non comme une ligne de spécification. Votre concentrateur VPN a une limite par adresse partagée, le partage est fait par un opérateur avec lequel vous n’avez aucun contrat, et votre proximité de cette limite dépend du nombre de vos utilisateurs qui se trouvent derrière la même. Il n’y a aucun compteur à consulter. Il y a seulement le jour où cela commence à échouer pour certains et pas pour d’autres.
Tout dans cette section découle d’une décision que ce pays a prise et reprise. J’ai exposé ce dossier ailleurs et je ne le répète pas. Le point est ici plus étroit : l’hypothèse fondatrice d’IPsec a été supprimée par le réseau d’accès, et IPsec vit depuis de contournements.
Et le réseau IPv6 seul ne le sauve pas non plus
Ici je dois être honnête contre mon propre argument, parce que la réponse évidente à tout ce qui précède est : très bien, donnez à chaque machine une vraie adresse IPv6 et IPsec refonctionne comme spécifié.
C’est vrai, entre deux bouts qui en ont une. Ce n’est pas le réseau où se trouvent la plupart des gens.
Les réseaux d’accès IPv6 seul qui existent réellement, le mobile en particulier, atteignent l’internet IPv4 par NAT64, qui n’est pas un NAT du tout au sens ordinaire. C’est un traducteur de protocole, qui réécrit un paquet IPv6 en paquet IPv4. Et la RFC 6146 nomme ce qu’il transportera, et nomme ce qu’il ne transportera pas, sans la moindre ambiguïté :
« The current specification only defines how stateful NAT64 translates unicast packets carrying TCP, UDP, and ICMP traffic. Multicast packets and other protocols, including the Stream Control Transmission Protocol (SCTP), the Datagram Congestion Control Protocol (DCCP), and IPsec, are out of the scope of this specification. »10
IPsec, nommément, hors périmètre. Et les paquets portant quoi que ce soit hors de cette liste « SHOULD be discarded »10.
Sur un téléphone ou un portable en IPv6 seul qui cherche à joindre un concentrateur IPv4 — et c’est le cas de la plupart des concentrateurs —, l’ESP natif n’est donc pas jeté par un pare-feu ni abîmé par un traducteur. Il n’est simplement jamais transporté. Le traducteur fait précisément ce que sa norme lui dit de faire.
La réponse du secteur est, inévitablement, une couche de plus : 464XLAT, qui donne à l’équipement une pile IPv4 locale et traduit deux fois, hors d’IPv4 puis de retour, pour que ce que NAT64 ne peut pas transporter fonctionne quand même11. Il figure déjà sur la liste des rustines du billet IPv6 et je ne vais pas le réargumenter. Ce qui mérite d’être dit ici, c’est la forme : un protocole qui s’est cassé sur le NAT en 2004 se casse aussi sur la traduction construite pour la transition IPv6 en 2011, et les deux fois la réponse consiste à l’emballer dans autre chose.
C’est le test qu’un protocole doit passer pour avoir sa place en 2026. Fonctionne-t-il sur le réseau que les gens ont réellement — derrière l’adresse partagée d’un opérateur, sur un réseau mobile IPv6 seul, à travers un hôtel qui ne laisse passer que TCP 443 ? Tout ce qui est bâti sur un port UDP passe les trois sans qu’on le lui dise. IPsec a besoin d’un contournement différent pour chacun, et pour le troisième d’une encapsulation TCP en plus3.
Pas de ports veut dire aussi pas de second lien
Voici une défaillance qui n’a rien à voir avec le NAT, qui est purement moderne, et dont on ne parle presque jamais.
Routeurs et commutateurs répartissent le trafic sur des chemins parallèles. Agrégation de liens, multichemin à coût égal : les deux fonctionnent pareil, en hachant le quintuplet. Adresse source, adresse destination, protocole, port source, port destination. ESP n’a pas de ports. Chaque paquet d’un tunnel entre les deux mêmes adresses se hache donc de façon identique, et tout le tunnel atterrit sur un seul lien membre, quel que soit le nombre que vous avez acheté.
Deux liens 10G et un tunnel IPsec vous donnent 10G. Quatre vous donnent 10G. Le matériel fonctionne exactement comme prévu.
Le contournement a la forme habituelle. Certains silicium savent hacher sur le SPI à la place, puisque chaque SPI nomme une association et donc un flux, mais c’est une fonction qu’il faut avoir achetée, pas quelque chose que l’on peut supposer d’un chemin qui ne vous appartient pas. Il existe un projet IETF actif dont l’unique objet est d’emballer ESP dans encore un en-tête UDP pour que des routeurs ordinaires puissent le hacher, et il dit pourquoi en une phrase : « Although the ESP SPI field within the IPsec packets can be used as the load-balancing key, but it cannot be used by legacy switches and routers. »12 Son exposé du problème est tout aussi direct sur ce que les gens font à la place : « Many cloud service providers allow customers to establish multiple IPsec VPN tunnels in parallel to enable ECMP and increase aggregate bandwidth. However, this approach is not ideal, as each tunnel typically requires its own public IP address, leading to higher public IP consumption and increased operational overhead. »12
Laissez cela infuser un instant. La manière recommandée d’accélérer une liaison chiffrée est d’en construire plusieurs, chacune brûlant une adresse IPv4 publique — pendant une pénurie d’adresses — parce que le protocole n’a pas de numéro de port à hacher. Pendant ce temps, un tunnel bâti sur UDP obtient le multichemin gratuitement, sur du matériel livré il y a quinze ans, parce qu’il a un port comme tout le reste de l’internet moderne.
Ce n’est pas un problème d’héritage qui va s’éteindre tout seul. C’est une limite bien vivante sur les constructions neuves, aujourd’hui, exactement aux débits que les gens achètent en ce moment.
La taxe MTU, et qui la paie
Chaque tunnel coûte des octets. IPsec en coûte plus que la plupart, et sa façon d’échouer quand la place manque est le pire genre de panne : intermittente, dépendante de la taille, et invisible à tous les tests que l’on lance en premier.
Faites le calcul pour une configuration plutôt que d’agiter les mains. ESP en mode tunnel sur IPv4 avec AES-GCM : 20 octets d’en-tête IP externe, 8 d’en-tête ESP, 8 de nonce, 2 au minimum de fin de bloc, 16 d’empreinte d’intégrité. 54 octets avant que la moindre partie de votre paquet n’entre. Emballez-le pour la traversée de NAT et l’en-tête UDP le porte à 62. Sur un chemin à 1500 octets il reste 1438, et dès qu’il y a du PPPoE à 1492 en amont vous repassez dessous.
Puis vient ce qui en fait une panne plutôt qu’un problème d’arithmétique. Un émetteur n’apprend qu’un paquet était trop gros que par le retour d’une erreur ICMP — Fragmentation Needed en IPv4, Packet Too Big en IPv6. Si quoi que ce soit sur le chemin jette ces erreurs, l’émetteur ne l’apprend jamais et continue d’envoyer des paquets qui continuent de mourir. C’est le trou noir classique : la négociation aboutit parce que les négociations sont petites, et le transfert bloque parce que les transferts ne le sont pas.
Cisco maintient un document entier là-dessus depuis l’époque de GRE et d’IPsec, et il reste l’une des meilleures explications de cette interaction dans la bibliothèque de quiconque13. S’il doit être maintenu, c’est parce que les gens continuent de bloquer ICMP en bloc puis s’étonnent que les tunnels se comportent bizarrement.
J’ai déjà écrit les deux moitiés de cet argument et elles valent ici sans être répétées : quels messages ICMP sont porteurs et lequel ne l’est pas, dans Ping : l’outil de diagnostic qui ouvre bien plus que ça, et comment trouver le saut exact qui mange votre trafic, dans Le pare-feu est à onze sauts. La version courte pour ce billet : les erreurs sont le mécanisme, l’écho ne l’est pas, et une politique de bordure qui jette tout ICMP a cassé votre VPN d’une façon qui sera imputée au VPN.
Et votre propre qualité de service peut le casser
Encore un, parce qu’il attrape de bons ingénieurs en train de bien faire.
ESP porte un numéro de séquence et le destinataire tient une fenêtre anti-rejeu de 64 paquets par défaut sur les plateformes Cisco14. Priorisez maintenant la voix sur le routeur émetteur. La file d’attente à faible latence fait ce que vous avez demandé et réordonne les paquets par rapport à la séquence dans laquelle ils ont été chiffrés. Si un paquet tombe hors de la fenêtre à son arrivée, le bout distant le jette comme un rejeu, et le compteur qui monte est un compteur de sécurité.
Les mots de Cisco : « Certain QoS features, such as Low Latency Queueing (LLQ), could cause IPsec packet delivery to become out-of-order and dropped by the receiving endpoint due to a replay check failure. »14 Leur réponse est d’élargir la fenêtre à 1024 là où la plateforme le permet, ou d’adopter une extension à espaces de numéros de séquence multiples qui associe les classes de QoS à des espaces de séquence séparés au sein d’une même association14.
Donc : activer une fonction standard de votre propre réseau casse votre propre tunnel, et le remède est encore une extension de protocole. La même forme que tout ce qui précède.
L2TP : du tramage d’accès commuté, chiffré, en 2026
L2TP n’est pas un protocole de sécurité et ne l’a jamais prétendu. La RFC 2661 est un protocole de tunnel pour transporter des sessions PPP, publiée en 1999, sans confidentialité propre — sa propre section sécurité vous renvoie à IPsec pour la protection au niveau du paquet15. Cet appariement, c’est la RFC 3193, et le résultat est la pile du schéma ci-dessus : un en-tête IP externe, un en-tête UDP pour la traversée de NAT, ESP, puis à l’intérieur du chiffrement encore un en-tête UDP sur le port 1701, un en-tête L2TP et un en-tête PPP.
PPP. Le tramage des modems d’accès commuté, transporté dans un tunnel chiffré, sur l’internet, en 2026, parce que c’est ce que L2TP a été écrit pour transporter.
Comptez ce que cela coûte sur un exemple — IP externe 20, UDP 8, en-tête ESP et IV 24, UDP interne 8, L2TP 6, PPP 4, fin de bloc et empreinte 18 — et vous dépensez environ 88 octets par paquet pour déplacer des données que l’ESP natif déplace pour 54. Trente-quatre octets, sur chaque paquet, pour une couche de session qui n’apporte rien de ce que vous vouliez et une couche de liaison conçue pour une ligne téléphonique.
Le surcoût est le moindre des soucis.
Cela multiplie le problème du NAT au lieu de le diviser. L2TP/IPsec utilise habituellement ESP en mode transport, c’est-à-dire le mode auquel le NAT fait le plus de mal, et le résultat bien connu est que beaucoup d’implémentations ne supportent pas du tout deux clients derrière une adresse. Deux personnes dans une maison, ou quarante dans un bureau, ou plusieurs centaines derrière l’adresse partagée d’un opérateur. Le bout distant voit une adresse et ne peut pas distinguer les sessions, donc la deuxième connexion remplace la première. C’est le ticket du début de ce billet, et ce n’est le défaut du produit de personne — c’est le problème de l’identité par adresse qui arrive là où le plus de gens le rencontrent.
Et sur le terrain il est le plus souvent déployé avec un secret partagé unique pour tout le monde. Comme le secret est configuré dans le profil client et distribué avec la notice d’installation, la clé prépartagée est dans le document d’accueil, sur la page du wiki, dans le courriel aux nouveaux arrivants, et sur chaque portable qui est un jour sorti. Ce n’est pas un second facteur. C’est un mot de passe qui authentifie la passerelle auprès de personne en particulier et qui n’a jamais été changé.
L2TP n’est pas un protocole qui a mal vieilli. C’est un protocole qui transportait la mauvaise chose dès le premier jour, et qu’on a boulonné à IPsec pour compenser ce qu’il ne savait pas faire du tout.
PPTP n’a jamais été sûr, et il est toujours en vente
PPTP mérite deux paragraphes, pas une section, et il ne les obtient que parce que des gens le livrent encore.
Il n’a jamais été une norme. La RFC 2637 est Informational. Un protocole de constructeur mis par écrit, pas quelque chose que l’IETF ait jamais recommandé. Il transporte PPP dans GRE, protocole IP 47, qui comme ESP n’a pas de ports, il lui faut donc un traitement particulier dans chaque NAT du chemin — la case « PPTP passthrough », qui sur bon nombre de routeurs domestiques ne supporte qu’une seule session à la fois.
La sécurité s’est terminée publiquement en 2012. Marlinspike et Hulton ont montré que la sécurité de MS-CHAPv2 se réduit à une seule opération DES quelle que soit la longueur du mot de passe, ont écrit chapcrack pour extraire la négociation, et l’ont branché sur un service de cassage qui rendait la clé en moins d’une journée pour vingt dollars — un taux de réussite de 100 %, pas une probabilité16. Leur conclusion était que le trafic PPTP doit être considéré comme non chiffré. Apple a voté avec ses pieds et a retiré PPTP du client intégré de macOS Sierra et d’iOS 10 en 2016, et publie toujours l’avertissement17.
Dix ans plus tard, PPTP est encore une entrée de menu sur des routeurs vendus cette année, encore dans les guides des constructeurs, encore ce que quelqu’un active parce que c’est celui qui marche du premier coup. Il marche du premier coup parce qu’il ne fait pas le travail.
Tout ce qui se dit VPN IPsec
« VPN IPsec » n’est pas un protocole. C’est une famille, et la longueur de la liste ci-dessous est l’argument, parce que deux produits n’implémentent jamais le même sous-ensemble, et que c’est dans les écarts entre ces sous-ensembles que vit chaque chantier d’interopérabilité que vous avez détesté.
| Pièce | Ce qu’elle apporte | Où elle en est |
|---|---|---|
| ESP, protocole IP 50 | Le chiffrement et l’intégrité eux-mêmes | RFC 4303 — en vigueur18 |
| AH, protocole IP 51 | L’intégrité sur l’en-tête IP aussi | RFC 4302 — inutilisable à travers un NAT2 |
| IKEv1 | L’échange de clés d’origine | Déprécié, RFC passées en Historic19 |
| IKEv2 | L’échange de clés actuel | RFC 729620 |
| IPComp, protocole IP 108 | Compresse avant de chiffrer, avec ses propres associations | RFC 317321 |
| PF_KEY v2 | Une API noyau pour qu’un démon charge les clés | RFC 236722 |
| Traversée de NAT | Emballe ESP dans UDP 4500 pour qu’un traducteur s’en sorte | RFC 3947 / 39486 |
| Encapsulation TCP | Pour les réseaux qui bloquent aussi l’UDP | RFC 9329, qui remplace la RFC 82293 |
| Fragmentation IKEv2 | Parce que l’échange de clés lui-même a dépassé la MTU | RFC 738323 |
| MOBIKE | Pour que le tunnel survive au changement d’adresse | RFC 455524 |
| Détection de pair mort | Un battement de cœur, parce que rien d’autre ne vous le dit | RFC 370625 |
| XAUTH | Authentification utilisateur — mot de passe, jeton, RADIUS | Jamais une RFC. Projet expiré, 200126 |
| Mode-Config | Donne au client adresse, DNS et routes | Jamais une RFC non plus26 |
| L2TP/IPsec | Transporte PPP dans le tunnel | RFC 2661 + RFC 319327 |
| GRE ou VTI sur IPsec | Vous donne une interface routable pour y faire tourner un protocole | Architecture constructeur au-dessus d’ESP |
| DMVPN | mGRE plus NHRP plus IPsec, pour que les branches se trouvent | Architecture constructeur, NHRP RFC 233228 |
| GETVPN | Clés de groupe, sans aucun tunnel deux à deux | GDOI, RFC 640729 |
| PPTP | Ce qu’IPsec devait remplacer | RFC 2637 — Informational, jamais une norme30 |
Regardez maintenant les deux lignes en gras, parce que ce sont celles qui devraient vous arrêter.
Pendant près de deux décennies, la façon normale de connecter un utilisateur à un VPN IPsec d’entreprise a été XAUTH — votre identifiant et votre mot de passe, votre jeton, votre serveur RADIUS — avec Mode-Config pour donner au client son adresse, ses serveurs DNS et ses routes. À eux deux, ils constituent toute l’expérience d’accès distant. Chaque client « Cisco IPsec », chaque icône VPN dans une barre des tâches, chaque notice de connexion.
Aucun des deux n’est une norme. XAUTH était un projet internet individuel qui a expiré en 2001 et a été archivé sans jamais devenir une RFC26. La raison invoquée mérite d’être lue, parce que c’est un comité qui explique pourquoi il ne ferait pas son travail : le projet consigne que le groupe de travail IPSRA n’accepterait aucun protocole étendant ISAKMP ou IKE, et que le groupe de travail IPsec refusait tout ce qui touchait à l’accès distant26. La partie la plus déployée du protocole VPN le plus déployé s’est donc retrouvée sans foyer, implémentée quand même par chaque constructeur selon sa propre lecture d’un projet expiré, et livrée à des millions d’utilisateurs.
IKEv2 a fini par corriger les deux, et cela mérite d’être dit : l’authentification est passée à EAP et les charges utiles de configuration du client sont entrées dans la spécification principale20. Mais lisez les dates. La fonction la plus utilisée du protocole VPN le plus utilisé a tourné sur un projet expiré pendant une décennie environ avant d’avoir la moindre norme, et le parc installé a continué de faire tourner la version projet des années après. Une famille de protocoles ne mérite pas de crédit pour avoir fini par normaliser la partie que tout le monde utilisait déjà.
Voilà la famille que vous exploitez. Une partie est en Standards Track et en vigueur. Une partie est Historic. Une partie n’est jamais devenue quoi que ce soit. Et un produit dont la fiche technique dit « VPN IPsec » ne vous a à peu près rien dit sur celles de ces dix-huit pièces qu’il sait faire, ce qui explique pourquoi en raccorder deux prend quinze jours, un tableur de propositions et un coup de fil à quelqu’un qui l’a déjà fait.
Le Fisher-Price OS (Windows) n’a jamais vraiment interopéré
C’est le passage où quelqu’un dit que le problème c’est Linux, alors faisons-le avec des sources.
Par défaut, le client Windows ne se connecte pas du tout à un serveur IPsec situé derrière un NAT. Pas « aura du mal ». Refusera. Le correctif est une valeur de registre nommée AssumeUDPEncapsulationContextOnSendRule sous HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent, mise à 1 si le serveur est derrière un traducteur ou à 2 si les deux bouts le sont, sur chaque client et sur le serveur, suivie d’un redémarrage31. Les mots de Microsoft : « By default, Windows Vista and Windows Server 2008 don’t support Internet Protocol security (IPsec) network address translation (NAT) Traversal (NAT-T) security associations to servers that are located behind a NAT device. »31
Deux remarques. La première, c’est que Microsoft a coécrit la norme de traversée de NAT qu’il refuse d’utiliser. Son nom figure sur la RFC 3947 et la RFC 39486. La seconde, c’est que la page qui vous dit de modifier le registre a été révisée pour la dernière fois en février 202631. Vingt ans après, une bidouille de registre sur chaque poste est toujours la réponse, et elle est toujours maintenue comme la réponse.
Et lisez la phrase que Microsoft place juste au-dessus : « If you must use IPsec for communication, use public IP addresses for all servers that you can connect to from the Internet. »31
C’est tout ce billet, dans la documentation du constructeur. Ne mettez pas IPsec derrière un NAT. Donnez à chaque machine une vraie adresse. Ils l’ont écrit, et le secteur a ensuite passé deux décennies à faire le contraire et à facturer la différence.
Cela ne s’arrête pas au NAT. Allez lire ce qu’une passerelle libre doit documenter pour accepter un client Windows.
- Le certificat de la passerelle a besoin d’un usage étendu de clé qui n’existe que pour cela. serverAuth, OID 1.3.6.1.5.5.7.3.1, plus IP Security IKE Intermediate, OID 1.3.6.1.5.5.8.2.232. Votre autorité de certification doit apprendre à émettre un OID dont la plupart des outils n’ont jamais entendu parler, sinon la connexion échoue sur une erreur de politique sans message utile.
- Une deuxième valeur de registre est nécessaire avant que le client propose de la cryptographie correcte. strongSwan documente l’ajout de
NegotiateDH2048_AES256sousRasman\Parameterspour obtenir AES-256-CBC et un groupe de 2048 bits33. Lisez-le dans l’autre sens, c’est celui qui compte : sans modification du registre, la proposition par défaut est plus faible que cela. - Le renouvellement de clés initié par le serveur est rejeté par les clients derrière un NAT, et le contournement documenté consiste à désactiver le renouvellement sur la passerelle et à laisser le client le lancer33.
- Des extensions IKEv2 standard sont tout simplement absentes — pas de redirection IKE, pas de tours d’authentification multiples33.
Rien de tout cela n’est un défaut de Linux. Chacun de ces points est un projet libre qui écrit ce qu’il doit faire pour s’accommoder de la lecture qu’un constructeur fait d’une norme qu’il a lui-même coécrite.
C’est le schéma, et il a trente ans. PPTP était le protocole de Microsoft, mis par écrit en Informational et jamais normalisé30. MS-CHAPv2 et MPPE étaient l’authentification et le chiffrement de Microsoft, et les deux ont été cassés en public16. SSTP est un tunnel Microsoft que personne d’autre ne termine. DirectAccess était de l’IPsec, et c’était Windows aux deux bouts par conception — et il est désormais déprécié et en cours de retrait, les clients étant poussés vers Always On VPN34. Aucun de ces protocoles n’a jamais été un protocole où le reste d’entre nous pouvait se retrouver à mi-chemin. C’était un protocole auquel on adhérait, et si vous ne faisiez pas tourner le bon système d’exploitation aux deux bouts, vous aviez droit à la bidouille de registre, à l’OID bizarre et à la page de contournement.
Alors disons-le clairement, c’est mon blog après tout. Le Fisher-Price OS (Windows) n’a jamais été un pair véritable dans une pile de protocoles ouverte, parce que ce n’est pas ce à quoi il servait. Il cache la machine à la personne qui l’utilise, et c’est un objectif de conception, et une pile qu’on ne peut pas voir est une pile qu’on ne peut pas rendre interopérable. Si c’est le seul système d’exploitation que vous ayez jamais administré, les sections ci-dessus sur la lecture des compteurs du noyau et l’écoute sur le fil auront sonné comme une langue étrangère, et c’est cela l’écart — pas une préférence, un écart.
Rien de tout cela ne doit coûter quoi que ce soit au lecteur. Chaque diagnostic de ce billet s’exécute depuis n’importe quel Unix du réseau, pointé sur ce qui est cassé, et il se moque complètement de ce qui tourne en face. Et si ce système d’exploitation est le seul dont vous disposez, la partie diagnostic plus bas porte aussi ses outils à lui — la capture, les deux applets de commande et les codes d’erreur avec ce que chacun dit vraiment. Un tunnel cassé doit quand même être réparé lundi. Le remplaçant que je défends à la fin a ensuite un seul client, au comportement identique, sur chaque plateforme y compris celle-là — c’est la première fois en trente ans que c’est vrai d’un VPN.
Le relevé des dépréciations se lit comme une notice nécrologique
Mettez les contournements de côté et lisez simplement ce que les organismes de normalisation ont fait à cette famille au fil des ans. Pas une opinion. Des niveaux d’exigence, dans des RFC publiées.
| Quoi | Où cela en est aujourd’hui | Source |
|---|---|---|
| IKEv1 | Déprécié ; RFC 2407, 2408 et 2409 passées en Historic | RFC 9395, 202319 |
| DES dans ESP | MUST NOT | RFC 82218 |
| 3DES dans ESP | SHOULD NOT | RFC 82218 |
| HMAC-MD5-96 | MUST NOT | RFC 82218 |
| ESP avec AH | NOT RECOMMENDED | RFC 82218 |
| ESP en chiffrement seul | Montré non sûr, et cassé en pratique en 2007 | Degabriele et Paterson35 |
| IPsec sur un nœud IPv6 | Rétrogradé de MUST à SHOULD | RFC 6434, 201136 |
| PPTP | Jamais une norme ; Informational seulement | RFC 263730 |
L’avant-dernière ligne est celle que je mettrais sous les yeux de quiconque m’explique qu’IPsec va bien et que c’est le réseau le problème. IPv6 imposait IPsec à l’origine — c’était l’argument de sécurité, inscrit dans les exigences de nœud. En 2011 l’IETF a changé d’avis : « Previously, IPv6 mandated implementation of IPsec and recommended the key management approach of IKE. This document updates that recommendation by making support of the IPsec Architecture a SHOULD for all IPv6 nodes. »36
Même la famille d’adresses qui aurait rendu à IPsec tout ce que le NAT lui avait pris a cessé de l’exiger il y a quinze ans. Ce n’est pas le réseau qui lâche IPsec. Ce sont les gens qui ont conçu le réseau et qui ont décidé qu’il n’avait pas mérité l’obligation.
La complexité avait été signalée en 1999, par écrit
Rien de tout cela n’est de la sagesse d’après coup, et c’est ce qui rend la chose digne d’être écrite.
En 1999, Niels Ferguson et Bruce Schneier ont été chargés d’évaluer IPsec. Leur rapport est court, clair et mérite d’être lu en entier. Il s’ouvre sur « IPsec was a great disappointment to us. Given the quality of the people that worked on it and the time that was spent on it, we expected a much better result. »37 Il en nomme la cause : « Our main criticism of IPsec is its complexity. IPsec contains too many options and too much flexibility; there are often several ways of doing the same or similar things. This is a typical committee effect. »37
Et il formulait trois recommandations qui se lisent aujourd’hui comme une liste de choses arrivées quand même, vingt ans trop tard et par la manière dure :
- Supprimer le mode transport. « We therefore recommend that transport mode be eliminated. »37 Le mode transport est celui qu’utilise L2TP/IPsec, et celui auquel le NAT fait le plus de mal.
- Supprimer AH. « We conclude that eliminating transport mode allows the elimination of the AH protocol as well, without loss of functionality. »37 C’est le NAT qui l’a supprimé à la place, pour une plus mauvaise raison.
- Ne jamais autoriser le chiffrement sans authentification. Ils prévenaient que les administrateurs « will be quite likely to configure ESP for only encryption, believing that it provides security » — configureraient très probablement ESP en chiffrement seul, croyant que cela apporte la sécurité37.
Huit ans plus tard, ce dernier point a cessé d’être un avertissement. Degabriele et Paterson ont publié des attaques qui « break any RFC-compliant implementation of IPsec making use of encryption-only ESP » — cassent toute implémentation conforme utilisant ESP en chiffrement seul, à partir du seul texte chiffré, et qui n’exigent rien de plus que d’écouter le trafic et d’injecter des paquets35. La prédiction était au dossier public depuis huit ans et la norme autorisait toujours cette configuration.
Le verdict de ce rapport de 1999 est la phrase sur laquelle je reviens sans cesse : « We have found serious security weaknesses in all major components of IPsec. As always in security, there is no prize for getting 90% right; you have to get everything right. »37
Encore deux points, et j’en resterai là.
Logjam, 2015. L’équipe derrière cette étude a scanné un échantillon de 1 % d’IPv4 à la recherche d’IKE et a trouvé que 86,1 % des serveurs IKEv1 et 91,0 % des serveurs IKEv2 supportaient le groupe Oakley 2 de 1024 bits, et que 66,1 % des serveurs IKEv1 profilés le préféraient. Leur conclusion : un précalcul contre un deuxième groupe de 1024 bits « would allow decryption of traffic to 66% of IPsec VPNs », et les documents de renseignement publiés sur l’exploitation des VPN sont « consistent with having achieved such a break »38. L’agilité cryptographique, ce dont IPsec dispose le plus, est ce qui a permis à presque tout le monde de rester quinze ans sur le même groupe faible.
CVE-2016-1287. Un débordement de tampon dans le code IKEv1 et IKEv2 des Cisco ASA, atteignable en envoyant des paquets UDP forgés, offrant l’exécution de code à distance avant authentification39. Pensez à l’endroit où se trouve ce boîtier. C’est l’équipement que vous avez délibérément exposé à l’internet entier, faisant tourner le protocole le plus chargé d’options du parc, avec un réassembleur de fragments devant l’analyseur, et détenant les clés de tout ce qui est derrière. La complexité dont Ferguson et Schneier avertissaient n’est pas une abstraction. C’est de la surface d’attaque, sur la seule machine que vous ne pouvez mettre derrière rien.
Le diagnostiquer tant que vous l’exploitez encore
Vous ne pouvez pas tout éteindre cet après-midi, voici donc comment travailler dessus. C’est la méthode, dans l’ordre qui coûte le moins, avec ce que chaque résultat signifie réellement.
Regardez le fil d’abord, pas la console
Les deux consoles vous diront ce qu’elles croient. Le fil vous dit ce qui s’est passé. Une capture à la bordure, trente secondes, répond aux trois premières questions d’un coup :
tcpdump -ni eth0 'udp port 500 or udp port 4500 or ip proto 50 or ip6 proto 50'
- Rien du tout en sortie — le problème est en amont d’IPsec : routage, politique, ou un pare-feu local. Arrêtez de chercher du côté de la cryptographie.
- Sortant seulement, rien en retour — vos paquets partent et leurs réponses n’arrivent pas. Filtrage en transit, pair mort, ou bout distant qui rejette en silence.
- UDP 500 dans les deux sens mais 4500 n’apparaît jamais — la traversée de NAT n’a pas été négociée. Soit un bout l’a désactivée, soit la détection a échoué.
- Protocole 50 sur le fil alors qu’un bout est derrière un NAT — la négociation a décidé qu’il n’y avait pas de traducteur alors qu’il y en a un. Cela ne reviendra jamais.
Lire l’échec de l’échange de clés
IKEv2 vous dit pourquoi il a refusé, et les noms des notifications sont assez précis pour diagnostiquer à eux seuls. Il aide d’avoir d’abord la forme de tout l’échange sous les yeux, car chaque notification ci-dessous appartient à un barreau précis de celui-ci.
| Notification | Ce que cela veut vraiment dire | Où regarder |
|---|---|---|
NO_PROPOSAL_CHOSEN | Aucune des combinaisons chiffrement/intégrité/DH/PRF proposées ne convient au bout distant | Les deux listes de propositions ; attendez-vous à un algorithme déprécié d’un côté |
INVALID_KE_PAYLOAD | Groupe Diffie-Hellman discordant — vous avez proposé un groupe, il en veut un autre | Le groupe DH, en tête de la proposition |
AUTHENTICATION_FAILED | Clé, certificat ou identité incorrects — clé prépartagée discordante, certificat expiré, ou identifiant que le pair n’attend pas | L’identité, pas seulement le secret |
TS_UNACCEPTABLE | Les sélecteurs de trafic ne se recouvrent pas — vous avez demandé à protéger des sous-réseaux que le pair ne protège pas | La configuration des sélecteurs aux deux bouts |
INVALID_SPI | Un paquet est arrivé pour une association qui n’existe plus, en général après un redémarrage d’un seul côté | Si un bout a renouvelé ses clés ou redémarré |
Le guide Juniper sur la phase 2 dit la même chose du plus courant d’entre eux : « no proposal chosen » signifie que l’équipement « did not accept any of the IKE Phase 2 proposals that the peer sent », et le correctif est une proposition mutuellement acceptable, pas un redémarrage répété40.
Sur strongSwan, l’état de tout en une commande :
swanctl --list-sas # what is established, and what it negotiated
swanctl --log # the negotiation as it happens
Sur Cisco, show crypto ikev2 sa et show crypto ipsec sa, avec debug crypto ikev2 quand cela ne monte pas41. Sur Junos, show security ike security-associations et show security ipsec security-associations, avec la négociation dans show log kmd-logs42.
La traversée de NAT a-t-elle vraiment été négociée ?
C’est la vérification que les gens sautent, et elle explique une grande partie des « ça marche depuis le bureau et pas depuis la maison ».
Chaque bout envoie des empreintes des adresses et des ports qu’il croit en jeu. Si l’empreinte que le bout distant calcule à partir du paquet reçu ne correspond pas à celle que vous avez envoyée, c’est qu’il y a un traducteur entre vous, et les deux bouts passent sur UDP 4500. Si la détection échoue — un côté a désactivé la traversée, ou quelque chose au milieu abîme l’échange — les deux bouts continuent en ESP nu, qui ne survivra pas au traducteur.
Donc : voyez le port 4500 dans la capture, dans les deux sens, ou il n’y a aucune traversée. Ne croyez pas la console sur parole.
Vérifiez ensuite que le keepalive tourne vraiment et que son intervalle est inférieur au délai auquel votre opérateur fait vieillir les associations. La valeur par défaut est de vingt secondes6 ; le plancher de la norme pour les opérateurs de NAT est de deux minutes9 ; ce que fait votre opérateur précis, vous ne le voyez pas. Si le tunnel meurt après une inactivité et renaît au premier trafic, c’est ce cas à chaque fois.
Les compteurs du noyau que presque personne ne lit
Sous Linux, la couche de transformation tient un décompte complet des erreurs, et c’est le moyen le plus rapide de transformer « ça ne marche pas » en cause précise. Les compteurs sont documentés par le noyau lui-même43.
cat /proc/net/xfrm_stat # error counters, by cause
ip -s xfrm state # per-SA packet and byte counters
ip xfrm policy # what should be protected, and in which direction
Cela se lit mieux comme un chemin que comme une liste. Le paquet traverse cinq étapes, et chacune a son compteur :
Regardez lequel bouge pendant que la panne se produit :
| Compteur | Description du noyau | Ce que cela veut dire le jour J |
|---|---|---|
XfrmInNoStates | « No state is found i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong » | Leurs paquets arrivent pour une association que vous n’avez pas — en général un renouvellement ou un redémarrage d’un seul côté |
XfrmInStateSeqError | « Sequence error i.e. Sequence number is out of window » | Réordonnancement ou ennui de fenêtre anti-rejeu ; voir l’interaction QoS ci-dessus |
XfrmInStateProtoError | « Transformation protocol specific error e.g. SA key is wrong » | Les clés divergent — l’association a survécu à un renouvellement d’un seul côté |
XfrmInTmplMismatch | « No matching template for states e.g. Inbound SAs are correct but SP rule is wrong » | L’association est bonne et la politique ne l’est pas |
XfrmInNoPols | « No policy is found for states e.g. Inbound SAs are correct but no SP is found » | Du trafic protégé arrive alors que rien n’avait demandé sa protection |
XfrmOutPolBlock | « Policy discards » | C’est vous qui le jetez, exprès, dans la politique |
XfrmOutNoStates | « No state is found » | Du trafic a rencontré une politique sans association pour le porter — le tunnel n’est jamais monté |
XfrmInTmplMismatch et XfrmInNoPols sont les deux à reconnaître à l’œil, parce que tous deux veulent dire que la cryptographie va bien et que la politique ne va pas, c’est-à-dire l’inverse de là où tout le monde cherche en premier.
Il dit « monté » et rien ne bouge
Les deux bouts établis, aucun trafic. Lisez les compteurs par association dans les deux sens :
ip -s xfrm state
- Octets sortants en hausse, entrants à plat — vous chiffrez et vous envoyez, et rien ne revient. Soit votre ESP ne les atteint pas, soit le leur ne vous atteint pas. Demandez au bout distant son compteur sortant ; s’il monte aussi, les paquets meurent en transit et la question suivante est où, et c’est une question de TTL, pas de cryptographie.
- Les deux à plat — rien n’est présenté au tunnel. Routage ou politique, pas IPsec. En mode routé, vérifiez que la route pointe bien sur l’interface du tunnel ; en mode politique, vérifiez les sélecteurs.
- Les deux en hausse, applications toujours cassées — ce n’est pas le tunnel. Allez voir ce qu’il y a de l’autre côté.
Le conseil de Juniper pour ce cas suit le même instinct dans leur langage : si seul le compteur de paquets sortants de la session monte, confirmez auprès du pair que le trafic est bien reçu44.
Les petites choses marchent, les grandes bloquent
La MTU. C’est toujours la MTU. Le test prend dix secondes :
ping -M do -s 1400 10.0.0.1 # inside the tunnel, do-not-fragment set
ping -M do -s 1300 10.0.0.1 # step down until it succeeds
L’endroit où cela commence à passer vous donne la taille réellement utilisable. Faites ensuite en sorte que TCP le découvre lui-même, en bornant la taille de segment annoncée au chemin plutôt qu’en espérant que chaque erreur ICMP survive au voyage :
nft add rule inet filter forward tcp flags syn tcp option maxseg size set rt mtu
Et corrigez aussi la cause, qui est presque toujours une règle ICMP trop large à une bordure quelque part. Jetez l’écho si vous voulez. J’ai défendu ailleurs qu’il le mérite. Mais gardez Fragmentation Needed et Packet Too Big. Ce sont le mécanisme, pas une politesse.
Il tombe à intervalle régulier
Chronométrez les pannes. L’intervalle nomme la cause à lui seul.
- Une période fixe correspondant à une durée de vie configurée — renouvellement de clés. L’association expire et la négociation de remplacement échoue ou entre en concurrence. Vérifiez les durées de vie des deux bouts ; des valeurs différentes sont normales et sans problème, mais une durée de vie dure d’un côté plus courte que la durée souple de l’autre produit exactement cela.
- Après une période sans trafic, de retour au premier usage — une association NAT a expiré. Intervalle du keepalive, ou absence de keepalive.
- La détection de pair mort coupe alors que la liaison va bien — les sondes se perdent au lieu que le pair soit mort, souvent parce que les sondes sont le seul trafic et que l’association est déjà partie.
Le deuxième utilisateur éjecte le premier
Deux pairs atteignent le concentrateur depuis une seule adresse et s’authentifient sous la même identité. La passerelle a le choix entre garder l’ancienne association et la remplacer, et une valeur par défaut répandue est de remplacer. La deuxième connexion gagne donc et la première meurt en silence.
Donnez à chaque pair une identité réellement unique plutôt qu’une adresse ou un nom partagé, et réglez la passerelle pour qu’elle conserve plusieurs associations depuis une même adresse au lieu d’en supposer une par pair. Puis testez-le de la seule façon qui compte : deux clients, une adresse, en même temps. Si votre recette n’a jamais eu deux utilisateurs derrière un NAT, vous n’avez pas testé le cas dans lequel se trouvent la plupart de vos utilisateurs.
Les mêmes pannes, sur le Fisher-Price OS (Windows)
Chaque vérification ci-dessus s’exécute depuis une machine Unix, et si vous en avez une sur ce réseau, prenez-la : elle vous dira la vérité plus vite et elle se moque de ce qui tourne en face. Mais beaucoup de lecteurs ont un client qui ne se connecte pas, un système d’exploitation qui leur cache la machine par choix de conception, et rien d’autre à regarder. Voici donc la même méthode, dans le même ordre, avec les outils que ce système livre réellement.
Regardez le fil. Il n’y a pas de tcpdump, mais il y a une capture. Lancez-la en mode élevé, reproduisez la panne, arrêtez-la :
netsh wfp capture start cab=on file=ipsec
netsh wfp capture stop
Cela écrit un .cab. Dedans se trouve la trace de ce que la plateforme de filtrage et l’échange de clés ont vraiment fait pendant la panne, ce qui est davantage que ce que l’une ou l’autre console veut bien admettre. Pour un regard en direct plutôt qu’une archive, la même famille de commandes écrit sur la console avec file=- : netsh wfp show state « Displays the current state of WFP and IPsec », et netsh wfp show ikeevents « Displays recent Internet Key Exchange (IKE) epoch events matching the specified parameters », filtré sur un seul pair45.
netsh wfp show state file=-
netsh wfp show ikeevents remoteaddr=203.0.113.5 file=-
show ikeevents est ici ce qui ressemble le plus au journal d’échange que toute autre pile écrit sans qu’on le lui demande. Bon à savoir qu’il existe. Sinon l’interface vous tend un nombre à trois chiffres et rien d’autre, et vous diagnostiquez un échange de clés à l’aveugle.
Lisez les associations, et lisez les deux. Les équivalents de ip -s xfrm state et de swanctl --list-sas sont deux applets de commande, et la séparation entre les deux est tout le diagnostic :
Get-NetIPsecMainModeSA
Get-NetIPsecQuickModeSA
Le mode principal est l’échange de clés. Le mode rapide porte les paquets. Microsoft énonce la relation clairement : « There is only one main mode SA between a pair of computers, but there can be many quick mode SAs »46. Un mode principal présent avec un mode rapide vide est donc la même panne qu’une IKE_SA montée sans CHILD_SA dessous, et cela veut dire la même chose : les deux bouts se sont mis d’accord sur la façon de parler, puis ne se sont pas mis d’accord sur ce qu’il faut protéger. Regardez les sélecteurs de trafic, pas les algorithmes.
Lisez les journaux, aux deux endroits où ils se cachent. Les échecs au niveau de la connexion atterrissent dans le journal Application sous la source RasClient, et la note de Microsoft sur leur lecture est la partie utile : « All error messages return the error code at the end of the message »47. Ce nombre est le diagnostic, et la section suivante dit ce que les nombres veulent dire. Les décisions de stratégie et de filtrage atterrissent ailleurs, sous Journaux des applications et des services, dans les canaux du Pare-feu Windows avec fonctions avancées de sécurité. Deux journaux, deux équipes, une panne.
Collectez proprement quand vous devez escalader. Le paquet pris en charge est TSS — TSS.ps1 -Scenario NET_VPN sur le client, TSS.ps1 -Scenario NET_RAS sur le serveur, démarré avant de reproduire la panne et arrêté après48. Apprenez-le avant qu’on vous le demande.
Quand il reste sur Connexion et finit par expirer
C’est la panne qui remplit les tickets, et le mot dans l’erreur est un mensonge. Commencez par nommer le code. Le code est précis même quand le message ne sert à rien.
| Code | Nom dans raserror.h | Ce qui s’est vraiment passé |
|---|---|---|
| 809 | ERROR_VPN_TIMEOUT | Rien n’est revenu du tout. Cause indiquée par Microsoft : « the UDP 500 or 4500 ports on the VPN server or firewall are blocked »47 — mais blocked recouvre trois choses différentes et une seule est une règle d’interdiction. Le plus souvent, le 4500 n’a jamais été envoyé, faute de traversée de NAT négociée, ou l’assistant qui le portait a été désactivé. Lisez la suite avant de demander une modification du pare-feu |
| 789 | ERROR_OAKLEY_GENERAL_PROCESSING | « The L2TP connection attempt failed because the security layer encountered a processing error during initial negotiations » — les identifiants ou les certificats, pas le réseau |
| 718 | ERROR_PPP_TIMEOUT | La partie IPsec a marché. PPP dans le tunnel L2TP n’a pas eu de réponse |
| 828 | ERROR_IDLE_TIMEOUT | « The connection was terminated because of idle timeout » — un réglage côté serveur, délibéré |
| 930 | ERROR_AUTH_SERVER_TIMEOUT | RADIUS n’a pas répondu à temps. Rien à voir avec IPsec |
| 638 | ERROR_REQUEST_TIMEOUT | Le générique. Traitez-le comme une absence d’information et allez sur le fil |
Chacun vient de la propre liste d’erreurs de Microsoft49. Relisez maintenant 809. Il s’appelle ERROR_VPN_TIMEOUT, et la cause documentée est un port bloqué. Le client n’expire pas parce que l’autre bout est lent. Il expire parce que l’autre bout est muet, et le silence est le seul mode de panne qu’un protocole sans ports et sans poignée de main visible sait signaler.
Méfiez-vous quand même du mot blocked, car il porte plus qu’il ne peut. Trois choses différentes le portent, et une seule est une règle d’interdiction.
Personne n’a jamais envoyé de 4500. La traversée de NAT n’a pas été négociée, donc le client a continué à parler ESP, et ESP ne donne rien à réécrire à un traducteur. Le réglage par défaut de cette plateforme suffit à l’expliquer : sans la valeur de registre, elle ne forme aucune association NAT-T vers un serveur derrière un traducteur31. Le 4500 n’est donc pas bloqué. Il n’a jamais été essayé.
L’assistant qui masquait cela a été désactivé. Les pare-feu et les box portent des assistants par protocole — l’IPsec passthrough sur le matériel grand public, et toute la famille des passerelles de niveau applicatif derrière — qui lisent un protocole que le NAT ne sait pas traiter et ouvrent le chemin de retour pour lui. Sous Linux, la forme automatique de tout cela a été désactivée par défaut au noyau 4.7 « for security reasons », la consigne depuis étant d’attacher un assistant délibérément par une règle ou pas du tout ; parmi les assistants couverts figure celui de PPTP50.
Et les désactiver était le bon choix. Un assistant est un morceau de votre pare-feu qui analyse une charge utile puis perce un trou d’après ce qu’il a lu. NAT Slipstreaming est la facture : un navigateur qui visite une page, du trafic façonné pour que l’assistant SIP ou H.323 du routeur le lise comme un appel, et un trou percé à travers le NAT — dans la version de 2021, vers n’importe quelle adresse interne, pas seulement la machine qui a chargé la page51. Désactiver les assistants ferme cela. Cela arrête aussi votre IPsec. Les deux sont vrais en même temps, et le second n’est pas un argument pour défaire le premier.
Ce qui est encore ce billet en miniature. Le protocole ne marchait que parce que des boîtiers au milieu lisaient du trafic qui ne les regardait pas et ouvraient des trous en son nom, et le secteur a passé la dernière décennie à décider, avec raison, d’arrêter de faire ça.
Travaillez donc les causes dans cet ordre, le moins cher d’abord.
Un : rien ne revient. Capturez au client, ou demandez à la passerelle. Si UDP 500 part et que rien ne revient, c’est du filtrage ou de la joignabilité, et aucun compteur ne réglera ça. Si 500 passe dans les deux sens et que 4500 n’apparaît jamais, la traversée de NAT n’a pas été négociée. Et si l’un des deux bouts est derrière un traducteur, vous revoilà à la valeur de registre plus haut dans ce billet : AssumeUDPEncapsulationContextOnSendRule, 1 ou 2, sur les deux machines, puis un redémarrage31. Sans elle, le client refuse par conception et le signale comme une expiration.
Deux : la réponse est trop grosse pour arriver. Celle-là coûte des après-midi entiers. L’authentification par certificat rend le deuxième échange gros, parce qu’il porte une chaîne, et un gros échange se fragmente. Les fragments sont jetés par les mêmes boîtiers intermédiaires que tout le reste de ce billet, le client retransmet dans le même trou, puis il abandonne et dit expiration. Le signe est à lui seul un diagnostic : une clé partagée se connecte et un certificat non. Ce n’est pas une panne de certificat. C’est une panne de taille, parce que l’échange avec clé partagée est assez petit pour passer. La fragmentation IKEv2 normalisée existe précisément pour ça23, et strongSwan consigne quand cette plateforme l’a eue : « IKEv2 fragmentation is supported since the v1803 release of Windows 10 and Windows Server »33. Plus ancien que ça, ou une passerelle avec la fragmentation désactivée, et vous comptez sur un chemin qui portera un datagramme UDP fragmenté. Beaucoup ne le feront pas.
Trois : il se connecte, puis tombe à intervalle régulier. Chronométrez. S’il meurt après une période d’inactivité fixe, c’est 828 et c’est de la configuration, pas une panne — -IdleDisconnectSeconds sur le serveur, avec -SALifeTimeSeconds, -MMSALifeTimeSeconds et -SADataSizeForRenegotiationKilobytes comme les trois autres horloges capables de terminer une session52. La dernière la termine au volume plutôt qu’au temps, et c’est pourquoi une session peut mourir régulièrement pendant une grosse copie de fichiers et jamais pendant une journée de courrier. Et si elle meurt au renouvellement de clés avec le client derrière un NAT, c’est la panne d’interopérabilité documentée plus haut : le client refuse un renouvellement lancé par le serveur avec l’erreur Microsoft 13863, et la réponse côté passerelle est d’arrêter de le lancer et de laisser faire le client33.
Quatre : ce n’est pas du tout le tunnel. 930, c’est RADIUS. 812, c’est une méthode d’authentification que le serveur n’a pas acceptée47. 13801 et 13806, ce sont des certificats — mauvaise utilisation étendue de clé, expiré, racine absente, ou un nom de serveur qui ne correspond pas au sujet du certificat47. La négociation du tunnel allait bien dans les quatre cas, et si vous passez l’après-midi sur les algorithmes vous n’en trouverez aucun.
Voilà ce qu’il faut retenir de ce tableau. Six codes d’erreur, cinq avec le mot timeout dans le nom, et pas un seul n’est une expiration en fait. Ce sont un port bloqué, un fragment perdu, une décision de stratégie et un serveur RADIUS, tous portant le même mot, parce que la couche qui signale la panne ne voit pas assez de ce qui s’est passé pour dire quelque chose de plus utile. Allonger le compteur n’en règle aucun, et allonger le compteur est ce que l’interface vous invite à faire.
Quoi faire tourner à la place
Je ne vais pas faire croire que le remplaçant est exotique. Il est dans le noyau et il y est depuis des années.
WireGuard, c’est un port UDP, une clé par pair, aucune négociation de chiffrement et aucune agilité de protocole. La position de son auteur là-dessus est délibérée et affichée : « It intentionally lacks cipher and protocol agility. If holes are found in the underlying primitives, all endpoints will be required to update. As shown by the continuing torrent of SSL/TLS vulnerabilities, cipher agility increases complexity monumentally. »53 Cette seule décision supprime d’un coup NO_PROPOSAL_CHOSEN, INVALID_KE_PAYLOAD, les attaques par rétrogradation et le constat de Logjam, parce qu’il n’y a rien à négocier et rien à rétrograder.
Il est honnête sur la contrepartie, et moi aussi : pas d’agilité veut dire que le jour où une primitive tombe, vous mettez à jour toute la flotte au lieu de changer une ligne de configuration. C’est un coût d’exploitation réel et c’est le bon à payer.
Le reste répond presque point par point à la liste ci-dessus. Avoir un port UDP veut dire que NAT et CGNAT le traitent comme n’importe quel flux, et qu’ECMP et l’agrégation de liens le hachent comme n’importe quel flux. L’itinérance est intégrée plutôt que boulonnée — un paquet authentifié venant d’une nouvelle adresse déplace le point d’extrémité du pair, donc un téléphone qui passe du Wi-Fi au mobile ne renégocie rien. Il ne répond rien à un paquet non authentifié, donc un scanner trouve un port fermé là où IPsec lui offrirait un concentrateur avec qui discuter. Et il tient en moins de 4 000 lignes de code53, face à une pile qui a besoin d’un document entier pour lister ses seize incompatibilités avec un seul intermédiaire.
Côté performances, il a simplement mesuré plus vite que les deux configurations IPsec auxquelles il a été comparé : 1 011 Mbit/s contre 881 et 825, avec une latence plus faible53. Je ne mettrais pas un protocole à la retraite sur la foi d’un banc d’essai. Je le mentionne parce que le dernier argument qui reste en faveur d’IPsec est en général la performance, et il est faux lui aussi.
Pour amener une personne à une application — plutôt qu’un réseau à un réseau — la réponse n’est pas un tunnel du tout. L’identité à la porte d’entrée, l’application publiée à travers elle, rien de routé. J’ai construit cela avec Proxmox et Cloudflare Access dans VDI Zero Trust sans la facture cloud, et le point pertinent ici est qu’un utilisateur qui a besoin de trois applications internes n’a pas besoin d’une route vers tout votre parc.
Et disons la part non dite au sujet du matériel. Oui, il existe des cartes réseau et des ASIC avec déchargement ESP, et c’est un vrai argument pour IPsec sur du matériel précis à des débits précis. C’est un argument sur du silicium qu’on vous a déjà vendu, pas sur la justesse du protocole. De ce fait il se périme, et vite. PPTP a survécu exactement de la même manière, exactement aussi longtemps que la case à cocher a existé.
Le mettre à la retraite correctement
Une mise à la retraite est un plan avec des dates, pas un sentiment. Voici celui que je signerais.
Arrêtez les nouveaux déploiements IPsec maintenant. Pas « privilégier les alternatives ». Arrêtez. Chaque nouveau tunnel est un tunnel que quelqu’un devra migrer plus tard, et ceux qu’on construit aujourd’hui tourneront encore en 2035 si personne ne dit non cette semaine.
Traitez l’accès distant en premier, parce que c’est là que chaque défaillance de ce billet frappe le plus fort : le CGNAT, l’adresse partagée, les keepalives, le deuxième utilisateur dans la même maison, le trou noir de MTU sur un réseau d’hôtel quelconque. C’est aussi le plus facile à déplacer, parce que les postes sont gérés et que le changement tient dans un client.
Puis le site à site sur l’internet public, les mêmes problèmes avec moins de points d’extrémité et une fenêtre de maintenance.
Gardez pour la fin les tunnels dont vous ne possédez pas les deux bouts : un partenaire, un régulateur, le service géré d’un opérateur. Ceux-là bougent quand le contrat bouge, et la manière de les faire bouger est au point suivant.
Cessez d’acheter du matériel dont le seul tunnel est IPsec. Mettez-le dans l’appel d’offres. Une ligne qui demande un tunnel moderne, fondé sur un port, capable d’itinérance, est une ligne à laquelle un constructeur répond ou ne répond pas, et c’est ainsi que l’argument du parc installé finit par perdre. Cet argument est le seul qui maintienne tout cela en vie, et il ne se bat que par les achats.
Écrivez quels tunnels restent et pourquoi, et mettez une date sur chacun. Un protocole dont personne ne s’est occupé pendant dix ans, c’est ainsi que PPTP est arrivé en 2026. Un inventaire daté fait la différence entre mettre quelque chose à la retraite et simplement ne pas l’aimer.
Si vous le déployez encore, pouvez-vous vous dire professionnel ?
C’est une vraie question, et je vais y répondre honnêtement, parce que c’est celle vers laquelle le reste de ce billet marche.
Tout dépend de si vous savez. Et le savoir ne vous arrive pas tout seul. Faire en sorte de savoir, c’est le métier.
Si vous montez cette année un nouvel accès distant IPsec et que vous ne pouvez pas dire, sans rien aller chercher, pourquoi ESP n’a pas de ports, ce qu’une ligne résidentielle derrière un NAT d’opérateur lui fait, pourquoi un réseau NAT64 ne le portera pas du tout, ou à quoi sert vraiment cet octet unique toutes les vingt secondes — alors non. Pas là-dessus, pas encore. Vous ne choisissez pas un protocole. Vous répétez une forme, parce que la précédente ressemblait à ça et que personne dans la pièce n’a demandé pourquoi — vous compris. Le manquement n’est pas la lacune. Tout le monde en a. Le manquement, c’est de construire par-dessus une lacune que vous n’êtes jamais allé combler. De ce fait, la personne qui en hérite en 2035 récupère une décennie de tickets qui étaient tous évitables le jour où vous l’avez dessiné.
Et je vais lui donner son vrai nom, parce que la version polie circule depuis vingt ans et n’a rien changé. Quelqu’un qui déploie un protocole qu’il ne sait pas expliquer n’est pas un ingénieur. C’est un suiveur. Il lit des fiches — l’architecture de référence de l’éditeur, la dernière demande de changement, un schéma que quelqu’un a tracé en 2014 et que personne n’a rouvert depuis — et il les lit avec une vraie conviction, et il n’y a aucune compréhension derrière la prestation. Vu de l’extérieur, cela ressemble exactement à de la compétence. Cela continue de ressembler exactement à de la compétence jusqu’à la première panne que les fiches ne couvrent pas, et à partir de cette seconde-là c’est la seule chose qui compte dans la pièce.
Les fiches sont aussi la raison pour laquelle ce protocole est encore là. Personne ne s’est levé devant un tableau blanc en 2026 pour défendre IPsec sur le fond. Il a été redéployé parce qu’il était sur la fiche, et la fiche a été écrite par un éditeur dont l’intérêt est que vous continuiez à acheter le boîtier qui le termine. C’est ainsi qu’une chose survit vingt ans à sa propre notice nécrologique : non pas en étant défendue, mais en n’ayant jamais eu à se justifier une seule fois devant quelqu’un capable de faire la différence.
Et cela se dit. À voix haute, dans la pièce, sur le moment — pas marmonné dans le couloir après coup. Quand quelqu’un met le mot professionnel à côté de son nom, le mot arrive avec une invitation à être interrogé, et interroger n’est pas impoli. Être interrogé et avoir une réponse, c’est toute la différence entre le mot et une carte de visite.
Cela compte surtout quand vous payez pour cela. Un cabinet de conseil, un MSP, la branche services professionnels d’un éditeur, l’intégrateur d’un accord-cadre : ce que vous achetez, c’est du jugement, et le jugement est la seule chose que vous ne pouvez pas inspecter à la livraison. Alors inspectez-le avant. Demandez pourquoi ce protocole plutôt qu’un autre. Demandez ce qu’il devient sur une ligne derrière un NAT d’opérateur, sur un réseau mobile IPv6 seul, sur un chemin qui jette silencieusement les fragments. Demandez lesquels ils ont personnellement rencontrés et ce qu’ils en ont fait. Vous saurez en moins de deux minutes si on vous dit quelque chose ou si on vous fait la lecture, et deux minutes coûtent nettement moins cher que quatre ans de tickets. Et si la réponse tient sur des fiches et que vous signez quand même, c’est aussi une décision : elle vient simplement de devenir la vôtre et non la leur.
Si vous pouvez dire tout cela et que vous le déployez quand même parce qu’un régulateur le nomme par protocole, parce que le boîtier du partenaire ne termine rien d’autre, ou parce que le remplaçant est au budget de l’année prochaine et que ceci doit marcher en mars — alors oui, évidemment, et vous faites le travail correctement. Les contraintes sont réelles, et j’ai contourné pire. Ce qui sépare les deux n’est pas le protocole sur le schéma. C’est d’avoir écrit pourquoi, et qu’il y ait une date à côté.
La position indéfendable est celle du milieu. En savoir assez pour être mal à l’aise, et le construire quand même parce que personne ne vous a obligé à le justifier. Pas de l’ingénierie. De l’habitude, avec un numéro de changement dessus — et c’est exactement comme ça que L2TP s’est retrouvé sur une fiche technique imprimée cette année.
Posez-vous donc la question avant la clôture de l’appel d’offres, pas après. Professionnel n’est pas un mot sur les protocoles que vous connaissez. C’est un mot sur votre capacité à défendre celui que vous avez choisi, à voix haute, devant quelqu’un qui en connaît les modes de panne. Si vous le pouvez, déployez ce que les contraintes exigent et dormez bien. Sinon, vous venez de trouver ce qu’il faut aller lire ce soir, et ce n’est pas une insulte. Tout le monde a été suiveur un jour, sans exception, moi compris. Ce qui n’est pas défendable, c’est de choisir de le rester et d’appeler cela une carrière.
Une bonne idée a le droit d’être terminée
Je veux être juste envers IPsec, parce qu’il le mérite.
C’était le bon instinct. La sécurité a sa place bas dans la pile, là où tout en hérite et où aucune application n’a besoin qu’on lui fasse confiance pour bien faire. Lier l’association à l’adresse n’était pas une erreur en 1995 — l’adresse était la machine, et bâtir là-dessus était juste. Ceux qui l’ont écrit étaient des gens sérieux face à un vrai problème, et c’est l’article sur WireGuard, de tous les documents, qui le dit le mieux : la stratification d’IPsec est saine, tout est à sa place, jusqu’à la perfection académique53.
Puis le sol a bougé. Non pas parce qu’IPsec a mal fait quoi que ce soit, mais parce que ce secteur a décidé que les adresses étaient un coût à gérer plutôt qu’une chose que chaque machine reçoit, et a bâti vingt-cinq ans de traduction pour éviter l’alternative. On a discrètement retiré à IPsec ses fondations et, plutôt que de l’admettre, on a calé dessous. Encapsulation UDP. Puis keepalives. Puis encapsulation TCP pour les réseaux qui bloquent l’UDP. Puis encore un en-tête UDP pour qu’un routeur trouve quelque chose à hacher. Chaque correctif raisonnable pris isolément ; leur empilement est un protocole tenu debout par des gens payés pour le tenir debout.
C’est la partie qui vaut la colère, et elle ne parle pas vraiment d’IPsec. Notre secteur est très bon pour entretenir les choses et très mauvais pour y mettre fin. L’entretien est facturable, budgété, doté en personnel et sans risque. La mise à la retraite est une décision que quelqu’un doit signer, avec son nom dessus, et sans récompense immédiate. Alors PPTP a vécu quatorze ans après la preuve de son inutilité, L2TP est encore livré sur des boîtiers vendus cette année, et IKEv1 a continué de négocier des tunnels une décennie après son passage en Historic. Non pas parce que quelqu’un les défendait. Parce que personne n’a jamais été tenu de les tuer.
Il n’y a pas de prix pour avoir 90 % de juste. Ferguson et Schneier l’ont écrit d’IPsec en 1999, et ce qui s’est passé depuis, ce sont trente ans pendant lesquels le secteur s’est trompé sur les 10 % restants d’une manière nouvelle à chaque fois en appelant le rustinage une solution.
Une bonne idée a le droit d’être terminée. Savoir quand cesser d’entretenir quelque chose est une compétence, et c’est celle où ce métier est le plus mauvais. Il faut bien que quelqu’un soit celui qui dit qu’un protocole a fait son temps, écrit la date et assume les conséquences d’avoir été celui qui l’a dit. Sinon nous enverrons encore en 2040 un paquet d’un octet toutes les vingt secondes, pour garder au chaud une table dans un boîtier qui ne nous appartient pas, sur un réseau qui nous a pris nos adresses et nous les a facturées.
RFC 4301 — Security Architecture for the Internet Protocol, décembre 2005. Définit l’association de sécurité et le triplet qui sert à la retrouver : adresse de destination, protocole de sécurité et SPI. ↩︎ ↩︎
RFC 4302 — IP Authentication Header, décembre 2005. Le contrôle d’intégrité d’AH couvre les champs immuables de l’en-tête IP, adresses source et destination comprises. ↩︎ ↩︎
RFC 9329 — TCP Encapsulation of Internet Key Exchange Protocol (IKE) and IPsec Packets, novembre 2022, qui remplace la RFC 8229. Existe parce que des intermédiaires sur les réseaux publics bloquent l’UDP. ↩︎ ↩︎ ↩︎
RFC 3715 — IPsec-Network Address Translation (NAT) Compatibility Requirements, mars 2004. Seize incompatibilités énumérées, dont : « Since the AH header incorporates the IP source and destination addresses in the keyed message integrity check, NAT or reverse NAT devices making changes to address fields will invalidate the message integrity check. » et « Where IP addresses are used as identifiers in Internet Key Exchange Protocol (IKE) Phase 1 or Phase 2, modification of the IP source or destination addresses by NATs or reverse NATs will result in a mismatch between the identifiers and the addresses in the IP header. » ↩︎ ↩︎ ↩︎
Cisco — Configuring IPsec NAT-Traversal, Security Configuration Guide, Cisco IOS XE 17.15.x (Catalyst 9300 Switches). « If PAT found a legislative IP address and port, it would drop the Encapsulating Security Payload (ESP) packet » ; l’en-tête UDP et un marqueur non-IKE de huit octets sont insérés entre l’en-tête IP externe et l’en-tête ESP ; la liste de restrictions mentionne des règles statiques pour les ports 500 et 4500, l’absence de prise en charge des politiques de NAT dynamique, l’absence d’IPv6, et le fait qu’IPsec et NAT ne peuvent pas fonctionner tous les deux sur le même équipement. ↩︎ ↩︎ ↩︎ ↩︎
RFC 3948 — UDP Encapsulation of IPsec ESP Packets, janvier 2005, avec la négociation dans la RFC 3947. Définit le keepalive comme « a one-octet-long payload with the value 0xFF », envoyé « if no other packet to the peer has been sent in M seconds. M is a locally configurable parameter with a default value of 20 seconds. », et exige la mise à zéro de la somme de contrôle UDP : « If the protocol header after the ESP header is a UDP header, set the checksum field to zero in the UDP header. » Microsoft, Cisco, F-Secure, Nortel et SafeNet figurent tous sur les listes d’auteurs des RFC 3947 et 3948. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
Juniper — Route-Based and Policy-Based VPNs with NAT-T, Junos OS IPsec VPN User Guide. « NAT-T encapsulates both IKE and ESP traffic within UDP with port 4500 used as both the source and destination port » ; « Because NAT devices age out stale UDP translations, keepalive messages are required between the peers » ; et sur SRX5400, SRX5600 et SRX5800 : « the total number of tunnels from a given public translated IP cannot exceed 1000 tunnels. » ↩︎ ↩︎ ↩︎
RFC 8221 — Cryptographic Algorithm Implementation Requirements and Usage Guidance for ESP and AH, octobre 2017. ENCR_DES MUST NOT, ENCR_3DES SHOULD NOT, AUTH_HMAC_MD5_96 MUST NOT ; ESP combiné à AH est NOT RECOMMENDED. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
RFC 4787 — Network Address Translation (NAT) Behavioral Requirements for Unicast UDP, janvier 2007. REQ-5 : « A NAT UDP mapping timer MUST NOT expire in less than two minutes », avec « a default value of five minutes or more for the NAT UDP mapping timer is RECOMMENDED ». ↩︎ ↩︎
RFC 6146 — Stateful NAT64 : Network Address and Protocol Translation from IPv6 Clients to IPv4 Servers, avril 2011. « The current specification only defines how stateful NAT64 translates unicast packets carrying TCP, UDP, and ICMP traffic. Multicast packets and other protocols, including the Stream Control Transmission Protocol (SCTP), the Datagram Congestion Control Protocol (DCCP), and IPsec, are out of the scope of this specification. » Les paquets portant autre chose « SHOULD be discarded ». ↩︎ ↩︎
RFC 6877 — 464XLAT : Combination of Stateful and Stateless Translation, avril 2013. Donne à un équipement IPv6 seul une pile IPv4 locale pour que fonctionne le trafic que NAT64 ne peut pas transporter. ↩︎
IETF — draft-xu-ipsecme-esp-in-udp-lb, Encapsulating IPsec ESP in UDP for Load-balancing. « Although the ESP SPI field within the IPsec packets can be used as the load-balancing key, but it cannot be used by legacy switches and routers » ; « Many cloud service providers allow customers to establish multiple IPsec VPN tunnels in parallel to enable ECMP and increase aggregate bandwidth. However, this approach is not ideal, as each tunnel typically requires its own public IP address, leading to higher public IP consumption and increased operational overhead. » ↩︎ ↩︎
Cisco — Resolve IPv4 Fragmentation, MTU, MSS, and PMTUD Issues with GRE and IPsec. La référence maintenue de longue date sur le surcoût des tunnels, la découverte de MTU de chemin et ce qui casse quand les erreurs ICMP ne reviennent pas. ↩︎
Cisco — Troubleshoot IPsec Anti-Replay Check Failures. « Certain QoS features, such as Low Latency Queueing (LLQ), could cause IPsec packet delivery to become out-of-order and dropped by the receiving endpoint due to a replay check failure. » Fenêtre par défaut de 64 paquets ; 1024 sur les plateformes plus récentes ; l’autre remède est l’usage de plusieurs espaces de numéros de séquence par association. ↩︎ ↩︎ ↩︎
RFC 2661 — Layer Two Tunneling Protocol « L2TP », août 1999. Un protocole de tunnel pour PPP, sans confidentialité propre au niveau du paquet ; sa section sécurité renvoie à IPsec. ↩︎
Moxie Marlinspike et David Hulton — Divide and Conquer : Cracking MS-CHAPv2 with a 100 % Success Rate, 2012 ; outil sur github.com/moxie0/chapcrack. La sécurité de MS-CHAPv2 se réduit à une seule opération DES quelle que soit la longueur du mot de passe ; compte rendu de l’époque dans The Register. Leur conclusion était de considérer le trafic PPTP comme non chiffré. ↩︎ ↩︎
Apple — If you see a « VPN Using PPTP May Not Be Secure » alert. PPTP a été retiré du client intégré de macOS Sierra et d’iOS 10 en 2016. ↩︎
RFC 4303 — IP Encapsulating Security Payload (ESP), décembre 2005. Protocole IP 50 ; l’en-tête ESP porte le SPI et le numéro de séquence, et n’a aucun champ de port. ↩︎
RFC 9395 — Deprecation of the Internet Key Exchange Version 1 (IKEv1) Protocol and Obsolete Cryptographic Algorithms, avril 2023. « Internet Key Exchange Version 1 (IKEv1) has been deprecated, and RFCs 2407, 2408, and 2409 have been moved to Historic status. » ↩︎ ↩︎
RFC 7296 — Internet Key Exchange Protocol Version 2 (IKEv2), octobre 2014. L’échange de clés actuel, et la source des noms de notification du tableau de diagnostic. ↩︎ ↩︎
RFC 3173 — IP Payload Compression Protocol (IPComp), septembre 2001. Son propre numéro de protocole IP et ses propres associations, négociées à côté d’ESP. ↩︎
RFC 2367 — PF_KEY Key Management API, Version 2, juillet 1998. L’interface noyau par laquelle un démon de clés installe les associations. ↩︎
RFC 7383 — IKEv2 Message Fragmentation, novembre 2014. « This document describes a way to avoid IP fragmentation of large Internet Key Exchange Protocol version 2 (IKEv2) messages. » ↩︎ ↩︎
RFC 4555 — IKEv2 Mobility and Multihoming Protocol (MOBIKE), juin 2006. Permet à un tunnel établi de survivre à un changement d’adresse. ↩︎
RFC 3706 — A Traffic-Based Method of Detecting Dead Internet Key Exchange (IKE) Peers, février 2004. ↩︎
draft-beaulieu-ike-xauth — Extended Authentication within IKE (XAUTH). Dernière révision 02, octobre 2001, statut Expired, « Expired & archived », jamais publié en RFC. Le projet consigne qu’il était proposé en Informational parce que « the IPSRA working group will not accept any protocol which extends ISAKMP or IKE, and the IPsec working group refuses to accept any protocols that deal with remote access. » Mode-Config a connu le même sort. ↩︎ ↩︎ ↩︎ ↩︎
RFC 3193 — Securing L2TP using IPsec, novembre 2001. Coécrite chez Microsoft. ↩︎
RFC 2332 — NBMA Next Hop Resolution Protocol (NHRP), avril 1998. La pièce qui permet aux branches DMVPN de se trouver. ↩︎
RFC 6407 — The Group Domain of Interpretation, octobre 2011. Les clés de groupe, telles qu’utilisées par GETVPN. ↩︎
RFC 2637 — Point-to-Point Tunneling Protocol (PPTP), juillet 1999. Catégorie : Informational. Un protocole de constructeur mis par écrit, jamais une norme. ↩︎ ↩︎ ↩︎
Microsoft — Configure L2TP/IPsec server behind NAT-T device, KB 926179, révisé pour la dernière fois le 12 février 2026. « By default, Windows Vista and Windows Server 2008 don’t support Internet Protocol security (IPsec) network address translation (NAT) Traversal (NAT-T) security associations to servers that are located behind a NAT device » ; la valeur DWORD
AssumeUDPEncapsulationContextOnSendRulesousHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgentaccepte 0 (défaut, impossible), 1 (serveur derrière un NAT) ou 2 (les deux bouts derrière un NAT), et la machine doit redémarrer. Également : « If you must use IPsec for communication, use public IP addresses for all servers that you can connect to from the Internet. » ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎strongSwan — Windows Certificate Requirements. Le certificat de la passerelle a besoin de l’EKU serverAuth, OID 1.3.6.1.5.5.7.3.1, et de l’EKU IP Security IKE Intermediate, OID 1.3.6.1.5.5.8.2.2. ↩︎
strongSwan — Windows Clients. Documente l’ajout du DWORD
NegotiateDH2048_AES256sousRasman\Parameterspour obtenir AES-256-CBC et MODP-2048 ; le contournement du renouvellement de clés pour les clients derrière un NAT (rekey_time = 0sur la passerelle, le client initie) ; et le fait que le client Windows « does not currently support IKE redirection (RFC 5685) and multiple authentication rounds (RFC 4739) ». Également : « IKEv2 fragmentation is supported since the v1803 release of Windows 10 and Windows Server », et les clients derrière un NAT refusent un renouvellement de CHILD_SA lancé par le serveur avec l’erreur Microsoft 13863. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎Microsoft — DirectAccess et Remote Access Always On VPN migration overview. DirectAccess est déprécié et sera retiré d’une version future de Windows Server ; les clients sont dirigés vers Always On VPN. ↩︎
Jean Paul Degabriele et Kenneth G. Paterson — Attacking the IPsec Standards in Encryption-only Configurations, IEEE Symposium on Security and Privacy, 2007. Des attaques qui « break any RFC-compliant implementation of IPsec making use of encryption-only ESP », à partir du seul texte chiffré, n’exigeant que d’écouter le trafic et d’injecter des paquets. ↩︎ ↩︎
RFC 6434 — IPv6 Node Requirements, décembre 2011. « Previously, IPv6 mandated implementation of IPsec and recommended the key management approach of IKE. This document updates that recommendation by making support of the IPsec Architecture [RFC4301] a SHOULD for all IPv6 nodes. » ↩︎ ↩︎
Niels Ferguson et Bruce Schneier — A Cryptographic Evaluation of IPsec, Counterpane Internet Security, 1999. « IPsec was a great disappointment to us » ; « Our main criticism of IPsec is its complexity » ; « We therefore recommend that transport mode be eliminated » ; « We conclude that eliminating transport mode allows the elimination of the AH protocol as well, without loss of functionality » ; et « We have found serious security weaknesses in all major components of IPsec. As always in security, there is no prize for getting 90% right; you have to get everything right. » ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
David Adrian et al. — Imperfect Forward Secrecy : How Diffie-Hellman Fails in Practice, ACM CCS 2015. Un précalcul pour un deuxième groupe de 1024 bits « would allow decryption of traffic to 66% of IPsec VPNs » ; 86,1 % des serveurs IKEv1 scannés et 91,0 % des IKEv2 supportaient le groupe Oakley 2, et 66,1 % des serveurs IKEv1 profilés le préféraient. ↩︎
CVE-2016-1287 et l’avis de Cisco, Cisco ASA Software IKEv1 and IKEv2 Buffer Overflow Vulnerability. Exécution de code à distance avant authentification, atteinte par des paquets UDP forgés vers le service IKE. ↩︎
Juniper — How to Analyze IKE Phase 2 VPN Status Messages. « No proposal chosen » signifie que l’équipement « did not accept any of the IKE Phase 2 proposals that the peer sent ». ↩︎
Cisco — Understand and Use Debug Commands to Troubleshoot IPsec et Troubleshoot Common L2L and Remote Access IPsec VPN Issues. ↩︎
Juniper — Troubleshoot a VPN Tunnel That is Down. ↩︎
Noyau Linux — XFRM proc counters. Les descriptions du tableau proviennent de la documentation du noyau elle-même. ↩︎
Juniper — Troubleshoot a VPN That Is Up But Not Passing Traffic. « If only the
pktscounter in the out direction of the session is incrementing, then validate with the VPN peer that the traffic is being received. » ↩︎Microsoft —
netsh wfp, Windows Commands.netsh wfp capture start« Starts a capture session for network events processed by WFP » et écritwfpdiag.cabpar défaut ;netsh wfp show state« Displays the current state of WFP and IPsec » ;netsh wfp show ikeevents« Displays recent Internet Key Exchange (IKE) epoch events matching the specified parameters » et accepte un filtreremoteaddr=. Avecfile=-, chaqueshowécrit sur la console au lieu de produire du XML. ↩︎Microsoft —
Get-NetIPsecQuickModeSA, module NetSecurity. « There is only one main mode SA between a pair of computers, but there can be many quick mode SAs », et leur surveillance « can provide information about which peers are currently connected to this computer, and which protection suite is protecting the data exchanged between them ». ↩︎Microsoft — Troubleshoot Always On VPN, dernière révision le 12 février 2026. Sur la lecture des journaux client : « look for events labeled RasClient. All error messages return the error code at the end of the message. » Cause de l’erreur 809 : « You can encounter this issue when the UDP 500 or 4500 ports on the VPN server or firewall are blocked. » L’erreur 812 est un désaccord de méthode d’authentification entre la stratégie du serveur et le profil du client. Les quatre causes listées pour 13801 sont un certificat machine sans Server Authentication dans l’utilisation étendue de clé, un certificat machine RAS expiré, un client sans le certificat racine, et un client dont le « VPN server name doesn’t match the subjectName value on the server certificate » ; 13806 est « IKE can’t find a valid machine certificate ». ↩︎ ↩︎ ↩︎ ↩︎
Microsoft — Guidance for troubleshooting Remote Access (VPN and AOVPN). La collecte prise en charge est TSS, exécutée en mode élevé :
TSS.ps1 -Scenario NET_VPNsur le client etTSS.ps1 -Scenario NET_RASsur le serveur, en reproduisant la panne entre le démarrage et l’arrêt, les traces étant écrites dansC:\MS_DATA. ↩︎Microsoft — Routing and Remote Access Error Codes, les codes définis dans
raserror.h. 638ERROR_REQUEST_TIMEOUT; 718ERROR_PPP_TIMEOUT; 789ERROR_OAKLEY_GENERAL_PROCESSING, « The L2TP connection attempt failed because the security layer encountered a processing error during initial negotiations with the remote computer » ; 809ERROR_VPN_TIMEOUT, « The network connection between your computer and the VPN server could not be established because the remote server is not responding » ; 828ERROR_IDLE_TIMEOUT, « The connection was terminated because of idle timeout » ; 930ERROR_AUTH_SERVER_TIMEOUT, « The authentication server did not respond to authentication requests in a timely fashion ». ↩︎firewalld — Automatic Helper Assignment. « With kernel 4.7 and up the automatic helper assignment in kernel has been turned off by default », piloté par le sysctl sous
/proc/sys/net/netfilter/nf_conntrack_helper, et « for the secure use of iptables and connection tracking helpers it is recommended to turn AutomaticHelpers off ». Le message du noyau sur ce changement donne la raison et le remplacement : l’affectation automatique « has been turned off for security reasons », utilisez plutôt la cibleCT. Les assistants couverts comprennentftp,irc,sip,h323,tftp,snmpetpptp. ↩︎Samy Kamkar — NAT Slipstreaming, v1 du 31 octobre 2020, v2 du 26 janvier 2021 avec Ben Seri et Gregory Vishnipolsky d’Armis. L’attaque abuse du « Application Level Gateway (ALG) connection tracking mechanism built into NATs, routers, and firewalls » pour « bypass victim NAT and connect directly back to any port on any machine on the network, exposing previously protected/hidden services and systems ». La v1 utilisait la passerelle SIP sur le port 5060, la v2 H.323 sur 1720, ce qui permettait de viser le trou sur n’importe quel hôte interne et non plus seulement la machine ayant chargé la page. ↩︎
Microsoft —
Set-VpnServerConfiguration, module RemoteAccess.-IdleDisconnectSeconds« Specifies the time, in seconds, after which an idle connection is terminated » ;-SALifeTimeSecondset-MMSALifeTimeSecondsfixent les durées de vie du mode rapide et du mode principal ;-SADataSizeForRenegotiationKilobytes« Specifies the number of kilobytes that are allowed to transfer using a security association (SA), after which the SA will be renegotiated ». ↩︎Jason A. Donenfeld — WireGuard : Next Generation Kernel Network Tunnel, NDSS 2017. « It intentionally lacks cipher and protocol agility. If holes are found in the underlying primitives, all endpoints will be required to update. As shown by the continuing torrent of SSL/TLS vulnerabilities, cipher agility increases complexity monumentally » ; « implemented for Linux in less than 4,000 lines of code » ; « it is important to stress, however, that the layering of IPsec is correct and sound; everything is in the right place with IPsec, to academic perfection ». Mesures : 1 011 Mbit/s contre 881 et 825 pour deux suites de chiffrement IPsec, et 0,403 ms de ping contre 0,501 et 0,508. ↩︎ ↩︎ ↩︎ ↩︎