Délégation de préfixe IPv6 d'une Bbox vers un routeur VyOS

Fut un temps je disposais de mon propre réseau /48 IPv6, que j’annonçais en BGP depuis des VPS dans le cloud. Pour en profiter je montais un tunnel wireguard entre chaque routeur de bordure et chez moi. L’une des raisons était que Bouygues Tel ne me fournissait pas d’IPv6 en VDSL. Suite à l’augmentations des tarif du RIPE NCC et mon passage à la fibre optique, j’ai choisi d’arrêter cette option et de configurer à la place une délégation de préfixes vers mon routeur VyOS pour pouvoir gérer moi-même l’adressage IPv6 de mes hôtes et serveurs.

Théorie

L’idée de la délégation est la suivante : en IPv6 une box domestique dispose d’un « gros » réseau : généralement un /56. La taille d’un réseau classique en IPv6 étant /64, on peut donc segmenter ce /56 en 256 sous-réseaux : 64 - 56 = 8 bits de sous-réseau ; 28 = 256. La box ne les utilise pas tous, typiquement un seul est utilisé pour le Wi-Fi et l’Ethernet, peut être un autre pour le services TV et ToIP. On peut donc déléguer une partie des réseaux non-utilisés à un équipement tiers qui s’occupera de les router à la place de la box. Cette dernière sera consciente que tel sous-réseau est routé par tel équipement et saura donc aiguiller les flux en conséquence. Le bloc délégué peut généralement contenir plusieurs /64, c’est la responsabilité de l’équipement derrière de le segmenter.

Chez Bouygues, c’est un peu étrange, on nous propose… trois /64 distincts indépendants. En gros, le dernier caractère de l’adresse du préfixe peut prendre 4 valeurs :

  • xxx0, c’est le LAN géré par la box (Wi-Fi, etc.),
  • xxx1 est délégable,
  • xxx2 est délégable,
  • xxx3 est délégable.

On peut attribuer chacun de ces préfixes manuellement à un équipements donné, soit de façon dynamique. Étudions comment configurer cela avec un routeur VyOS, mais avant penchons-nous sur le fonctionnement de la délégation de préfixe.

SLAAC et DHCPv6

Rappelons le rôle de SLAAC et DHCPv6. SLAAC est un mécanisme d’IPv6 qui permet d’autoconfigurer une adresse dans un réseau /64 (à la manière d’APIPA), mais aussi de récupérer l’adresse de la passerelle (de type link-local) et d’autres paramètres comme le MTU. Cela se fait grâce aux Router Advertisement (RA) et Neigbor Advertisement (NA).

On a en parallèle le DHCPv6, très facultatif, qui lui fourni également une adresse /128 (donc non dérivable en adresses temporaires contrairement à SLAAC), et d’autres infos notamment custom. Et aussi… la capacité à déléguer des préfixes.

Les deux systèmes ne sont pas incompatibles, d’ailleurs DHCPv6 ne peut pas toujours se passer de SLAAC, qui fourni la passerelle. Et c’est SLAAC qui indique aux client qu’il faut aller toquer à la porte du DHCP (flag M dans les RA) ! On a ainsi souvent plusieurs adresses IPv6 dans un même réseau : une liée au DHCPv6, et plusieurs /64 liées à SLAAC (la principale et des temporaires pour éviter le pistage) et c’est tout à fait normal. L’adresse attribuée au DHCP (quand il y en a une) n’a souvent pas la même fonction que les autres, mais ne rentrons pas dans les détails.

DHCPv6-PD

Ce qui nous intéresse ici, c’est DHCPv6-PD, décrit dans les RFC 3769 et 3633. Alors que l’attribution d’adresses IP se fait par ce que l’on appelle un IA_NA pour Identity Association - Non-temporary Address, de façon équivalente l’attribution de préfixe délégué se fait par un IA_PD. Sans rentrer dans le détail des mécanismes, le routeur demandeur et le délégataire se mettent d’accord sur un transfert de responsabilité d’une liste de préfixes. Ensuite, le demandeur va devoir annoncer ces préfixes dans ses RA pour que les clients puissent se configurer ; il prendra lui-même une adresse dans chacun de ces réseaux : soit avec un ID d’interface (partie « hôte ») fixé, soit en EUI-64.

