Les utilisateurs distants n’atteignent pas le second site via le concentrateur VPN
Le transit par le concentrateur demande trois recherches : la route du client, la route de sortie du concentrateur et le chemin de retour du site distant, plus une règle de transfert ciblée.
Un utilisateur distant se connecte au concentrateur, atteint le serveur de fichiers du LAN du concentrateur, et tout semble sain. Puis il ouvre un partage sur 10.20.0.50 au siège, que le concentrateur atteint par un tunnel inter-sites distinct, et la connexion expire. Les deux tunnels sont actifs et les deux compteurs montent, donc aucun tunnel n’est cassé. Traverser le concentrateur, ce sont trois décisions de routage sur trois équipements, et un tunnel ne transporte que les préfixes pour lesquels il a été construit. Voici l’ordre que je vérifie, et la commande qui montre si chaque étape est vraie.
Le transit demande trois recherches, pas un seul tunnel
Chaque équipement fait sa propre correspondance de préfixe le plus long et l’oublie. Le portable doit envoyer 10.20.0.50 dans le tunnel plutôt que vers son routeur local. Le concentrateur doit prendre un paquet arrivé sur l’interface d’accès distant et le remettre à l’interface inter-sites. Le siège doit renvoyer une réponse pour l’adresse de l’utilisateur par le tunnel. Que l’une des trois échoue se voit de la même façon dans le navigateur : le silence.
C’est pourquoi tester chaque tunnel séparément prouve si peu. Un ping vers l’adresse LAN du concentrateur exerce la première décision, et un ping vers le concentrateur depuis le siège exerce la troisième. Le paquet qui échoue a le pool d’utilisateurs pour source et le second site pour destination, alors notez d’abord ces préfixes. Ici le pool est 10.80.0.0/24, le LAN du concentrateur 10.10.0.0/24 et le siège 10.20.0.0/24.
Poussez le préfixe distant vers le client distant
Sur un serveur d’accès distant OpenVPN, le client apprend les routes au moment de la connexion. Sans push, un client à tunnel fractionné envoie 10.20.0.50 vers sa propre passerelle et le paquet n’entre jamais dans le tunnel.
push "route 10.20.0.0 255.255.255.0"
Une route poussée s’applique à la connexion du client, donc un utilisateur qui reste en ligne ne voit rien tant qu’il ne se reconnecte pas. Vérifiez sur le client : ip route get 10.20.0.50 sous Linux, route print sous Windows. La sortie doit nommer l’interface du tunnel.
Le push n’aide pas le concentrateur. C’est un message au client, pas une route sur le serveur ni une autorisation de transférer, donc un concentrateur avec la ligne push parfaite laisse quand même tomber le flux un saut plus loin. C’est la raison habituelle pour laquelle on conclut que le push a échoué.
Donnez au concentrateur une vraie route de sortie
Le concentrateur a besoin de son propre prochain saut pour le préfixe du siège. Sur un tunnel routé, c’est une route ordinaire par l’interface inter-sites, et une seule commande montre à la fois la route choisie et la source choisie :
ip route get 10.20.0.50 from 10.80.0.25
sudo ip route add 10.20.0.0/24 via 172.30.0.2 dev s2s0
Quand le tronçon inter-sites est lui-même OpenVPN, la route peut vivre dans cette configuration avec l’adresse de tunnel du pair comme passerelle : route 10.20.0.0 255.255.255.0 172.30.0.2. La passerelle n’est pas facultative. Omettez-la et le prochain saut retombe sur un défaut d’implémentation, qui diffère entre un client à pair unique et un concentrateur à plusieurs pairs.
L’IPsec à base de politiques est différent : le noyau du concentrateur envoie le paquet à sa passerelle LAN habituelle et la politique l’intercepte à la sortie, donc une route de tunnel soit ne fait rien, soit détourne le trafic au-delà de la politique. Surveillez la source dans la commande ci-dessus, car 10.10.0.1 au lieu de l’adresse du pool signifie que le noyau a choisi une adresse que le site distant rejettera. iroute n’est pas la réponse non plus ; il indique au serveur quel client possède un sous-réseau derrière son propre tunnel, pas où envoyer le trafic pour un troisième site.
Étendez le site distant au pool d’utilisateurs
Le siège couvre déjà le LAN du concentrateur, 10.10.0.0/24. Le pool d’utilisateurs est un second préfixe et doit aussi figurer dans les sélecteurs, sinon aucune politique ne couvre une réponse adressée à 10.80.0.25. Chaque pair nomme la même paire d’ensembles de préfixes de son côté :
# strongSwan swanctl.conf, on the hub
local_ts = 10.10.0.0/24, 10.80.0.0/24
remote_ts = 10.20.0.0/24
# on the headquarters peer
local_ts = 10.20.0.0/24
remote_ts = 10.10.0.0/24, 10.80.0.0/24
Le local_ts d’un équipement est le remote_ts de l’autre. Copiez le bloc du concentrateur sur le siège et la paire est inversée, donc la child SA ne monte jamais.
L’ancienne syntaxe de ipsec.conf utilise un leftsubnet séparé par des virgules. L’association de sécurité en cours conserve les sélecteurs qu’elle a négociés, donc rétablissez le tunnel après la modification. Un sélecteur changé à 10:00 et testé contre une SA montée à 09:40 échoue encore, alors que le fichier de configuration semble correct tout du long.
Vérifiez ensuite le dernier saut. ip route get 10.80.0.25 sur le point d’extrémité distant doit pointer dans le tunnel. Si le service utilise un routeur LAN comme passerelle par défaut, ce routeur a aussi besoin de la route de retour, sinon la réponse meurt là. Exécuter tcpdump -ni eth1 host 10.80.0.25 sur ce segment montre si la réponse a quitté le point d’extrémité.
Autorisez le flux sur le concentrateur
Le transfert doit être activé et le chemin autorisé. Limitez les règles aux deux préfixes au lieu d’accepter tout entre les interfaces.
sysctl -w net.ipv4.ip_forward=1
iptables -I FORWARD -i tun0 -o s2s0 -s 10.80.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -I FORWARD -i s2s0 -o tun0 -s 10.20.0.0/24 -d 10.80.0.0/24 -j ACCEPT
Le filtrage de chemin inverse est la panne silencieuse à côté : avec les deux jambes sur des interfaces différentes, rp_filter=1 peut jeter la réponse alors que le compteur de la règle d’acceptation ne bouge jamais. Comparez iptables -vnL FORWARD avant et après une tentative. Une règle qui n’incrémente jamais n’est pas atteinte, alors regardez une couche plus bas au lieu de la réécrire.
Si un seul groupe a besoin du transit, mettez la route dans un fichier par client sous client-config-dir au lieu d’élargir le push global. Le NAT source sur le concentrateur supprime aussi le besoin d’une route de retour distante, mais il masque l’adresse de l’utilisateur, donc les journaux du site distant et les règles basées sur l’adresse cessent de distinguer les utilisateurs.
Vérifiez depuis le client, puis annulez dans l’ordre inverse
Testez un port TCP, pas seulement ICMP, car un ping peut passer alors que le service reste bloqué. nc -vz 10.20.0.50 445 et traceroute -n 10.20.0.50 depuis le client montrent si le deuxième saut est l’adresse de tunnel du concentrateur. Sur le concentrateur, tcpdump -ni tun0 host 10.20.0.50 et le même filtre sur l’interface inter-sites : une requête sur les deux sans réponse sur aucune déplace le problème vers le site distant.
Testez ensuite quelque chose qui doit rester bloqué. Si un hôte que le pool ne devrait jamais atteindre répond aussi, vous avez ouvert plus que le transit et devriez resserrer les règles. Un concentrateur qui transfère tout vers chaque antenne passe le premier test et échoue au second.
Tenez une liste d’annulation, car quatre objets ont changé et trois sont faciles à oublier : la route poussée, la route du concentrateur, les sélecteurs et les règles du pare-feu. Annulez-les dans l’ordre inverse, rétablissez la SA et faites reconnecter un utilisateur. Une annulation partielle laisse une route qui pointe vers un tunnel qui ne correspond plus, ce qui est plus difficile à lire que le silence d’origine. Le manuel d’OpenVPN 2.6 documente push, route et iroute pour votre version.