IPv6 à la maison

January 8, 2009 by nono
Catégories geekeries - Mots-clés ADSL FDN IPv6 Linux

FDN propose depuis peu une connectivité IPv6 à ses abonnés. Voilà comment ça se configure sur un routeur sous Debian. Bien entendu, les adresses IP (v4 comme v6) mentionnées ici sont les miennes, il conviendra de les adapter.

Le point de départ

Un PC x86 sous Debian Etch tout ce qu'il y a de plus banal. Il possède 2 interfaces ethernet (eth0 vers le réseau local et eth1 vers le modem ADSL) ; une interface virtuelle dummy0 est configurée en plus pour garder l'adresse IPv4 publique accessible même quand le lien PPP est tombé.

Le fichier interfaces

Le fichier /etc/network/interfaces contient la configuration des interfaces réseau de la machine, hors PPP. On lui ajoute, pour chaque interface concernée, une section IPv6. On peut en profiter pour forcer le lancement de radvd (cf plus loin) quand on monte une interface ethernet (la directive up). Au final, il ressemble à ça :

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 192.168.62.252
        netmask 255.255.255.0
        network 192.168.62.0
        broadcast 192.168.62.255
iface eth0 inet6 static
        address 2001:910:1021::1
        netmask 64
        up /etc/init.d/radvd restart

auto eth1
iface eth1 inet static
        address 10.0.0.2
        netmask 255.255.255.0
        network 10.0.0.0
        broadcast 10.0.0.255

auto dummy0
iface dummy0 inet static
        address 80.67.176.33
        netmask 255.255.255.255
        network 80.67.176.33
        broadcast 80.67.176.33
iface dummy0 inet6 static
        address 2001:910:1021:1::1
        netmask 64

L'adresse 80.67.176.33 est mon IP fixe publique. Les adresses IPv6 sont prises dans le sous-réseau /48 attribué par FDN ; chaque interface reçoit un /64.

radvd

Le démon radvd sert aux routeurs IPv6 à annoncer les préfixes locaux et un minimum de données de routage sur les différentes interfaces ethernet de la machine. Charge ensuite aux autres machines du réseau local d'ajuster leur configuration pour que « ça marche tout seul ». Sa configuration se trouve dans le fichier /etc/radvd.conf ; chez moi, il ressemble à ça :

interface eth0 {
        AdvSendAdvert on;
        prefix 2001:910:1021:0::/64
        {
                AdvOnLink on;
                AdvAutonomous on;
        };
};

La configuration PPP

Tout d'abord il faut ajouter les deux lignes suivantes au fichier de configuration de ppp (/etc/ppp/peers/fdn chez moi, mais ça dépend de votre config) :

ipv6 ,
ipparam fdn

La première ligne force pppd a négocier une adresse IPv6. Il s'agira probablement d'une adresse lien-local, mais peu importe, elle servira simplement à notre machine pour dialoguer avec l'équipement de FDN. La deuxième ligne est un paramètre qui sera passé en 6ème position au script /etc/ppp/ipv6-up, qui va lui-même le transmettre à ses collègues du répertoire /etc/ppp/ipv6-up.d sous le doux nom de PPP_IPPARAM. Vous voyez où je veux en venir ? Il suffit maintenant de poser un script /etc/ppp/ipv6-up.d/00defaultroute dont le contenu sera le suivant :

#!/bin/sh

if [ "$PPP_IPPARAM" = "fdn" ];
then
    /sbin/ip -f inet6 route del ::/0
    /sbin/ip -f inet6 route add ::/0 dev $PPP_IFACE
fi

Ne pas oublier de le rendre exécutable, et c'est gagné, on a une route par défaut.

Le routage

Maintenant, c'est la partie facile avec des petits détails à ne pas oublier. D'abord autoriser le routage IPv6 ; ça se passe dans le fichier /etc/sysctl.conf auquel on ajoute une ligne :

net.ipv6.conf.all.forwarding=1

On peut l'activer immédiatement au moyen de la commande suivante :

sysctl -w net.ipv6.conf.all.forwarding=1

Ensuite le firewall ; sur les noyaux Linux récents (par exemple le noyau 2.6.24-etchnhalf de Debian Etch), ça marche exactement comme en IPv4, il suffit de remplacer la commande iptables par ip6tables. Un exemple minimaliste :

#!/bin/sh

ip6tbl=/sbin/ip6tables

echo -n "Setting up IPv6 filter: "

/sbin/sysctl -w net.ipv6.conf.all.forwarding=0

$ip6tbl -F
$ip6tbl -X

$ip6tbl -P INPUT DROP
$ip6tbl -P OUTPUT ACCEPT
$ip6tbl -P FORWARD DROP

# conntrack
$ip6tbl -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ip6tbl -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

######################################################
#### local
# icmp, aucazou
$ip6tbl -A INPUT --protocol icmpv6 -j ACCEPT --match limit --limit 30/minute

# services locaux
$ip6tbl -A INPUT -p tcp --dport 22 -j ACCEPT
$ip6tbl -A INPUT -p tcp --dport 25 -j ACCEPT
$ip6tbl -A INPUT -p tcp --dport 53 -j ACCEPT
$ip6tbl -A INPUT -p udp --dport 53 -j ACCEPT
$ip6tbl -A INPUT -p tcp --dport 80 -j ACCEPT

######################################################
#### reseau interne
# on peut sortir
$ip6tbl -A FORWARD -i eth0 -o ppp+ -j ACCEPT

# ping
$ip6tbl -A FORWARD -p icmpv6 -j ACCEPT
# ssh vers les machines internes
$ip6tbl -A FORWARD -p tcp --dport 22 -j ACCEPT

/sbin/sysctl -w net.ipv6.conf.all.forwarding=1

echo "done."

À adapter à vos besoins bien entendu. Voilà, c'est prêt ! Reste à trouver ce qu'on va faire de 65534 autres sous-réseaux. ;-)