Configuration IPv6 de la Haute Disponibilité sur pfSense
Divulgâchage : Pour rester connecté à Internet en cas de panne de notre pare-feu pfSense, on a décidé de le redonder en haute disponibilité. La documentation pour IPv6 étant lacunaire, nous avons du creuser pour trouver une solution qui marche la plupart du temps (car certaines distributions Linux ne gèrent pas tout). On comprend mieux pourquoi le manque d’enseignement et de déploiement IPv6.
Comme beaucoup d’accrocs au Réseau, on est tellement angoissés à l’idée de perdre notre connexion à cause d’une panne quelque part qu’on cherche à redonder tout ce qui peut l’être. Bon, on l’avoue, c’est aussi pour la beauté geekette du geste.
On a donc commencé par redonder nos accès proprement dits. Au cas où la fibre nous lâche, nous avons de l’ADSL chez un autre opérateur. Et en cas de problème sur les 100 derniers mètres on peut aussi partager nos connexions 4G, chez un troisième opérateur. La bascule entre ces connexions se fera automatique par le pare-feu. Et pour en être sûr, on fait des exercices régulièrement.
Mais quid du pare-feu lui-même… Que se passe-t-il si c’est lui qui tombe en rade ?
On avait initialement bricolé un mode actif/passif avec ESXi où un pare-feu était éteint et attendait qu’on le démarre en cas de besoin mais on doit bien admettre que ce n’était pas très pratique. Il fallait manuellement reporter chaque changement de configuration et la bascule n’était pas toujours automatique.
On a donc décidé d’investir un peu plus de temps pour mettre en place la solution officielle du mythe : la haute disponibilité (abrégé HA pour High Availability en anglais). Cette fois les deux pare-feux fonctionnent de concert : la configuration est automagiquement synchronisée et le secondaire prendra en charge le trafic réseau dès que le principal ne lui répondra plus.
Pour IPv4, c’est presque un jeux d’enfant ; la documentation officielle fourni un exemple de configuration qu’il suffit globalement de suivre et même une deuxième page pour diagnostiquer et résoudre les problèmes si ça marche pas du premier coup…
Pour IPv6, en revanche, c’est une autre histoire… Mis à part quelques mentions maladroites dont certaines erronées dans un hangout de netgate en mars 2017, rien n’est utilisable en l’état. Ne cherchez pas de solution non plus dans les nombreux tutoriels qu’on trouve un peu partout ailleurs ; ils ne font que paraphraser l’exemple officiel, en IPv4.
Le monde serait-il bloqué dans les années 80 ?
Alors, comme nous voulions absolument être connecté à l’Internet du futur, nous avons retroussé nos cyber-manches et après pas mal d’huile de coude, trouvé le pourquoi du comment et abouti à quelque chose qui marche (mais pas toujours).
Plan et adresses
Avant de commencer, comme toujours lorsqu’on va faire du réseau, on va dresser la carte et y reporter toutes les informations dont on va avoir besoin. On vous laisse remplacer nos valeurs d’exemple par les vôtres chez vous.
Les deux pare feu. Forcément puisqu’on parle de haute disponibilité… Notez que d’après la documentation, ils doivent avoir les mêmes connexions réseaux - cartes branchées dans le même ordre avec les mêmes noms - et que vous allez donc devoir le faire sur chacun d’entre eux.
Préfixes IPv6 publics. On va partir du principe que
votre fournisseur d’accès internet vous a attribué au moins un préfixes
IPv6 que vous pouvez déléguez. 2001:DB8:1234:5679::/64
dans
notre exemple.
Si votre fournisseur ne vous attribue qu’un seul préfixe et qu’il est collé à la box comme une bernique sur une coque, ça va être compliqué pour vous. Si vous voulez un conseil, changez d’opérateur.
Synchronisation - en IPv4
Je vous avait annoncé une configuration IPv6 et vous vous rendez compte que le réseau de synchronisation qui relie les deux pare-feux est en IPv4 sur mon schéma. Me serais-je trompé, ou pire, vous aurai-je menti ?
Non ; c’est parce que la synchronisation ne peut pas fonctionner complètement en IPv6. Si vous voulez le faire quand même, vous allez rencontrer deux problèmes.
1. Le choix des adresses. Votre interface doit avoir
une adresse fixe mais vous ne pouvez pas utiliser d’adresse locale de
lien (préfixe FE80
, l’interface l’interdit). Vous devez
donc utiliser soit un préfixe public (cf. le hangout de mars
2017 mais je trouve que c’est du gaspillage), soit utiliser le préfixe
privé FC00
.
2. pfSync refuse l’IPv6. Ensuite, une fois dans l’écran de configuration de la haute disponibilité, vous pouvez entrer vos adresses IPv6 mais l’interface ne l’acceptera pas pour la synchronisation des états (pfsync) et vous fera savoir qu’elle n’accepte que de l’IPv4.
Donc, au mieux, vous pourriez synchroniser la configuration via IPv6 mais devrez garder la synchronisation des états en IPv4… C’est dommage et pour éviter de tout complexifier avec deux adresses, on vous conseille de tout garder en IPv4 pour la synchronisation.
La documentation officielle étant bien faite on ne va pas détailler cette partie et on va poursuivre sur les autres subtilités.
Côté WAN - une VIP
Votre box d’accès internet n’est normalement pas conçue pour voir deux pare-feux et envoyer le trafic d’elle-même à l’un ou l’autre. Elle ne veut en voir qu’un et ne veut surtout rien savoir de vos petits arrangements.
Vous allez donc devoir utiliser une VIP (adresse IP
virtuelle) que se partagerons les deux pare-feu (dans notre exemple :
FE80::ba0:bab/64
).
La configuration va se faire comme en IPv4 et vous pouvez donc suivre la documentation officielle.
La subtilité, cette fois, vient plutôt de la configuration des boxes :
- En IPv4 on avait la notion d’adresse de DMZ. Comme les boxes n’avaient qu’une seule adresse IP publique, vous leur disiez de rediriger tout le trafic entrant vers l’IP de votre pare-feu (la fameuse DMZ) et lui faisait du NAT pour masquer tout le réseau qui se trouvait derrière.
- En IPv6 les opérateurs vous attribuent plusieurs
préfixes IPv6
/64
et vous laisse dire vers qui envoyer le trafic de ces IP (certaines box parlent de DMZ, d’autre de délégation et de next hop).
Exemple chez free
Une fois dans l’interface de configuration de la box, allez dans les
paramètres, choisissez le mode avancé puis cliquez sur configuration
IPv6. La nouvelle fenêtre vous informe de l’adresse IPv6 locale de
la box (commençant par FE80
, notez cette adresse quelque
part car vous devrez la renseigner comme routeur sur vos pare-feux) et
vous propose de configurer la délégation de préfixe.
Pour chacun des préfixes que vous allez utiliser derrière vos
pare-feux, renseignez l’adresse IP virtuelle (FE80::ba0:bab
dans notre exemple, à adapter suivant votre réseau).
Exemple chez RED/SFR
Une fois connecté sur l’interface d’administration de votre box,
allez dans le menu Etat puis Internet et naviguez
jusqu’à l’encart Internet IPv6. Vous y verrez le préfixe
publique qui vous a été attribué et, surtout, l’adresse IP de la
passerelle (préfixe fe80
à noter pour plus tard car ce sera
la passerelle pour vos pare-feux).
Vous pouvez alors aller dans la configuration du pare-feux (menu Réseau v6 puis Pare-feu). Naviguez ensuite vers l’encart DMZ pour l’IPv6.
Même si le premier écran nous informait que nous disposions d’un préfixe de 56 bits (soit l’équivalent de 256 préfixes de 64 bits), cet écran ne permet de ne configurer qu’un seul préfixe de 64 bits.
Pour le reste, le principe est le même que précédemment, renseignez l’adresse IP virtuelle de vos pare-feux en tant qu’adresse de la DMZ pour que ce préfixe leur soit redirigé.
Côté LAN - deux solutions
C’est à partir d’ici que les choses se compliquent car la documentation se fait de plus en plus lacunaire et on va devoir se confronter à toutes ces petites subtilités du réseau parfois incompatibles entre elles… Vous allez avoir le choix entre la solution classique (qui marche pas toujours) et la solution officielle (qui marche pas toujours non plus).
Utiliser une IP Virtuelle
Divulgâchage : Cette solution ne marche pas vraiment, on vous conseille la suivante.
Première idée, simuler un seul pare-feu avec une adresse IP virtuelle. C’est ce qu’on faisait déjà en IPv4 et une partie de la documentation suggère même de passer par là (i.e. toujours ce hangout de mars 2017). Sur le papier ça devrait marcher…
Configurer une VIP. Dans le menu Firewall,
puis Virtual IPs, cliquer sur le bouton Add, choisir
CARP, renseigner les champs (i.e. adresse
FE80::3:BA0:BAB/64
).
Configurer les annonces. Dans le menu Services, puis DHCPv6 Server & RA, choisir l’interface (LAN) puis l’onglet Router Advertisements.
- Router mode : unmanaged fera très bien l’affaire (lire : les autres ne résoudront pas les problèmes),
- RA Interface : choisissez la VIP précédemment configurée (si ce champ n’apparaît pas, c’est que vous n’avez pas de VIP sur l’interface),
- DNS Configuration : vous pouvez renseigner l’IP de
vos pare-feu (i.e.
2001:DB8:1234:5679::1
et2001:DB8:1234:5679::2
).
Concrètement, lorsqu’une machine cliente se connectera au réseau et demande où elle est, les routeurs s’annonceront (notez qu’ils le font aussi à intervalles réguliers). Sur linux, vous pouvez voir ces paquets avec la commande suivante :
sudo tcpdump -v -n -i enp2s0 icmp6 and ip6[40] == 134
Et vous obtiendrez des lignes de ce genre, assez imbuvables c’est vrai, mais rassurez-vous ; on vous les explique juste après. J’ai changé les adresses IP de ma capture par celles de l’exemple pour que vous puissiez plus facilement savoir qui est qui.
10:16:52.293453 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 176) fe80::3:1 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 176
hop limit 64, Flags [none], pref medium, router lifetime 60s, reachable time 0ms, retrans timer 0ms
prefix info option (3), length 32 (4): 2001:DB8:1234:5679::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s
route info option (24), length 24 (3): ::/0, pref=medium, lifetime=60s
rdnss option (25), length 40 (5): lifetime 60s, addr: 2001:DB8:1234:5679::1 addr: 2001:DB8:1234:5679::2
dnssl option (31), length 48 (6): lifetime 60s, domain(s): example.com. example.com.
mtu option (5), length 8 (1): 1500 source link-address option (1), length 8 (1): a6:6e:de:ad:be:ef
En gros, voici ce que disent ces paquets :
- Salut, je (
fe80::3:1
) suis un routeur qui peut transmettre vos paquets vers le grand internet, - Le préfixe IPv6 public par ici est le
2001:DB8:1234:5679::/64
, vous pouvez piocher votre adresse dedans, - Voici deux serveurs DNS qui répondrons à vos requêtes avec joie,
d’ailleurs, le domaine local est
example.com
, - Et dernière info bonus pour vous faciliter la vie, voici aussi mon adresse MAC, comme ça pas besoin de la demander. De rien.
Normalement (d’après la documentation), puisque vous utilisez une VIP, seul le pare-feu principal envoie ces annonces. Le secondaire n’est sensé en envoyer que s’il détecte que le principal ne répond plus. Le problème, c’est que les deux pare-feux envoient ces annonces qu’importe qui gère la VIP (peut être une régression due à la version 2.6 de pfSense puisque la documentation est en 2.4).
D’ailleurs, sans la dernière information sur l’adresse MAC, ça pourrait même marcher. Pour trouver l’adresse physique (MAC) du routeur, les machines devraient en faire la demande (via le protocole NDP) et, magie de la VIP, seul le principal ne répondrait.
Malheureusement, comme cette option est transmise, les clients doivent la prendre en compte et en deviennent fous.
- Il y a ceux qui vont mettre leur table de voisinage à jour à chaque nouvelle annonce reçue et changer d’avis en permanence sur « quelle est l’adresse MAC du routeur » (i.e. Linux et Windows). Quand c’est la bonne adresse les paquets partent et reviennent, quand c’est pas la bonne, ça part mais reviendra pas.
- Il y a ceux qui voyant que l’adresse change, vont considérer que le réseau a changé et se reconfigurer (coucou android). Ils vont donc se déconnecter le temps que leur auto-configuration reconstruise les nouveaux paramètres réseaux et ça peut prendre un peu de temps pendant lequel le réseau ne marche pas.
Dans les deux cas vous avez l’impression d’une connexion intermittente qui marche aléatoirement.
Prioriser les routeurs
Cette solution marche un peu mieux que la précédente mais vous aurez quelques surprises sous Linux.
Plutôt que de confondre les routeurs, la solution est cette fois de bien les différentier mais en les dotant d’une priorité. Cette fois, on n’utilise pas du tout de VIP (si vous en aviez créé une, vous pouvez la supprimer) mais on va configurer différemment les deux routeurs.
Configurer les annonces. Dans le menu Services, puis DHCPv6 Server & RA, choisir l’interface (LAN) puis l’onglet Router Advertisements.
- Router mode : unmanaged fera très bien l’affaire (lire : les autres ne résoudront pas les problèmes),
- Router priority : high pour le principal et medium pour le secondaire (ou alors medium pour le principal et low pour le secondaire),
- RA Interface : ne devrait pas être affiché mais si
c’est le cas, choisissez l’adresse locale du routeur,
FE80::3:1
etFE80::3:2
, surtout pas de VIP ici), - DNS Configuration : vous pouvez renseigner l’IP de
vos pare-feu (i.e.
2001:DB8:1234:5679::1
et2001:DB8:1234:5679::2
).
Lorsqu’une machine cliente en fera la demande, et à intervalles réguliers, vos routeurs s’annonceront mais cette fois ils intègreront leur priorité spécifique dans leurs messages. Les machines clientes verront donc plusieurs passerelles mais sauront qu’il faut en utiliser une en priorité et n’utiliser l’autre que si la première ne s’annonce plus ou ne répond plus.
Même s’ils ne vous affichent pas ces priorités, c’est comme ça que fonctionnent Windows et Android. Ils vous listent les passerelles mais n’utilisent la principale que tant qu’elle répond et ne bascule sur la secondaire qu’en cas de défaut de la principale.
Linux de son côté vous affiche les priorités mais certaines distributions on des problèmes pour les différencier.
Pour voir les passerelles et leur poids, vous pouvez utiliser la commande suivante :
ip -6 route show
Sur Centos 7-2009, et avec nos deux routeurs, voici un extrait (adapté à l’exemple) de ce que vous pourriez obtenir (j’ai supprimé les lignes unreachable) :
2001:DB8:1234:5679::/64 dev enp0s3 proto ra metric 100 pref medium
fe80::/64 dev enp0s3 proto kernel metric 100 pref medium
default via fe80::3:1 dev enp0s3 proto ra metric 100 pref high default via fe80::3:2 dev enp0s3 proto ra metric 100 pref medium
On a bien deux routes par défaut, chacune avec un routeur différent et leur priorité correspondante (high et medium).
Sur toutes les autres distributions que nous avons testés, vous obtiendrez quelque chose de ce genre (capture modifiée d’une Ubuntu desktop 22.04) :
::1 dev lo proto kernel metric 256 pref medium
2001:DB8:1234:5679::/64 dev enp0s3 proto ra metric 100 pref medium
fe80::/64 dev enp0s3 proto kernel metric 1024 pref medium
default proto ra metric 100 pref high
nexthop via fe80::3:1 dev enp0s3 weight 1 nexthop via fe80::3:2 dev enp0s3 weight 1
Pour ces distributions, les deux routeurs sont regroupés avec la même préférence (la plus grande reçue, ici high). Le noyau va donc choisir tantôt l’un (et les réponses reviendront), tantôt l’autre (et aucune réponse ne reviendra). Vous pouvez vous en rendre compte avec cette commande :
watch ping -c 1 -W 1 2600::1
Cette commande watch
lance à intervalles réguliers
(toutes les deux secondes) ping
vers 2600::1
en n’envoyant qu’une seule requête (option -c 1
) et en
n’attendant pas plus d’une seconde pour considérer un échec (option
-W 1
). Vous verrez alors tantôt une réponse reçue, tantôt
aucune réponse reçue suivant par quel routeur le noyau a décidé
d’expédier vos requêtes.
Pour info, voici la liste des distributions que nous avons testées. Pour chacune d’entre elle, nous avons configuré une machine virtuelle VirtualBox avec une carte réseau en accès par pont puis effectué une installation par défaut et, lorsque c’était nécessaire, nous avons activé la carte réseau (rien de plus).
- Centos : 7-2009 ✅,
- Debian : 11.5 ❌,
- Ubuntu desktop : 22.04 ❌, 22.10 ❌, 20.04 ❌,
- Ubuntu Server : 22.04 ❌, 22.10 ❌, 20.04.4 ❌, 18.04.4 ❌,
- Mint : 21 Cinnamon ❌,
- Slackware : 15 amd64 ❌,
- Kali : 2022.4 ❌ (ova téléchargé sur le site officiel),
- Open Mandriva Lx : platinium candidate plasma ❌,
- Gentoo : 2022-11-12 ❌ (en live uniquement car l’installation n’a pas réussi).
Notes à propos du DNS
Vous pourriez vous demander pourquoi, dans les deux solutions précédentes, je vous ai conseillé de mettre les deux routeurs dans chacune des annonces.
Après tout, pourquoi chaque routeur, s’annonçant comme passerelle, ne pourrait pas s’annoncer seul comme serveur DNS ? L’autre routeur faisant de même les machines clients sauraient qu’il y a deux serveurs DNS et on pourrait même imaginer que les priorités soient gérées aussi pour les serveurs DNS…
Mais Windows et Android n’apprécieront pas car chaque annonce contenant des informations DNS va remplacer la configuration précédentes (et pas s’y ajouter). S’ensuit que ces deux systèmes remplacent leurs serveurs DNS à chaque annonce reçue.
D’où mon conseil : les deux routeurs annoncent l’ensemble des serveurs DNS à chaque fois, vos configurations en seront d’autant plus stables.
Et après ?
D’habitude, c’est à ce moment de l’article que je conclu d’un « Et là tout marche, le problème est résolu, voici comment aller plus loin ». Mais pas aujourd’hui…
On voulait passer toute la configuration haute disponibilité en IPv6 et on doit bien admettre que ça n’a pas réussi. D’abord la synchronisation des états des pare-feux ne peut se faire qu’en IPv4 (dont acte mais on peut se dire que c’est pas dramatique). Ensuite, et c’est surtout là que ça blesse, les priorités sur les passerelles ne sont pas toujours prise en charge (mis à part Centos, les distributions Linux la gère mal).
Si les documentations et autres cours en ligne passent en général IPv6 sous silence pour ne donner d’exemple qu’avec IPv4, c’est peut-être parce que leurs auteurs ne savent pas comment fonctionne IPv6 mais il est difficile de leur en vouloir vu les problèmes et incompatibilités décourageantes qu’on rencontre quand on veut faire l’effort de se mettre à jour.