Un sous-réseau privé dans le tunnel et tout le reste par votre chemin habituel : c'est une petite demande avec beaucoup de façons de se tromper. Ce qui décide du résultat n'est pas la case nommée split tunneling, mais l'endroit où la décision s'applique : la table de routage du client lui-même, une route poussée par le serveur ou une politique que les deux extrémités négocient. Choisissez la mauvaise couche et vous obtenez soit un tunnel complet que vous ne vouliez pas, soit une route vers un tunnel que l'autre côté refuse d'accepter. J'applique un test à trois conditions avant d'ouvrir la moindre configuration, puis je choisis l'un des mécanismes ci-dessous.

Trois conditions qui fixent la conception

D'abord, il vous faut le préfixe et le masque exacts du propriétaire du réseau. Le réseau 10.x n'est pas un préfixe ; 10.20.0.0/16 en est un. Vérifiez qu'il ne chevauche pas votre LAN domestique, un pont Docker ou un autre VPN que vous exploitez, car un chevauchement rend la route ambiguë et le noyau choisit l'entrée que vous ne vouliez pas.

Ensuite, qui répond au trafic de retour. Router un paquet dans le tunnel ne le mène qu'au serveur VPN. Si le sous-réseau se trouve derrière un autre routeur qui n'a pas de route de retour vers votre pool de clients, le serveur doit masquer le trafic, ou ce routeur doit apprendre votre pool. Aucune route côté client ne corrige un chemin de retour manquant.

Troisièmement, le point d'application. Certains clients installent une route et le système d'exploitation fait le reste. D'autres négocient une politique, et une politique que la passerelle n'accepte pas ne produit aucun tunnel : les paquets sont abandonnés sans erreur évidente. Déterminez lequel des deux vous concerne avant d'écrire quoi que ce soit.

WireGuard : AllowedIPs est la table de routage

Sur le client, AllowedIPs énumère les destinations autorisées à entrer dans le tunnel, et wg-quick transforme chaque entrée en route ordinaire. La moitié client de cette tâche tient donc en une ligne.

[Peer]
PublicKey = ...
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16

Comparez maintenant l'entrée du serveur pour ce même client. Elle décrit ce que le serveur enverra au client, c'est-à-dire normalement l'adresse de tunnel du client, et non le sous-réseau privé.

[Peer]
PublicKey = ...
AllowedIPs = 10.99.0.2/32

Intervertir ces deux entrées est l'erreur que je vois le plus souvent. Placer 10.20.0.0/16 dans la section peer du serveur affirme que tout le sous-réseau se trouve derrière ce client, ce qui est une prétention site à site et non une autorisation. Les paquets qui ne correspondent à l'AllowedIPs d'aucun peer sont abandonnés en silence, si bien qu'une entrée erronée ressemble exactement à un problème de pare-feu.

Si vous gérez les routes vous-même, placez Table = off sous [Interface] et ajoutez la route souhaitée. Rien n'est alors ajouté automatiquement, la route appartient donc à ce qui monte l'interface.

OpenVPN : poussez la route, puis assurez-vous qu'elle arrive

Sur un serveur normal, le changement tient en une directive dans la configuration du serveur, à côté du pool de clients.

push "route 10.20.0.0 255.255.0.0"

Le client l'ajoute lorsqu'il se connecte. Le mode de défaillance apparaît lorsque le même profil pousse aussi redirect-gateway, ou lorsque quelqu'un a déjà ajouté route-nopull : le premier transforme la session en tunnel complet, le second écarte toutes les routes poussées, y compris la vôtre.

Un client qui a besoin d'un comportement étroit face à un serveur en tunnel complet ne doit ignorer que les parties dont il ne veut pas. Sur OpenVPN 2.4 et ultérieur, pull-filter existe précisément pour cela.

pull-filter ignore "redirect-gateway"
route 10.20.0.0 255.255.0.0

Gardez les familles d'adresses séparées : une route IPv4 poussée ne fait rien pour un service interne qui résout en IPv6, et ce service échoue par le tunnel alors que tout le reste semble correct.

