Tunnels IPv6 pour la maison
Table of Contents
J'ai voulu avoir de l'IPv6 à la maison. Mon opérateur Internet ne fournit que de l'IPv4, il faut donc tunneller d'une façon ou d'une autre. J'ai une Kimsufi à disposition, avec un accès IPv6 natif, j'ai donc voulu l'utiliser comme point de sortie.
Bien sûr, une solution est d'utiliser un fournisseur de tunnel comme HE ou SixXS, mais où est l'intérêt de ne pas faire les choses soi-même ?
1 Creusage de tunnels
Beaucoup de technologies qui permettent de faire des tunnels IPv6 à travers un réseau IPv4 :
Nom | Type | Usage |
---|---|---|
6in4 | Routeur - Routeur | Un lien IPv6 (typiquement entre routeurs) explicitement configuré entre les deux extrémités |
GRE | Routeur - Routeur | Une technique d'encapsulation générique Cisco (depuis normalisée) avec quelques fonctionnalités en plus |
6to4 | Routeur - Internet | Un lien IPv6, les adresses sont dans 2002::⁄32 et on inclut dans l'adresse IPv6 l'adresse IPv4 (publique !) du routeur. Il y a besoin de relais sur l'Internet (pour le sens Internet -> Routeur) |
ISATAP | Hôte - Hôte | Deux hôtes (éventuellement routeurs pour leurs réseaux respectifs) qui peuvent se parler en IPv4, avec quelques options d'autoconfiguration. Prévu pour un réseau local. |
6over4 | Hôte - Hôte | Comme ISATAP, mais les hôtes doivent se parler en IPv4 multicast (typiquement, ils sont sur le même LAN). Pas intéressant par rapport à ISATAP, mais historiquement le premier. |
Teredo | Hôte - Internet | Un hôte (éventuellement derrière un NAT) qui accède à l'Internetv6 |
IPsec | Routeur - Routeur | Initialement prévu pour créer un tunnel sécurisé entre deux réseaux |
Quand on a un point de sortie, la technique idéale est 6in4, ou éventuellement IPsec en mode authentification (le chiffrement est peu intéressant, puisque couvrant uniquement la partie du trafic de la maison au point de sortie, et uniquement pour l'IPv6…).
2 Plan du réseau
Le serveur / point de sortie utilise lui-même des adresses IPv6. Le réseau côté maison a besoin d'au moins deux préfixes, pour le Wifi et pour le filaire. Or, OVH ne fournit aux kimsufi qu'un seul /64… Il va donc falloir découper en plusieurs morceaux. J'ai choisi /80, attribué comme suit :
Figure 1: Schéma réseau
Où :
- 2001:db8:a:b::/64 est le préfixe attribué au point de sortie ;
- le premier /80 est attribué aux différents services qui tournent sur la machine ;
- les /80 suivants pour la maison ;
- en vert le tunnel entre le routeur Wifi à la maison et le point de sortie ;
J'ai utilisé des adresses ULA pour les extrémités du tunnels, mais en
fait il n'y en a pas vraiment besoin : une fois qu'on a commencé à
découper notre /64, autant aller jusqu'au bout. Ça permet juste de
bien reconnaître les adresses dans les fichiers de configuration et
dans les
tcpdump
.
3 Problèmes
Il y a deux problèmes avec cette façon de faire. Le premier est évident : on utilise des préfixes qui font plus que /64. Cela nous fait essentiellement perdre les mécanismes d'auto-configuration sur les réseaux de la maison.
Le deuxième est un peu plus subtile. Le /64 fournit par OVH n'est pas vraiment routé jusqu'à nous. Si c'était le cas, tous les paquets à destination du /64 seraient livrés à 2001:db8:a:b::1 (par exemple), et notre routage interne avec les /80 lui serait transparent. À la place, le dernier routeur s'attend à être directement connecté à ce /64, et à pouvoir faire directement un NS et recevoir une réponse pour chaque adresse. Il va donc falloir mettre en place sur l'interface externe un proxy NDP, qui fera croire au routeur que toutes les adresses sont directement connectées.
4 Implémentation
4.1 Routage sur le point de sortie
On va configurer les adresses que l'on utilise sur la machine comme des /128 (ou éventuellement comme des /80, enfin bref), créer le tunnel, et ajouter les routes statiques vers la maison.
Quelques lignes dans
rc.conf
:
ifconfig_nfe0= "inet 203.0.113.197/24" defaultrouter= "203.0.113.254" ifconfig_nfe0_ipv6= "inet6 auto_linklocal" # entree statique pour le routeur : # http://travaux.ovh.net/?do=details&id=6819 # rtsold_enable="YES" ipv6_defaultrouter= "fe80::5:73ff:fea0:0%nfe0" ifconfig_nfe0_alias0= "inet6 2001:db8:a:b::1/128" ifconfig_nfe0_alias1= "inet6 2001:db8:a:b::22/128" ifconfig_nfe0_alias2= "inet6 2001:db8:a:b::25/128" ifconfig_nfe0_alias3= "inet6 2001:db8:a:b::80/128" # tunnel vers la maison gif_interfaces= "gif0" gifconfig_gif0= "203.0.113.197 198.51.100.56" ifconfig_gif0= "mtu 1480" ifconfig_gif0_ipv6= "inet6 -auto_linklocal" ifconfig_gif0_alias0= "fd93:1:2:3::1/127" ipv6_gateway_enable= "YES" ipv6_static_routes= "home_wifi home_wired" ipv6_route_home_wifi= "2001:db8:a:b:1:: -prefixlen 80 fd93:1:2:3::" ipv6_route_home_wired= "2001:db8:a:b:2:: -prefixlen 80 fd93:1:2:3::"
Si pf(4) tourne, on ajoutera :
table < home_nets> const persist { 2001:db8:a:b:1::/80 2001:db8:a:b:2::/80 } extif = "nfe0" tunif = "gif0" # Tunnel 6in4 vers maison pass on $ extif proto ipv6 pass from < home_nets> to any pass from any to < home_nets> # Éventuellement des règles plus restrictives pour contrôler ce qui # arrive à la maison
4.2 Configuration du routeur wifi
Le routeur est un Cisco 877W qui fait tourner 15.1(3)T4. En 12.2, j'ai vu que parfois, le routeur décide de ne pas répondre aux NS, ce qui est un peu gênant. On utilise DHCPv6 pour distribuer les adresses. L'interface Wi-Fi ne peut pas être configurée en IPv6, mais on peut la placer dans un bridge qui, lui, peut être configuré avec IPv6.
ipv6 unicast-routing ipv6 cef ! interface Dot11Radio0 description wireless bridge-group 1 ssid Coloc ! interface BVI 1 description bridge pour wireless ipv6 mtu 1480 ipv6 address 2001:DB8:A:B:1::1/80 ipv6 nd autoconfig default-route ipv6 nd managed-config-flag ipv6 dhcp server HOME_WLANv6 ! interface Vlan20 description vlan wired ipv6 mtu 1480 ipv6 address 2001:DB8:A:B:2::1/80 ipv6 nd managed-config-flag ipv6 dhcp server HOME_WIREDv6 ! interface range FastEthernet 0 - 2 switchport mode access switchport access vlan 20 description wired (vlan 20) spanning-tree portfast ! interface Vlan10 description vlan internet ip address dhcp ! interface FastEthernet3 description internet (vlan 10) switchport access vlan 10 ! interface Tunnel0 description tunnel vers serveur no ip address ipv6 address FD93:1:2:3::/127 tunnel source Vlan10 tunnel destination 203.0.113.197 tunnel mode ipv6ip ! ipv6 dhcp pool HOME_WIREDv6 address prefix 2001:DB8:A:B:2::/80 dns-server 2001:DB8:A:B::53 ! ipv6 dhcp pool HOME_WLANv6 address prefix 2001:DB8:A:B:1::/80 dns-server 2001:DB8:A:B::53 ! ipv6 route ::/0 FD93:1:2:3::1/127
Les interfaces Fa 0 - 2, utilisées pour le LAN filaire, sont mises en
portfast
. Sans le
portfast
, il faut ≈45 secondes à STP pour
accepter que je n'ai pas créé de boucle en branchant mon portable.
NetworkManager envoie
n RS avec un timeout de
t secondes pour la
réponse RA. Avec
n = 3,
t = 1 seconde (RFC2461), NetworkManager a
le temps d'abandonner plusieurs fois… Donc on passe en
portfast
.
4.3 Proxy NDP
Comme mentionné plus haut, l'un des soucis est que le routeur devant la KS s'attend à voir le /64 complètement à plat. Il faut donc un proxy NDP qui réponde à la place des machines qui sont à la maison.
Ça fait environ 300 lignes pour un programme qui écoute avec
libpcap
les NS sur l'interface externe et qui envoie les NA correspondants. Le
code est dans un
dépôt git (ou
interface gitweb). Avec le réseau
montré plus haut, j'appelle
ndp6
avec les options :
ndp6 -i nfe0 -p 2001:db8:a:b:1::/80 -p 2001:db8:a:b:2::/80
Les gens qui utilisent Linux sur le point de sortie seront intéressés
par
ndppd. Parmi les linuxeries, il y a la lecture de
/proc/net/ipv6_route
pour mettre à jour les réseaux proxifiés,
l'utilisation d'une
socket
AF_PACKET
pour écouter les paquets qui
ne nous sont pas destinés.
5 Soucis rencontrés
5.1 Clients DHCP
Avec ISC dhclient, lorsqu'une adresse est configurée par DHCPv6, elle est installée avec un préfixe en /64. C'est un bug dans le client DHCP (les annonces DHCP ne contiennent qu'une adresse, pas d'informations sur le lien local). La RFC 5942, section 5 explique le problème, disant que c'est ce qui arrive quand « the IPv6 subnet model is not understood by the implementers of several popular host operating systems ».
Le bug Debian #684009 contient un patch pour ISC dhclient (apparemment remonté upstream). De son côté, Network Manager ne fait ples confiance aux préfixes annoncé par les clients DHCPv6.
Le client WIDE dhcp6c a le bon comportement (à condition de lui dire de demander une adresse…), je n'ai pas testé son intégration avec Network Manager.
Le Windows 7 du boulot semble avoir le bon comportement.
5.2 Bizarrerie sur le DHCP côte WAN
Les serveurs DHCP de chez Virgin Media se comportent bizarrement. En particulier, après une coupure de courant, le routeur ne reçoit pas d'adresse jusqu'à ce que le modem câble se fasse rebooter. Pas quelque chose que je peux corriger de mon côté…