UFW rejette le serveur DNS du VPN dès que le tunnel est actif
La politique de refus par défaut d'UFW couvre aussi l'interface du tunnel. Triez le trafic par direction, autorisez le résolveur poussé sur tun0, puis ouvrez le chemin extérieur.
Les noms cessent d'être résolus à l'instant où le VPN se connecte, alors qu'un ping vers une adresse publique répond encore et que l'état du pare-feu n'affiche rien qui semble anormal. Rien n'a changé dans la politique ; ce qui a changé, c'est qu'une nouvelle interface est apparue, et le refus par défaut la couvre dès le premier paquet. UFW décide selon la direction et l'interface, donc une règle écrite pour la liaison sans fil ne dit rien du trafic qui quitte le tunnel. La réparation est une poignée de règles étroites appliquées dans un ordre précis.
Le symptôme n'apparaît qu'une fois le tunnel actif
Une politique de refus par défaut fait exactement ce qu'on lui a dit : tout ce qui n'a pas de règle correspondante est rejeté, sur chaque interface qui existe. Le tunnel n'existait pas quand les règles ont été écrites, donc aucune d'elles ne peut le couvrir, et le refus qui était toujours là s'applique désormais à la résolution de noms. Le trafic direct vers une adresse littérale peut encore fonctionner quand une autorisation plus large le couvre, et c'est pourquoi un ping vers un résolveur public réussit alors que la recherche d'un nom échoue. Le trou est une règle pour une interface que la politique n'a jamais vue.
Cela explique aussi pourquoi la panne s'inverse proprement : coupez le tunnel et les noms se résolvent de nouveau, car la requête revient vers une interface qui a des règles. Une politique qui n'échoue que pendant que le tunnel est actif n'est pas un problème DNS, et régler le résolveur lui-même fait perdre le plus de temps ici. Lisez la liste des interfaces avant de lire la configuration du résolveur.
Trois directions, trois jeux de règles différents
Une seule session touche des règles dans plus d'une direction, et un tunnel ajoute une seconde interface à presque chacune d'elles. Trier le trafic d'abord par direction et par interface rend le reste mécanique, car chaque ligne ci-dessous a besoin de sa propre règle à sa propre place. Les exemples utilisent tun0 et un pool de 10.8.0.0/24, alors remplacez les noms et les plages par ceux de la sortie du client lui-même.
| Direction | Example packet | Rule that admits it | Written on |
|---|---|---|---|
| Client to the pushed resolver | A DNS query to 10.8.0.1 | Destination port 53 over the tunnel | The client's tun0 |
| Client to the VPN server | A handshake to the server's public address | Server address and port on the physical link | The client's physical interface |
| Server to a service | SSH from the pool to port 22 | Source pool, destination port, tunnel interface | The server's tun0 |
| Anyone to the listener | The VPN listener itself | 1194/udp on the public side | The server's public interface |
Deux lignes sont souvent confondues parce que toutes deux mentionnent le tunnel. Une règle pour le résolveur autorise le trafic que le client envoie dans le tunnel, tandis qu'une règle pour SSH autorise le trafic que le serveur en reçoit ; elles vivent sur des machines différentes et échouent indépendamment. La ligne que l'on oublie le plus souvent est la deuxième, car le client ne peut pas du tout établir le tunnel tant que son trafic vers l'adresse publique du serveur n'est pas autorisé. Travaillez de haut en bas et chaque échec a une seule cause candidate.
Un résolveur poussé a besoin de sa propre règle
Que le tunnel transporte le DNS dépend de ce que le serveur envoie. Un serveur qui pousse une option de résolveur installe une adresse privée dans la configuration du client, et cette adresse n'est routable que par le tunnel. Si le serveur ne pousse rien, le client garde le résolveur qu'il avait déjà et les règles ci-dessous n'ont rien à autoriser. Vérifiez l'état poussé et le résultat actuel de la requête avant d'écrire quoi que ce soit :
dig +short @10.8.0.1 example.com
resolvectl status tun0
sudo ufw status numberedLa sortie d'état nomme le résolveur utilisé et la liaison à laquelle il est rattaché, et la recherche de route en arrière-plan montre quelle interface porterait une requête vers cette adresse. Quand le résolveur se trouve sur une autre liaison, le problème est antérieur au pare-feu et aucune règle n'aidera. Quand les deux s'accordent sur le tunnel, deux règles sont nécessaires, car UDP transporte la plupart des requêtes et TCP prend le relais quand une réponse est tronquée. Notez les deux valeurs, car ce sont elles que les règles nommeront :
sudo ufw allow out on tun0 to 10.8.0.1 port 53 proto udp comment 'pushed resolver'
sudo ufw allow out on tun0 to 10.8.0.1 port 53 proto tcp comment 'truncated answers'Ouvrez le chemin extérieur avant l'intérieur
Le client doit atteindre l'adresse publique du serveur avant qu'un tunnel existe, donc la règle correspondante siège sur la liaison physique et doit être en place d'abord. Une politique qui autorise le résolveur mais oublie le serveur laisse le client incapable de construire le tunnel, et ce symptôme est généralement imputé à un kill switch. Autorisez ensuite les services que vous vouliez réellement à travers le tunnel, une règle étroite à la fois, plutôt que d'ouvrir l'interface en bloc. Les règles étroites sont la raison pour laquelle le refus peut rester en place.
sudo ufw allow out to 198.51.100.10 port 1194 proto udp comment 'vpn server'
sudo ufw allow out on tun0 to any port 443 proto tcp comment 'web through tunnel'L'ordre compte pendant les tests, car la première règle est ce qui permet au tunnel de monter du tout. Ajoutez-la, connectez-vous et confirmez que le tunnel est actif avant d'ajouter la règle de service, car faire les deux à la fois signifie qu'un échec ne vous dit rien sur la moitié qui est fausse. Remplacez l'adresse de documentation ci-dessus par le point de terminaison pour lequel le client est configuré.
Terminez le côté client en vous déconnectant exprès. Le refus devrait encore rejeter le trafic que vous avez délibérément exclu, car un résolveur qui répond pendant que le tunnel est actif ne couvre que la moitié d'une politique qui refuse en cas de doute.
Un client qui se connecte n'est pas encore admis
Le serveur a sa propre direction à considérer, et un client qui termine la poignée de main n'atteint toujours rien de ce qui tourne sur le serveur tant que le serveur ne l'admet pas. La règle du listener public ne fait qu'autoriser l'existence du tunnel ; elle ne laisse pas entrer le trafic du tunnel. Sur le serveur, cela fait deux règles plus une vérification que le service écoute réellement :
sudo ufw allow 1194/udp comment 'openvpn listener'
sudo ufw limit in on tun0 from 10.8.0.0/24 to any port 22 proto tcp comment 'admin over tunnel'
ss -ltn | grep ':22'Le pool de la règle doit être égal à la plage que le serveur alloue, et le numéro de tunnel doit correspondre à celui que le serveur a créé, car une règle pour une autre interface est indiscernable de l'absence de règle. limit est délibéré pour un port administratif, car il limite les connexions répétées au lieu de les admettre sans borne. La vérification du listener sépare un port fermé d'un paquet abandonné, qui semblent identiques depuis le client. Les règles numérotées ne sont pas non plus toute l'image : les règles before d'UFW et toute ligne nftables écrite à la main correspondent plus tôt et peuvent encore rejeter un paquet que la liste semble autoriser.