Aventure étonnante sur un VPN

Phénomène curieux et faille potentielle sur un VPN

On se met sur un réseau, mettons 192.168.1.0/24 avec une passerelle 192.168.1.2 par exemple.
Le serveur VPN est sur des machines et les clients sur d’autres. Le VPN établit un réseau 192.168.0.0/24 avec des adresses fixes. Tout se passe très bien.

Le cable réseau d’une machine se coupe 'cétait pour un test), à ce stade la connexion VPN s’interrompt et ne repart pas après le remise du cable. Pourtant, la connexion vers le serveur VPN via son adresse VPN en 192.168.0.0/24 fonctionne. On vérifie que la connexion est en clair.

Raison: sur la passerelle, une vieille route subsistait:

route add -net 192.168.0.0/24 eth0

Le client n’a plus la route via le VPN et se rabat vers la passerelle, la passerelle reçoit le paquet et l’envoit eth0 à destination de vers la machine 192.168.0.1 (serveur VPN). Cette machine reçoit le paquet et y répond. J’imagine que la connexion VPN vers la machine client étant tombé, elle se rabat elle aussi vers la passerelle (c’est étonnant tout de même, cela signifie que les routes sur le VPN se font machine par machine, à la réflexion c’est logique). En tout état de cause, sur la machine client comme le serveur n’a pas vu la coupure de connexion et ne se sont jamais aperçu que la connexion, initalement sur le VPN et donc sécurisée est passée en clair sur le réseau classique. Il convient donc de faire très attention choix de la plage réseau sur le VPN et de bien controler la passerelle. En fait, il faut supprimer la route par défaut sur les machines client du VPN ou bien la faire passer par le VPN.

À la relecture, je pense qu’il faut faire un résumé:

En clair on a un VPN sur un réseau LAN géré par une passerelle. Les ordinateurs clients comme serveur VPN ont cette passerelle comme route par défaut. On suppose que 192.168.0.0/24 est le réseau interne au VPN.

Si eth0 est l’interface de la passerelle, on peut faire basculer le trafic VPN sur le LAN en clair sans que les gens ne s’en rendent compte comme suit:

Sur la passerelle:

route add -net 192.168.0.0/24 eth0

Puis on déconnecte et reconnecte le serveur VPN du réseau. Le trafic passe immédiatement en clair sur la passerelle, il suffit alors d’écouter sur cette passerelle. Les utilisateurs du VPN ne se rendent compte de rien.

La solution consiste à faire passer la route par défaut par le VPN et non par la passerelle classique.

PS: Pascal, tu peux confirmer mon analyse?

Quel est le but de cette configuration de VPN ? Chiffrer les communications sur le réseau local, je suppose ?

Je confirme ton diagnostic concernant l’existence des deux faiblesses et j’en ajoute une.

  1. Sur le serveur VPN, la route vers le préfixe du VPN associée à l’interface ethernet, qui n’a évidemment rien à faire là.
  2. La route par défaut sur le client VPN qui est utilisée pour le préfixe du VPN lorsque la route spécifique via le VPN est tombée.
  3. Le “modèle faible” (weak host model) de Linux le conduit à accepter de communiquer sur une interface avec une adresse ne correspondant pas. Cela favorise la connectivité mais pas la sécurité, comme tu l’as constaté : la connexion passe mais en clair.

En revanche je ne comprends pas ta phrase “cela signifie que les routes sur le VPN se font machine par machine”. Une fois son VPN tombé, le client utilise son adresse LAN.

Du côté des contre-mesures, il y en a plusieurs possibles, qui peuvent être combinées.

  • Sur la passerelle, supprimer la route vers le préfixe du VPN. Mais ce n’est qu’une demi-mesure, car des paquets peuvent encore circuler en clair entre un poste et la passerelle.
  • Sur les clients du VPN, supprimer la route par défaut via la passerelle et la remplacer par une route par défaut via le VPN. Mais ce n’est pas indispensable ni franchement utile, car ce trafic est destiné à passer en clair ensuite.
  • Ajouter des “nullroutes” (unreachable) pour le préfixe du VPN avec une forte métrique sur les clients VPN, ainsi quand le VPN est inactif son préfixe n’est pas routable.
  • Filtrer sur l’interface LAN, en bloquant le préfixe du VPN.

