Router uniquement un service web local hors du VPN selon le port
Décidez si une règle de port source peut faire sortir un service de l’hôte par le WAN pendant que le reste de l’hôte continue d’utiliser le VPN, et à quel prix.
Un service de l’hôte doit répondre à internet par le lien montant physique pendant que tout le reste de la machine continue d’utiliser le tunnel. Trois conditions décident si le routage basé sur des politiques peut porter cette charge, et chacune est peu coûteuse à vérifier avant d’écrire une règle. Le service doit se terminer sur cet hôte et non derrière un DNAT ou un port redirigé, les règles propres du VPN doivent autoriser l’exception, et vous devez faire correspondre la réponse plutôt que la requête. Si l’une des trois échoue, les commandes ci-dessous se chargent proprement tout en ne faisant rien d’utile.
Vérifiez les trois conditions avant d’écrire une règle
Un conteneur qui publie un port par DNAT, ou un serveur derrière une redirection de port, produit des paquets qui ne prennent pas naissance sur cet hôte. Ces paquets sont transférés, donc une règle fondée sur l’entrée locale de l’hôte ne les voit jamais et le trafic continue de prendre la route par défaut. Confirmez où le service s’exécute réellement avant de continuer, car c’est la condition que les gens se trompent le plus souvent.
La deuxième condition relève de la politique et non de la mécanique. Toute route qui contourne le tunnel est une exception à la raison d’être du tunnel, et sur un hôte géré cette décision appartient à qui possède la politique, pas à la personne qui débogue un délai d’attente.
Faites correspondre la réponse, pas le port de destination du client
La réponse d’un serveur qui écoute sur TCP 443 quitte l’hôte avec le port source 443. Un navigateur du même hôte qui se connecte à un site HTTPS distant envoie un port source éphémère et un port de destination 443. Les deux sont du trafic sur le port 443 et un seul devrait prendre la table WAN, c’est pourquoi une correspondance sur le port de destination attraperait la mauvaise moitié.
La direction de la réponse est ce que vous pouvez distinguer. Faites correspondre le port source, limitez la règle aux paquets générés localement, et la règle couvre les réponses du service lui-même sans toucher aux requêtes du navigateur.
Construisez une table de retour complète avant que la règle ne pointe vers elle
Une table vide signifie aucune route, ce qui ressemble à un service cassé plutôt qu’à une politique cassée. Remplissez-la d’abord, avec un numéro de table et une priorité que rien d’autre sur l’hôte ne revendique :
ip -4 route add table 100 192.0.2.0/24 dev eth0
ip -4 route add table 100 default via 192.0.2.1 dev eth0
ip -4 rule add priority 1000 iif lo ipproto tcp sport 443 lookup 100
Lisez les numéros sur l’hôte en direct au lieu de les copier. ip -4 rule show vous indique quelles priorités sont prises, et ajouter une règle sur une priorité qui existe déjà change silencieusement l’ordre de deux règles qui, séparément, semblent correctes.
Deux sélecteurs font le vrai travail ici. iif lo est la façon dont le noyau signale les paquets que l’hôte a lui-même générés, si bien que la règle ne peut pas capturer accidentellement le trafic transféré venu de l’extérieur. ipproto tcp sport 443 la resserre sur un transport et un port, ce qui est aussi étroit que l’exigence le permet. Retirez le sélecteur de protocole et la règle attrape aussi UDP 443, un autre service au comportement différent.
Gardez les réponses privées à l’intérieur du tunnel
Si le même écouteur répond aussi à des clients du côté privé, une route WAN par défaut qui attrape tout dans la table 100 tentera de renvoyer ces réponses par le lien montant. Ajoutez les préfixes privés qui ne doivent pas suivre la route WAN par défaut, ou laissez-les retomber sur la règle de politique suivante :
ip -4 route add table 100 throw 10.90.0.0/24
Une route throw termine la recherche dans cette table et rend le paquet à la liste des règles, afin que la politique VPN qui suit ait sa chance. Elle ne route rien elle-même dans le tunnel, et si aucune règle ultérieure n’a de route correspondante, le paquet échoue quand même ; vérifiez la politique suivante plutôt que de supposer que le throw est une correction.
Le filtrage du chemin inverse et les règles du pare-feu de l’hôte s’appliquent toujours à la requête qui arrive. Regardez leurs verdicts réels avant d’assouplir la validation, car une exception de routage ne fait pas que rp_filter accepte un chemin de retour qu’il juge impossible.
Testez TCP, puis QUIC, puis un redémarrage
Ouvrez une connexion depuis un client externe autorisé et une depuis le côté privé, puis inspectez la recherche de réponse avec les adresses et les ports réels. Si la réponse externe prend la table 100 et que la privée ne le fait pas, la politique fait ce que vous avez demandé.
HTTP/3 est servi sur UDP et ne sera pas mis en correspondance par une règle TCP, donc un écouteur QUIC a besoin de son propre sélecteur, sinon il continuera d’utiliser le tunnel pendant qu’HTTPS fonctionne. Persistez les règles que vous retenez avec le composant qui possède l’interface, et confirmez-les après une reconnexion ou un renouvellement DHCP. Quand un gestionnaire concurrent supprime une route d’exécution après un redémarrage, c’est un problème de propriété à corriger à la source, pas une raison d’ajouter des règles NAT plus larges par-dessus.