💡 Utilité de cette adresse
De ce que j’ai observé, cette IP est utile pour que le routeur sache router les flux en retour : si je l’enlève, les paquets des clients sortent bien sur Internet, les paquets retours arrivent jusqu’au routeur mais ne sont pas routés jusqu’aux clients. Pour moi, la link-local suffisait, mais visiblement non.

Pratique

Côté Bbox

Passons à la pratique. Côté box, j’ai un menu Délégation de préfixe IPv6 dans Réglages avancés > DHCP • IPv6. Je peux choisir un préfixe parmi trois disponibles, et l’affecter à un équipement. Celui-ci doit déjà être connu du DHCP donc si rien n’est configuré côté routeur, il n’apparaitra pas. On peut également définir un niveau de sécurité, ce qui correspond à la politique du pare-feu :

  • Faible = pas de filtrage
  • Normal = flux entrants bloqués
  • Elevé = flux entrants et sortants bloqués
Menu de la Bbox
Figure 1 — Menu délégation

Côté VyOS

Partons d’une configuration simple avec eth0 connecté à la box0. Il faut activer DHCPv6 pour s’associer à la box et pouvoir configurer la délégation par la suite. Dois-je configurer une adresse SLAAC ? Non, ce n’est pas utile, sauf si je veux émettre du trafic IPv6 avec ce routeur, auquel cas cela peut être préférable (je n’ai pas d’avis franc là dessus et je connais encore mal les bonnes pratiques IPv6). Par contre, mon routeur doit écouter SLAAC pour récupérer la passerelle ! Je pourrais la configurer à la main, avec le link-local de ma box, mais je n’ai pas de garantie qu’il reste le même dans le temps. Je préfère donc que la route soit définie automatiquement. On va donc récupérer le FE80 en écoutant les RA de la box.

[edit]# set int eth eth0 address dhcpv6

Mais il y a un piège : par défaut Linux n’accepte pas les RA sur les interfaces routées. Normal, on est sensé router le trafic, pas se comporter en client. D’ailleurs si je configure ipv6 address auto sur l’interface pour activer l’autoconfiguration avec SLAAC, le routage IPv6 est désactivé sur l’interface. Dans ce cas précis on a légitimement besoin du routage, donc on peut forcer la main en modifiants des paramètres sysctl. Le paramètre accept_ra défini à 2 force l’écoute des RA y compris quand le routage IPv6 est activé. Quand accept_ra est actif sur une interface, accept_ra_defrtr est automatiquement activé : il permet d’accepter une route par défaut.

[edit]# set system sysctl param net.ipv6.conf.eth0.accept_ra value 2

Le routeur doit être redémarré pour prise en compte. Il faut ensuite configurer la délégation de préfixe : la demander d’une part, et l’attribuer à une interface LAN (ici eth1.200). On précise adress 1 pour que l’interface prenne une IP dans ce réseau délégué ; ici la partie interface ID (partie hôte) vaut 1, donc l’adresse sera du type : x.x.x.D::1. Le D va dépendre de quel préfixe la box nous délègue. Enfin, on peut préciser la longueur du préfixe que l’on demande. Ici c’est la valeur par défaut.

emile@rt-core-1.emiletouron.fr# show int eth eth0
address dhcpv6
dhcpv6-options {
    pd 0 {
        interface eth1.200 { 
	        address 1
        }
    length 64
    }
}

On obtient une IP unique (/128), c’est le but de DHCP :

inet6 2001:860:2cf1:26c0:dda7:dc02:71d7:88e2/128 scope global

Ce qui nous intéresse ici n’est pas vraiment l’adresse mais la délégation de préfixe que cela va permettre. En revanche cette adresse est indispensable au routage du PD, la supprimer coupe la connexion des préfixes délégués comme expliqué plus haut.

On observe aussi la création d’une adresse avec le préfixe x:x:x:26c1::/64 sur l’interface déléguée. C’est une bonne nouvelle car ça montre que l’on a bien reçu notre préfixe délégué, on va pouvoir envoyer des RA et router !