[quote=“PascalHambourg”]Quel est le but de cette configuration de VPN ? Chiffrer les communications sur le réseau local, je suppose ?
[/quote]Oui[quote]
Je confirme ton diagnostic concernant l’existence des deux faiblesses et j’en ajoute une.

  1. Sur le serveur VPN, la route vers le préfixe du VPN associée à l’interface ethernet, qui n’a évidemment rien à faire là.[/quote]Je n’ai pas une route spécifique justement, je pensais que dès que le VPN était en root (la chute de la connexion ne fait pas tomber le serveur, juste les connexions existantes), il y avait un route via tap0 automatiquement crée… Ici, seule la route vers le LAN est associée à l’interface ethernet. Je suis étonné que si la machine n’est pas accessible via le VPN, le serveur utilise alors la route par défaut.[quote]
  2. La route par défaut sur le client VPN qui est utilisée pour le préfixe du VPN lorsque la route spécifique via le VPN est tombée.
  3. Le “modèle faible” (weak host model) de Linux le conduit à accepter de communiquer sur une interface avec une adresse ne correspondant pas. Cela favorise la connectivité mais pas la sécurité, comme tu l’as constaté : la connexion passe mais en clair.

En revanche je ne comprends pas ta phrase “cela signifie que les routes sur le VPN se font machine par machine”. Une fois son VPN tombé, le client utilise son adresse LAN.
[/quote]C’est ce que j’ai dit plus haut, je pensais que le serveur VPN créait un route type
route add -net 192.168.0.0/24 tap0

Ce qui signifie que tant que openvpn tourne (que la connexion existe ou non), la route était tap0, or il semble que si on coupe une connexion vers un client, la connexion passe alors par la passerelle par défaut. Je vais essayer aujourdhui une connexion à trois machines (serveur + 2 clients et tester si en débranchant et rebranchant client1, les paquets pour client1 passe par la passerelle et les paquets pour client2 passe par le VPN). C’est cet aspect qui m’étonne vraiment.

[quote]
Du côté des contre-mesures, il y en a plusieurs possibles, qui peuvent être combinées.

  • Sur la passerelle, supprimer la route vers le préfixe du VPN. Mais ce n’est qu’une demi-mesure, car des paquets peuvent encore circuler en clair entre un poste et la passerelle.
  • Sur les clients du VPN, supprimer la route par défaut via la passerelle et la remplacer par une route par défaut via le VPN. Mais ce n’est pas indispensable ni franchement utile, car ce trafic est destiné à passer en clair ensuite.[/quote]C’est ce que j’ai fait…[quote]
  • Ajouter des “nullroutes” (unreachable) pour le préfixe du VPN avec une forte métrique sur les clients VPN, ainsi quand le VPN est inactif son préfixe n’est pas routable.
  • Filtrer sur l’interface LAN, en bloquant le préfixe du VPN.[/quote]
    La dernière solution est simple et efficace. Adopté. Mais je n’avais pas de souci sur le remède, c’est plutôt cette histoire de gestion des routes machine par machine que semble faire le serveur VPN… Je vais regarder plus en détail et reproduire le pbm…

[quote=“fran.b”]je pensais que le serveur VPN créait un route type
route add -net 192.168.0.0/24 tap0[/quote]
S’il s’agit d’openvpn en mode server, il me semblait que oui. Ce n’est pas le cas ?

Pour le reste, il faut examiner les tables de routage de chaque machine impliquée, la réponse s’y trouve forcément.

Si j’ai bien compris, moi ça ne m’étonne pas.
Tu peux faire communiquer deux machines avec une route dans un sens et une autre dans l’autre. L’une des particularité d’ATM était justement d’avoir la même route dans le même sens.
Là où il me semble que le bas blesse c’est que la machine qui est encore dans le VPN accepte des connexions qui ne viennent pas du VPN (c’est une configuration du firewall).

Bon, je suis dans la salle, 4 machines plus passerelle.

Là je suis dans un situation vérifié par tcpdump où

  • Le serveur VPN et une machine se pinguent via le VPN.

  • Une autre machine sur laquelle j’ai coupé le VPN, pingue le serveur VPN via son IP réseau VPN (192.168.0.0/24)

  • Le serveur VPN lui est incapable de pinguer la machine VPN (là ça m’échappe).

  • La passerelle ne voit rien passer

  • L’adresse arp du serveur VPN est la virtuelle sur la machine qui pingue par VPN et l’adresse physique ethernet sur l’autre.

  • Sur le serveur VPN, l’adresse arp de la machine via VPN est correcte, l’autre est déclarée incomplète, par contre y figure l’adresse ethernet de la machine client connectée sans VPN

  • Un tcpdump montre un dialogue direct cette fois entre la machine client sans VPN et le serveur. Cela est confirmé par la suppression de la route dans la passerelle.

Bon je fais une photographie des tables de routages de cet instant précis, connexion d’une machine au serveur VPN via VPN, de l’autre directement, sans passer par la passerelle, alors que le serveur VPN lui ne peut pas joindre par ping. Je présume que le ping passant par l’interface eth0, l’adresse LAN est utilisée et passe l’adresse VPN, le serveur VPN peut donc lui répondre. Cela signifie que le client VPN peut se connecter sur le serveur VPN mais pas l’inverse, ce que confirme l’expérience. Ça me parait «à peu près» clair mais il faut que je sois sur de ça. L’enquiquinant est que je teste la présence du serveur depuis les clients VPN via un ping sur son IP VPN, il faut donc que je fasse attention à cet aspect si le serveur est capable de répondre via l’ethernet…