Lorsque le sous-réseau privé n'est pas sur le serveur VPN mais derrière un autre client, il faut prévenir le serveur. Ajoutez un fichier par client via client-config-dir contenant iroute 10.20.0.0 255.255.0.0, plus la route correspondante pour que les autres clients apprennent le chemin. Sans iroute, le serveur n'a aucune raison d'envoyer ce préfixe par ce tunnel précis.

IPsec : les sélecteurs de trafic doivent s'accorder

Avec IPsec, il n'y a pas de route à pousser. Les deux extrémités négocient quelles adresses vivent dans le tunnel, et le trafic hors des sélecteurs convenus n'est ni chiffré ni envoyé par celui-ci. Sur un client strongSwan, les sélecteurs sont explicites.

leftsubnet=192.168.1.0/24
rightsubnet=10.20.0.0/16

Si la passerelle est configurée avec 0.0.0.0/0 des deux côtés, le rétrécissement IKEv2 réduit généralement la SA enfant à l'intersection des deux propositions, ce qui est le résultat voulu. Certaines passerelles rejettent plutôt une proposition qui ne correspond pas à leurs sélecteurs configurés, et le journal montre alors une SA enfant en échec plutôt qu'un grief de routage. Quand cela arrive, le changement revient à la passerelle, car une route côté client ne peut pas créer un tunnel pour un sélecteur que l'autre côté n'acceptera pas.

Sous Windows, le client intégré cache la même décision derrière deux paramètres. La division du tunnel doit être active, et le préfixe doit être enregistré sur le profil.

Set-VpnConnection -Name Office -SplitTunneling $true
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.20.0.0/16

C'est l'enregistrement du préfixe qui le fait survivre à une reconnexion, ce qu'une route ajoutée à la main ne fait pas.

Gardez le point d'extrémité et le DNS hors de la décision

Le point d'extrémité du VPN doit rester joignable sans le tunnel, sinon le tunnel s'effondre sur lui-même. Quand seul 10.20.0.0/16 est routé, c'est automatique, puisque le point d'extrémité est une adresse publique. Sur un profil en tunnel complet, ce n'est pas le cas, et le client a besoin de une route d'hôte explicite vers le point d'extrémité avant que le tunnel ne monte.

Le DNS est une seconde décision qu'un push de route ne prend pas pour vous. Les noms internes se résolvent généralement par un résolveur que seul le réseau privé peut atteindre. Si le serveur pousse un serveur DNS, chaque nom passe par lui ; s'il ne le fait pas, les noms internes échouent ou se résolvent publiquement en quelque chose que vous ne vouliez pas. Le DNS divisé garde un domaine de recherche sur le résolveur interne, mais cela dépend du support du client, alors traitez-le comme une tâche à part et non comme un effet de bord du routage.

Vérifiez, redémarrez, puis vérifiez à nouveau

Trois sondes couvrent la question du routage. Demandez au noyau où irait une adresse distante, récupérez quelque chose depuis l'intérieur du sous-réseau, puis confirmez qu'une requête publique ordinaire sort toujours par votre connexion normale.

ip route get 10.20.5.7
curl -sS http://10.20.5.7/health
curl -sS https://ifconfig.me

La première ligne nomme une interface. Si elle nomme votre interface physique, la route n'est jamais arrivée. Sous Windows, Find-NetRoute -RemoteIPAddress 10.20.5.7 répond à la même question, et la dernière sonde devrait toujours montrer votre adresse habituelle et non celle du serveur VPN.

Redémarrez ensuite. Les routes ajoutées à la main disparaissent, tandis que les routes du profil, d'une configuration poussée ou de AllowedIPs reviennent. Si l'accès étroit fonctionne avant le redémarrage et échoue après, la faute tient à la façon dont le tunnel démarre, non à la route elle-même.

Avant de le déclarer terminé, confirmez quatre choses : le préfixe vient du propriétaire du réseau et ne chevauche rien de local, le chemin de retour existe ou une règle de masquage le remplace, le mécanisme que vous avez configuré est celui qui applique le routage sur votre plateforme, et les mêmes sondes passent après un redémarrage propre. Les notes de transfert de strongSwan valent la lecture si le chemin de retour est la partie qui n'arrête pas d'échouer.

Articles similaires