Routes fractionnées L2TP sur Mac : pourquoi une adresse d'hôte ne fonctionne pas
setadditionalroutes veut des paires réseau et masque, remplace toute la liste et exige le nom littéral du service. Vérifiez la table avant d'accuser la passerelle.
Le VPN se connecte, la barre de menus l'affiche, et un hôte interne expire toujours. Dans cette situation, trois causes sont possibles, et celle qui s'applique dépend de la façon dont le tunnel a été configuré. Soit la commande de route a utilisé une adresse d'hôte là où une adresse réseau était requise, soit le profil lui-même installe une route par défaut qui avale la décision, soit le client est un tunnel PPP qui a besoin d'un hook plutôt que d'une clé de profil. Vérifiez-les dans cet ordre, car la première est la moins coûteuse à écarter.
La destination est une adresse réseau, le masque décrit le préfixe
networksetup -setadditionalroutes prend des triplets de destination, de masque de sous-réseau et de passerelle. L'appel qui envoie un sous-réseau interne par le tunnel ressemble à ceci :
sudo networksetup -setadditionalroutes "VPN (L2TP)" 192.168.1.0 255.255.255.0 10.2.0.0
Notez ce qu'est la destination : l'adresse réseau, pas l'adresse du serveur que vous cherchez à joindre. Dans le cas qui a produit cet article, la commande identique avec 192.168.1.20 à cette position n'a rien fait d'utile, et son remplacement par 192.168.1.0 a fonctionné immédiatement. Même masque, même passerelle, un numéro différent. C'est toute la panne en miniature.
La raison est arithmétique, pas politique. Une adresse d'hôte associée à un masque /24 ne décrit pas 192.168.1.0/24 ; elle décrit quelque chose que la table de routage ne peut pas retenir utilement, donc l'entrée est rejetée ou ignorée et le tunnel finit par transporter moins que prévu.
Lorsque vous voulez exactement un hôte, utilisez l'adresse d'hôte avec un masque 255.255.255.255. C'est dans les paires mixtes que cela se gâte, pas dans l'usage d'une adresse d'hôte en soi. Un /32 construit à partir d'une adresse est une route légitime ; un /24 construit à partir d'une adresse est une erreur.
L'appel remplace la liste, et le nom est littéral
Deux comportements surprennent au premier essai. La commande définit la liste complète des routes supplémentaires au lieu d'ajouter, donc un appel qui ajoute un préfixe retire silencieusement les autres qui étaient là avant. Construisez l'ensemble en une seule invocation.
Le nom du service n'est pas non plus l'étiquette que vous avez inventée. Lisez-le depuis l'outil et copiez-le exactement, suffixe de type compris :
networksetup -listallnetworkservices
Un nom qui diffère d'un caractère ne produit aucune erreur digne d'être lue et aucune route. Copier-coller est la bonne technique ici, pas la ressaisie de mémoire.
Quand le profil revendique la route par défaut
Les routes fractionnées perdent contre une route par défaut pour toute destination qu'elles ne couvrent pas explicitement, et un profil L2TP configuré en tunnel complet installe exactement cela. Si le profil dit que tout passe par le tunnel, la liste des routes supplémentaires change très peu. Votre entrée n'est pas fausse ; elle est simplement sans objet pour les destinations qu'elle ne nomme jamais. Le contrôle de cela se trouve généralement dans le réglage du profil pour l'envoi de tout le trafic, pas dans une commande de route.
Décidez quel modèle vous voulez vraiment avant de modifier d'autres entrées. Le tunnel complet avec exceptions est une configuration différente du tunnel fractionné avec des préfixes précis, et mélanger les deux produit une table que personne ne peut prédire.
Si l'organisation exige un tunnel complet, cessez d'essayer de le fractionner localement et portez l'exigence à qui détient la politique. Une route ajoutée localement qui la contredit sera de toute façon supprimée par la prochaine mise à jour du profil.
Les tunnels PPP ont besoin d'un hook plutôt que d'une clé
Pour les tunnels basés sur PPP, defaultroute est la clé de profil qui crée une route par défaut ; supprimez-la et le client cesse de revendiquer chaque destination. Les routes sont ensuite ajoutées après l'apparition de l'interface, généralement depuis /etc/ppp/ip-up :
#!/bin/sh
/sbin/route add -net 192.168.1.0 -interface ppp0
Gardez le script détenu par root et exécutable, et ajoutez une garde sur le nom de l'interface quand plus d'un profil de tunnel existe sur la machine. Un hook qui s'exécute pour chaque lien PPP et suppose un seul nom de périphérique est un petit bug à la longue vie.
Vérifiez le fractionnement avec trois requêtes
Capturez la table pendant que vous êtes connecté et notez quelle interface sert le tunnel. Vérifiez ensuite la destination précise plutôt que de faire confiance au code de sortie de la commande qui l'a créée. Un code de sortie indique si l'outil a accepté les arguments, pas si le trafic emprunte le chemin voulu.
Terminez par trois requêtes qui prouvent le fractionnement : un hôte interne par adresse, un nom interne via le résolveur interne, et un site public qui devrait encore utiliser la connexion locale. Si le site public passe désormais aussi par le tunnel, le fractionnement n'a jamais eu lieu, quoi que la liste des routes semble dire.
Reconnectez-vous une fois de plus et répétez la requête interne, car les routes ajoutées à la main peuvent survivre à l'interface qui les a rendues valides et transformer silencieusement le trafic en trou noir après la chute du tunnel.