Bloquez une plage de destination pour chaque pool de clients VPN
Une seule règle nftables peut refuser un préfixe de destination à un pool VPN autorisé sans toucher au trafic propre de la passerelle. Soignez le hook et la position.
Une règle suffit pour tenir un pool VPN autorisé à l’écart d’une plage de destination sans perturber le reste de ce que fait la passerelle. La règle elle-même est courte ; ce qui décide si elle fonctionne, c’est le hook dans lequel elle vit et sa position dans la chaîne. Se tromper sur ces deux points donne un pare-feu qui paraît correct et se comporte de façon incohérente. Partez de ce que fait le paquet lorsque la règle le voit.
Ce que la règle compare réellement
La règle compare trois choses à la fois : une interface d’entrée, un préfixe source et un préfixe de destination. Les trois doivent être vraies avant que le drop s’applique, et c’est ce qui la garde étroite. La lire comme une seule expression est plus simple que la lire comme trois politiques séparées.
La correspondance d’interface est ce qui distingue le trafic client transféré des connexions propres à la passerelle. Sans elle, une règle qui nommerait seulement le pool source affecterait aussi les paquets que la passerelle génère elle-même depuis cette adresse, si cela lui arrive. Le préfixe source limite la politique aux clients autorisés, et le préfixe de destination la limite à une plage. Lisez la règle comme une intersection et non comme une liste.
Notez les trois valeurs avant de modifier quoi que ce soit : le nom de l’interface du tunnel, le pool que le serveur distribue et le préfixe que vous voulez refuser. Une faute de frappe dans l’une d’elles produit une règle qui s’analyse proprement et ne protège rien. Conservez ces trois valeurs dans le journal des modifications, à côté de la règle.
Le hook décide à qui la règle s’applique
Une chaîne netfilter est rattachée à un hook, et le hook décide quels paquets la chaîne voit réellement. Le hook forward voit le trafic routé à travers la passerelle, c’est-à-dire le trafic de client à destination. Tout le reste de la chaîne vise un autre public.
Le hook input voit le trafic adressé à la passerelle elle-même, donc une règle placée là régit l’accès à ses propres services et non le transit. Le hook output voit le trafic que la passerelle origine, soit l’inverse de ce dont une politique de pool de clients a besoin. Les noms de chaîne sont des étiquettes arbitraires choisies par celui qui a écrit le jeu de règles, donc ne déduisez pas le hook du nom. Vérifiez où la chaîne est rattachée avant de supposer ce qu’elle peut comparer.
| Hook | Traffic it sees | Right for this policy |
|---|---|---|
| input | Addressed to the gateway | No, that is the host's own services |
| forward | Routed through the gateway | Yes, for client-to-destination traffic |
| output | Generated by the gateway | No, that is the opposite direction |
Lire le rattachement est une vérification d’une ligne qui empêche une règle d’atterrir dans une chaîne qui ne voit jamais le paquet.
Placez la règle avant l’accept large
Les règles sont évaluées dans l’ordre et le premier verdict l’emporte. Un accept large plus haut dans la chaîne termine l’évaluation pour les paquets qu’il compare, donc un drop ajouté ensuite ne s’exécute jamais pour eux. Cette règle d’ordre est toute la raison pour laquelle une règle d’apparence correcte peut rester sans effet.
Insérez la règle avant l’accept plutôt que de l’ajouter à la fin. Si la chaîne contient déjà un accept général pour l’interface du tunnel, la nouvelle règle doit le précéder, sinon elle est décorative. Vérifiez l’ordre obtenu et non le fichier que vous avez modifié, car un jeu de règles assemblé à partir de plusieurs fichiers peut ne correspondre à aucun d’eux. Confirmez ensuite avec un paquet de test issu du pool.
sudo nft list chain inet filter forward
sudo nft insert rule inet filter forward iifname "tun0" ip saddr 10.90.0.0/24 ip daddr 198.51.100.0/24 drop
sudo nft -c -f /etc/nftables.conf
La troisième commande analyse le fichier sans l’appliquer, ce qui attrape les erreurs de syntaxe avant qu’elles ne deviennent une panne. Appliquez avec un plan de retour, car une règle erronée dans une chaîne forward peut couper le tunnel par lequel vous travaillez.
Les flux existants ne se soucient pas de votre nouvelle règle
Une entrée conntrack créée avant l’existence de la règle continue de correspondre à l’accept précédent. C’est pourquoi un nouveau drop semble parfois fonctionner pour des connexions neuves et ne rien faire pour celle que l’on teste.
Lisez la correspondance d’état en haut de la chaîne. Si elle accepte le trafic established et related avant votre règle, chaque flux déjà en cours continue de circuler jusqu’à sa fermeture. C’est généralement le comportement souhaité pour une règle d’urgence, et c’est déroutant quand on attend une coupure immédiate. Décidez de l’effet voulu avant de déployer. Un test qui réutilise une connexion ouverte vous racontera une fausse histoire.
sudo conntrack -L -s 10.90.0.14 -d 198.51.100.20
sudo nft list ruleset | grep -n -A3 'ct state'
La première commande indique si un flux existe, et la seconde si une règle d’état précoce continue de l’accepter. Les deux sont en lecture seule et sûres pendant un incident.
Ce que cette règle n’est pas
La règle n’est pas une liste noire de domaines, une politique IPv6 ni une restriction sur un compte d’application particulier.
Chacune de ces choses demande son propre mécanisme. Un blocage de domaine doit résoudre des noms, ce qu’un filtre de paquets ne fait pas. Le trafic IPv6 a besoin de sa propre correspondance, car une expression ip ne dit rien des paquets ip6. Une restriction au niveau applicatif appartient au service ou à un proxy authentifié, pas à une correspondance de préfixe. Garder ces exigences séparées évite de demander à une règle étroite de faire quatre métiers.
Le contrat que cette règle remplit est précis : le trafic d’un pool autorisé vers un préfixe de destination est refusé, tandis que le trafic non lié de la passerelle conserve sa politique existante. Écrivez cette phrase à côté de la règle, et la personne suivante saura à quoi elle servait.