11: eth1.200@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether bc:24:11:f1:5b:8a brd ff:ff:ff:ff:ff:ff
    inet6 2001:860:2cf1:26c1::1/64 scope global
	    valid_lft forever preferred_lft forever
    inet6 fe80::be24:11ff:fef1:5b8a/64 scope link
        valid_lft forever preferred_lft forever

Pour envoyer les RA il reste une étape de configuration :

emile@rt-core-1.emiletouron.fr# show service router-advert
interface eth1.200 {
    prefix ::/64 { 
    }
}

On aurait pu écrire prefix 2001:860:2cf1:26c1::/64, mais ::/64 permet d’annoncer chaque préfixe assigné à l’interface. C’est particulièrement utile lorsque l’on a des délégation de préfixe dynamique côté box car on couvre le cas où le préfixe alloué évolue au cours du temps, voir la doc à ce sujet.

Résumé de la configuration

emile@rt-core-1.emiletouron.fr# show
 interfaces {
     ethernet eth0 {
         description "WAN"
         address dhcpv6
         dhcpv6-options {
             pd 0 {
                 interface eth1.200 {
                     address 1
                 }
             length 64
             }
         }
     ethernet eth1 {
         vif 200 {
             description "LAN délégué"
         }
     }
 }
 service {
     router-advert {
         interface eth1.200 {
             prefix ::/64 {
             }
         }
     }
 }
 system {
     sysctl {
         parameter net.ipv6.conf.eth0.accept_ra {
             value 2
         }
         parameter net.ipv6.conf.eth0.accept_ra_defrtr {
             value 1
         }
     }
 }

Et après ?

Après, on voudrait utiliser d’autres préfixes, pour segmenter. Il en reste deux, c’est peu mais on peut déjà séparer les serveurs des clients. Après des soirées de bricolage, je n’ai pas réussi à faire fonctionner 2 préfixes en parallèle de façon stable.

Quand on demande deux préfixes depuis eth0, la box nous attribue 2 fois le même. L’astuce est d’utiliser une interface MACVLAN en mode VEPA avec une DUID (identifiant DHCP) différent :

 pseudo-ethernet peth0 {
     address dhcpv6
     dhcpv6-options {
         duid 00:03:00:82:88:9a:58:f6:0f
         pd 0 {
             interface eth1.30 {
                 address 1
             }
         }
     }
     source-interface eth0
 }

Pour éviter que le trafic ne sorte par eth0 on peut créer une table de routage dédiée, et forcer les paquets du préfixe délégué à passer par là :

 protocols {
     static {     
         table 30 {
             route6 ::/0 {
                 next-hop fe80::46ad:b1ff:fe72:d99c {
                     interface peth0
                 }
             }
         }
     }
 }


policy {
     route6 deleg_30 {
         interface eth1.30
         rule 10 {
             set {
                 table 30
             }
             source {
                 address 2001:860:2cf1:26c2::/64
             }
         }
     }
 }

Pour activer accept_ra la difficulté est que peth0 n’existe pas au boot, elle est créée plus tard, donc la commande set system sysctl parameter ...accept_ra value 2 ne fonctionne pas. Il faut passer par le script postboot et on en profite pour passer l’interface en mode VEPA :

sudo vim /config/scripts/vyos-postconfig-bootup.script

#!/bin/sh

# On attend que peth0 arrive vraiment
while [ ! -d /proc/sys/net/ipv6/conf/peth0 ]; do
    sleep 1
done

echo 2 > /proc/sys/net/ipv6/conf/peth0/accept_ra
echo 1 > /proc/sys/net/ipv6/conf/peth0/accept_ra_defrtr

ip link set dev peth0 type macvlan mode vepa

On voit bien le ping sortir par peth0 (puis eth0 qui est l’interface mère) avec la bonne MAC, mais la réponse n’arrive pas. Donc la box drop, pour une raison qui m’échappe.

J’ai essayé toutes les combinaisons possibles sur le VyOS ; la fonctionnalité de DHCPv6-PD étant assez récente sur la Bbox et l’interface web pas toujours au point, je ne vais pas cramer davantage d’énergie là dessus pour le moment car ça semble bien buggé. A suivre dans de prochaines versions de l’OS Bbox :)