Table routage serveur VPN

Destination Passerelle Genmask Indic Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tap0 0.0.0.0 192.168.1.2 0.0.0.0 UG 0 0 0 eth0

Table routage client pertubé

Destination Passerelle Genmask Indic Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 192.168.1.2 0.0.0.0 UG 0 0 0 eth0

Table routage client non pertubé

Destination Passerelle Genmask Indic Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tap0 0.0.0.0 192.168.1.2 0.0.0.0 UG 0 0 0 eth0

Table routage passerelle

Table de routage IP du noyau Destination Passerelle Genmask Indic Metric Ref Use Iface 81.57.102.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 81.57.102.254 0.0.0.0 UG 0 0 0 eth1 puis

Destination Passerelle Genmask Indic Metric Ref Use Iface 81.57.102.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 81.57.102.254 0.0.0.0 UG 0 0 0 eth1

Par contre, là où je ne comprends plus trop c’est que l’expérience n’est pas reproductible chez moi (où je n’ai pas la route vers 192.168.0.0/24 au niveau de la passerelle au début de l’expérience).

Là où j’ai fait l’expérience, la route existait et la machine a commencé à faire des pings en passant par la passerelle. Se pourrait il que l’existence d’une entrée vers le serveur VPN LAN dans la table arp (en clair une entrée

serveurVPN ether 00:13:d3:92:41:1f C eth0 au lieu de

serveurVPN 90:12:c2:4c:5b:2a C tap0 (de mémoire) puisse modifier le comportement du routage une fois le VPN tombé??? Je croyais avoir parfaitement compris le pbm mais ça se complique.

Je ressaye en mettant au préalable une route sur la passerelle. Le VPN tombe, un ping du client VPN vers le serveur VPN passe puis plus rien, normal il y a deux entrées dans la table arp ayant la même adresse Ethernet. Je laisse cette double entrée et supprime la route sur la passerelle et là les pings passent comme ci dessus. À ce stade figure dans la table arp les deux adresses (LAN et VPN) du serveur associée à la même adresse MAC, adresse MAC de la carte eth0 du serveur. Les ping ne passent pas par la passerelle et vont directement du client au serveur VPN.
Je pense donc avoir compris à peu près mais des zones d’ombre subsistent, pas assez pour m’empêcher de compléter mon système mais suffisament pour m’agacer. Félicitations à celui qui suit jusque là…

[En fait, je souhaite pouvoir relancer automatiquement la connexion VPN si il y a une interruption de réseau suivi d’un éventuel chgt d’IP du serveur]

J’avoue que je n’ai pas tout compris dans le comportement de tes machines. Surtout, je ne comprends pas pourquoi, VPN coupé, un ping vers l’adresse VPN passe après suppression de la route sur la passerelle alors qu’il ne passait pas quand la route était présente.

En tout cas les tables de routage sont correctes.
A ma connaissance les entrées ARP n’influencent pas la décision de routage : d’abord le routage choisit l’interface de sortie, et ensuite ARP fait la résolution d’adresse du next hop sur l’interface concernée. Logiquement, dans tous les cas la résolution devrait retourner l’adresse MAC physique sur eth0 ou l’adresse MAC virtuelle sur tap0.

En fait il y a trois situations pour un résultat assez étonnant:

C est le client avec VPN, S est le serveur

  1. Situation 1 standard:
    C a comme adresse arp pour S sous l’adresse VPN.

Maintenant plus de VPN (plus d’interface tap0, table de routage identique exceptée la route vers tap0 donc) : 2 cas

  1. Pas de route add -net LAN eth0 sur la passerelle, jamais.
    Rien ne passe dans un sens ou dans l’autre, jamais.

  2. Une route existe dans la passerelle
    Le ping passe (C IP LAN vers S IP VPN) Puis la route est interrompue.
    La table arp contient alors deux adresses arp pour S sous l’adresse VPN, l’une étant celle de l’interface tap0 du serveur, l’autre celle de eth0.
    Un ping du client vers le serveur passe (et est vu comme C IP LAN vers S IP VPN) mais pas du serveur vers le client. Je l’ai reproduit plusieurs fois et les tables ci dessus sont directement issues de ces essais.

Je pensais que le protocole IP et le routage était au niveau 3 ou 4 (3 je pense) et la gestion ethernet et les adresses arp au niveau 2 donc que ces dernières ne pouvaient influer sur le routage et tu me confirmes ça. Je ne comprends toujours pas. Ça m’énerve.