L2TP : signal fatal 15, NO_PROPOSAL_CHOSEN et modp1024 manquant
Le signal fatal 15 accompagné de NO_PROPOSAL_CHOSEN est un désaccord de phase 2 : soit le démon n’offre plus modp1024, soit une valeur de phase 1 se trouve dans le champ de phase 2.
Votre connexion se bloque, le client quitte et la dernière ligne à l’écran est death_handler: Fatal signal 15 received. Cette ligne signale une interruption, pas une cause. Une ligne plus haut dans le journal IPsec se trouve presque toujours NO_PROPOSAL_CHOSEN, et le couple pointe vers la phase 2 de l’échange, où les pairs comparent leurs choix de chiffrement et de hachage et s’arrêtent quand ils n’en partagent aucun. Les identifiants n’ont pas encore été envoyés à ce stade, donc retaper le mot de passe ne peut pas changer le résultat.
Deux choses vident généralement cette intersection sur un client Linux. Le démon local n’implémente peut-être plus le groupe Diffie-Hellman demandé par le profil, ou le profil porte une proposition de phase 1 dans un champ de phase 2. Les deux laissent une trace dans le journal, et ni l’une ni l’autre n’est un problème de compte.
Ce que disent réellement les deux messages
IKE négocie par passes. La phase 1 construit un canal protégé et choisit ses propres algorithmes ; la phase 2, la SA enfant, transporte le trafic sous un ensemble distinct. NO_PROPOSAL_CHOSEN est la notification que renvoie un répondeur quand aucune des combinaisons proposées n’est acceptable, et elle apparaît sous la forme [ HASH N(NO_PROP) ] dans un échange INFORMATIONAL.
Le signal 15 est un autre événement : quelque chose a demandé au processus local de s’arrêter et le gestionnaire l’a journalisé. Quand les deux lignes apparaissent ensemble, l’ordre est causal, d’abord le rejet puis l’extinction.
Lisez la négociation avant de toucher aux identifiants
Augmentez le niveau de journalisation là où le démon écrit, puis reconnectez-vous en surveillant la sortie. Sur un hôte NetworkManager, le greffon L2TP transmet ce niveau au backend, et les messages atterrissent dans le journal ou dans le fichier syslog classique selon la distribution. L’un ou l’autre montrera l’échange : journalctl -f -u NetworkManager | grep -Ei 'pluto|charon|no_prop|proposal' ou tail -f /var/log/syslog | grep -Ei 'pluto|charon|ike'.
Une ligne nommant pluto vient de libreswan, charon de strongSwan, et les deux décrivent la même condition avec des mots différents. La forme qui vaut la peine d’être cherchée est celle qui nomme le groupe manquant, par exemple algorithm 'modp1024' is not supported, parce qu’elle transforme une panne vague en panne précise.
Où est passé modp1024
Le groupe 2 de Diffie-Hellman est assez faible pour que plusieurs distributions aient cessé de le compiler dans libreswan à partir de la 3.30. Un profil écrit il y a des années, ou repris d’un guide de passerelle qui ne liste que aes128-sha1-modp1024, demande alors au démon local quelque chose qu’il ne peut pas exécuter du tout. Les versions plus récentes de NetworkManager-l2tp rendent ce résultat plus probable : depuis la 1.2.16, elles remplacent l’ensemble par des propositions de style Windows 10 et iOS et abandonnent modp1024 dès que libreswan est détecté. L’extrémité distante est souvent innocente et propose toujours exactement le groupe que vous avez configuré.
C’est cette asymétrie qui fait paraître la panne aléatoire. Un client plus ancien se connecte, le même profil sur un portable à jour ne le fait pas, et la configuration du serveur n’a jamais bougé. Les dégâts viennent de la dérive des versions.
Deux réparations à portée différente
La réparation bon marché consiste à cesser de coder les algorithmes en dur. Videz les deux champs de proposition dans l’éditeur et laissez le greffon choisir un ensemble que l’extrémité distante accepte ; si la passerelle prend en charge les groupes modernes, la négociation aboutit sans travail supplémentaire.
La seconde réparation garde une passerelle ancienne joignable en installant strongSwan, dont les paquets implémentent encore le groupe 2 sur la plupart des distributions. C’est un changement de démon, donc cela a un coût : vérifiez si d’autres tunnels de l’hôte dépendent de la configuration de libreswan avant de le retirer, et attendez-vous à des refus SELinux entre NetworkManager et le greffon strongSwan sous Fedora. Ces refus apparaissent dans le journal d’audit et non dans la trace IKE, ce qui explique qu’un tunnel puisse sembler cassé juste après une installation réussie. L’ordre qui fonctionne est d’abord dnf install strongswan, puis rpm -e libreswan.
Des chaînes de propositions qui correspondent, et les pièges autour
Quand les champs doivent être remplis à la main, la phase 1 et la phase 2 prennent des valeurs différentes. Un couple connu pour fonctionner face à une extrémité de style Meraki propose aes128-sha1-modp1024 en phase 1 avec 3des-sha1-modp1024 derrière, les deux fermés par un point d’exclamation qui rend l’ensemble strict, de sorte que seules ces propositions sont jamais envoyées.
La phase 2 se réduit ensuite à aes128-sha1 et 3des-sha1 avec le même marqueur strict et sans aucun suffixe Diffie-Hellman. Une ligne de phase 2 portant -modp1024 est une valeur de phase 1 dans le mauvais champ, et le répondeur la rejette à chaque tentative. Copiez cette ligne dans un second profil et le second profil échoue de la même manière, et c’est ainsi qu’une faute de frappe devient un incident à l’échelle de la flotte.
D’autres pannes portent la même fenêtre sans être des désaccords de proposition. Sous KDE, le type L2TP peut être listé avec le greffon installé alors que chaque connexion meurt aussitôt, parce que l’éditeur de connexions et les assistants d’exécution sont livrés en paquets séparés. Les hôtes sans écran peuvent réutiliser un profil d’un bureau qui fonctionne : copiez-le depuis /etc/NetworkManager/system-connections/, mettez le mode à 600, puis exécutez nmcli con reload. Montez-le avec nmcli con up id work-l2tp, car la forme nue veut un UUID, et supprimez toute entrée ifname obsolète, sinon le gestionnaire répond Could not find source connection alors que tout le reste est correct.
Une clé pré-partagée peut être stockée en clair ou sous la forme 0s suivi de base64 ; les deux formes fonctionnent, mais la valeur doit correspondre à la passerelle octet pour octet, y compris les espaces de fin que vous avez copiés avec elle.