Petit achievement aujourd’hui, j’ai réussi à avoir l’IPv6 de mon fournisseur d’accès directement depuis mon routeur EdgeRouter-4. Pour remettre en contexte, ma box SFR est dans son carton. Le seul équipement de SFR que j’utilise est l’ONT, qui converti un signal fibre en cuivre entre-autre.
Jusqu’à présent, j’utilisais un tunnel IPv6-in-IPv4 fourni par Hurricane. C’est gratuit, la bande passante est plutôt grosse, mais n’arrange sûrement pas à réduire la latence par rapport à une connectivité IPv6 directement fournie par l’opérateur (du moins, je pense).
Pourquoi ?
Avant de détailler comment j’ai fait, j’aimerais expliquer pourquoi je n’utilise pas la box de l’opérateur, après tout elle est gratuite et propose plein de fonctionalités, non ? C’est vrai mais… non, pour plein de raisons :
- en matière de sécurité, je trouve totalement malsain d’avoir une box opérateur, propriété de l’opérateur, contrôlée par l’opérateur au sein de mon réseau local. L’utilisation d’un routeur sous mon contrôle évite une fuite des données vers l’opérateur. Distinction franche entre mon réseau local et le réseau opérateur.
- si je change d’opérateur, je n’ai pas à reconfigurer mon réseau interne. Seul la patte WAN sera modifiée. J’ai zéro adhérence avec mes opérateurs Internet ou de téléphonie.
- je n’ai plus de téléphone fixe et la merdasse télévisuelle ne m’encourage pas à utiliser le décodeur fournit. Au pire, il s’agit juste de VLAN à faire passer, donc là aussi la box n’est pas indispensable
- j’ai vraiment plus de fonctionnalités avec mon routeur que toutes les box opérateurs réunies. Je peux monter un tunnel GRE, IPSec v2, avoir des routes conditionnelles etc… Il s’agit de fonctionnalités que j’utilise.
- Ca marche (avez-vous déjà utilisé l’interface d’administration de la box Orange) ?
- Ca marche vraiment. Impossible de faire fonctionner un tunnel IPSec le plus bidon possible en utilisant la box Orange.
- Ca marche même sous stress, là où la box opérateur plante avec un simple DoS (désolé Nunzz ^^ »)
Il est clair que remplacer sa box n’est pas à la portée de tout le monde, mais rien que pour la fiabilité, ça donne envi.
Mimer la box opérateur
Le plus simple pour trouver comment faire est encore d’analyser la communication entre la box opérateur et le réseau opérateur. Cela tombe bien, j’avais justement un switch manageable ce qui m’a permis de mettre en place un port mirroring et ainsi pouvoir sniffer le traffic depuis mon pc portable en live.
Contrairement à ce que j’avais lu ici ou là, j’ai été ravi de lire que l’obtention d’un bloc IPv6 se fait de manière non seulement simple mais suivant les standards (enfin presque) ! En effet, le bloc IPv6 s’obtient via le protocole DHCPv6 en 4 messages :
- SOLICIT: le client hurle (broadcast) à la recherche d’un serveur DHCP
- ADVERTISE: un serveur DHCP répond à l’aide
- REQUEST: le client souhaite obtenir une délégation sur un bloc IPv6
- REPLY: le serveur, tout aimable qu’il est, répond positivement à la requête
Bloc IPv6 vs IPv4
De prime abord, le processus pour obtenir une IPv6 semble plus compliquée. Cette apparente complexitée s’explique par le fait qu’il n’y a pas de NAT en IPv6 (enfin si mais on va supposer que non). Cela signifie que tout équipement souhaitant aller sur Internet ne peut pas utiliser l’IP du routeur, comme cela se fait en IPv4 mais doit avoir sa propre IPv6 routable. Routable par opposition à une IPv6 privée (commençant par fe80:) qui pourrait être l’équivalent du 192.168.x.y en IPv4.
Pour répondre à cette problématique d’IP routable, on a deux choix de réseaux :
- il n’y a plus de réseau local, uniquement le réseau de l’opérateur dont vous et tout vos équipements font parti. Cette solution n’est absolument pas raisonnable tant pour l’usager que pour l’opérateur d’un point de vue de la sécurité.
- le réseau local de chaque utilisateur et le réseau opérateur, séparés par un routeur
La solution retenue est bien entendue la seconde. Sans IP routable, la communication d’un périphérique est limitée à son réseau local. L’obtention d’une IPv6 se fait donc par un appareil se trouvant lui aussi dans le réseau local, c’est à dire la box opérateur.
Cette box va donc demander à l’opérateur quels sont les IPs qu’il peut distribuer en local, c’est le prefix delegation (PD). L’opérateur fournit à chaque box, qui en fait la demande, une délégation sur un préfixe IPv6 (ou bloc IPv6), ce qui va permettre deux choses :
- la box va pouvoir distribuer une IP dans ce pool aux objects connectés
- ce bloc sera routé depuis Internet vers la box (pinger une IP de ce pool va arriver sur le routeur, qui forwardera (ou pas) le paquet)
Patcher Wide-DHCPv6
L’OS EdgeMax est tout à fait en mesure de gérer intégralement la stack IPv6, au moins en CLI vu que la GUI tarde à le gérer proprement. En tant que client DHCPv6, il utilise wide-dhcpv6 pour obtenir une prefix delegation. Là où ça coince, est que le serveur attend deux informations qu’il n’est pas possible de setter dans la configuration de wide-dhcpv6 :
- le client identifier (option 1) avec un DUID de type 3 (link-layer adress) et non 1 (link-layer adress plus time). Ce pré-requis est obligatoire. Actuellement la valeur est l’adresse mac de la box côté LAN mais pour plus de sûreté, prenez la valeur indiquée dans la capture
- le vendor class (option 16) qui est l’id du modèle de la box. Il s’agit d’un paramètre optionnelle pour le moment.
Vu que Ubiquiti est respectueux de la licence GPL, j’ai pu récupérer le code source patché de wide-dhcpv6 et commencer à travailler me casser les dents dessus.
Fixer les bugs n’étaient pas une mince affaire. Le EdgeRouter fonctionne sous une architecture MIPS. J’ai donc du monter une vm avec qemu, elle-même dans une VM linux puisque je suis sous Windows, afin de pouvoir compiler la chose. Le débuggage avait comme un arrière goût des années 80 : une compilation qui prend 15 minutes à chaque fois et des outils franchement pas pratique, genre gdb. Et une doc complètement inexistante bien entendu, avec des noms de variables incompréhensible. Au-secours !
Mais j’ai fini par me sortir de ce sable mouvant, voici donc les patches ubnt-wide-dhcpv6-201.tar
Comme c’est ultra chiant à compiler, voici également le binaire à glisser à la place de /usr/sbin/dhcp6c sur le routeur.
Au passage, Ubuntu sous Hyper-v Gen 2, ça marche 🙂
Configurer le Edgerouter
Il va falloir au préalable récupérer quelques informations contenues dans la capture faite précédemment. Elles sont indispensables pour pouvoir configurer proprement le EdgeRouter :
- le DUID dans le message SOLICIT
- le vendor class value dans le message SOLICIT
- le prefix
Il y a 3 sections à configurer :
- le dhcpv6 pour obtenir un préfixe côté WAN
- le radvd (router-advert) pour distribuer les préfixes côté LAN
- l’override de l’adresse mac de l’interface WAN
Ci-dessous ma configuration EdgeRouteur :
interfaces { ethernet eth0 { address 192.168.x.254/24 address 2a02:8428:xx:xx00::ff/64 description lan0 ... ipv6 { dup-addr-detect-transmits 1 router-advert { cur-hop-limit 64 link-mtu 0 managed-flag true max-interval 600 name-server 2a02:8428:xx:xx::ff other-config-flag false prefix 2a02:8428:xx:xx::/64 { autonomous-flag true on-link-flag true preferred-lifetime 14400 valid-lifetime 28800 } reachable-time 0 retrans-timer 0 send-advert true } } } ethernet eth2 { address dhcp description wan0 ... dhcpv6-pd { duid 00030001e45d41dexxxx no-dns pd 1 { interface eth0 { prefix-id 1 } prefix-length 56 } prefix-only rapid-commit disable } mac e4:5d:41:de:xx:xx } }
SFR distribue un préfix /56. Un réseau local avec radvd utilise un préfix en /64. Cela signifie que vous pouvez avoir 256 réseaux locaux. Récupérez le préfixe distribué par SFR (depuis la box par exemple) et choisissez un sous-préfixe en /64 pour votre LAN. C’est ce qu’il faudra renseigner dans interfaces -> ethernet ethx -> ipv6 -> router-advert -> prefix.
Fixez également l’IPv6 de l’interface LAN du routeur, afin de pouvoir spécifier un serveur DNS qui écoute sur la stack IPv6, c’est le paramètre interfaces -> ethernet ethx -> ipv6 -> router-advert -> name-server.
Enfin remplacer l’adresse mac de l’interface WAN par celle de l’opérateur. Ce n’est pas obligatoire mais devrait mieux supporter les évolutions du réseau de l’opérateur.
Afin de mieux mimer les requêtes DHCPv6 (et parce que de toute façon il n’est pas possible de générer le bon fichier de conf en cli), on va écraser complètement le fichier généré par la section dhcpv6-pd par notre propre version.
# interface wan interface eth2 { request domain-name-servers, domain-name; duid 00:03:00:01:e4:5d:41:de:xx:xx; send ia-pd 1; # récupéré par le sniff, il s'agit de mettre la valeur brute du vendor class send raw-option 16 00:00:a0:0c:00:40:6e:65:75:66:62:6f:78:5f:4e:42; script "/opt/vyatta/sbin/ubnt-dhcp6c-script"; }; id-assoc pd 1 { prefix ::/0 0 0; # interface lan prefix-interface eth0 { sla-id 1; sla-len 8; }; # interface lab prefix-interface eth0.213 { sla-id 213; sla-len 8; }; };
Je donne ici un exemple où je récupère un préfix en /56 de SFR et j’assigne deux /64 pour mes deux réseaux locaux :
- eth0, qui est le réseau principal
- eth0.213 qui est mon réseau lab
Cela permet de mettre en évidence le rôle des paramètres sla-id et sla-len. sla-len est la différence entre le /56 donné par l’opérateur et le /64 que j’assigne à un réseau, soit 64-56=8.
sla-id est de longeur sla-len, il peut donc avoir une valeur entre 0 et 255 inclus. C’est le nombre qui sera suffixé au préfix. Par exemple mon préfixe donné est 2a02:8428:1234:3300::/56. Alors :
- avec un sla-id de 1, le subnet de eth0 sera 2a02:8428:1234:3301::/64
- avec un sla-id de 213, le subnet de eth0.213 sera 2a02:8428:1234:33d5::/64
Il ne reste plus qu’à rendre la configuration et le binaire persistent, à l’aide de /config/user-data et d’un petit script de restauration. Jetez un oeil à mon article de présentation de l’ER-4 pour se faire.
Plus
Ca marche aussi avec Sosh / Orange. Il faudra sniffer le traffic entre la box et l’ONT afin de récupérer les bonnes options et valeurs.
Trashinator
5 juillet 2020 at 22:11Hey,
Je deterre un peu ce post pour deux raisons :
> La premiere pour te remercier car il m’a bien aidé à configurer la connexion IPV6
> La seconde parce que je suis bloqué à la derniere etape.
Je m’explique :
Toute la configuration est faite mais je n’ai pas le bon binaire dhcp6c (le tien ne fonctionne pas sur ERX en firmware 1.10.x).
J’aimerais bien le re-compiler et appliquer tes patchs (ou compiler directement la version opnsense pour MIPS https://github.com/opnsense/dhcp6c) mais je n’arrive pas à trouver la bonne technique.
Tu te souviens comment tu avais fait?
J’ai tenté aussi de mettre à jour le firmware en 2.x du coup je suis clairement obligé de compiler vu que ca passe de Debian Wheezy à Stretch.
T’aurais pas une piste à me donner?
Merci beaucoup !
veovis
28 septembre 2020 at 20:32Pour compiler, je crois avoir tout tenter mais le cross-compiling est juste une pure horreur. J’ai fini par compiler directement sur l’ER en y installant gcc et compagnie. C’est crade sur le moment mais au moins ça marche !