Blog-like notes

Retour d’expérience sur IPv6

Mettre en place une connexion IPv6

L’hébergeur auprès de qui je loue mon serveur dédié ne fournit pas de connectivité IPv6. Après avoir attendu plusieurs mois, en l’absence d’annonces concrètes de la part de l’hébergeur concernant une hypothétique disponibilité d’IPv6 dans le futur, j’ai décidé de ne plus attendre et de passer par un tunnel broker pour mettre en place moi-même une connexion IPv6.

Parmi les fournisseurs disponibles, j’ai choisi Hurricane Electric, essentiellement sur les conseils de Stéphane Bortzmeyer (invité de la Guilde le 12 avril 2011). Je ne m’étendrai pas sur la création du tunnel sur le site de Hurricane Electric, qui se fait en quelques secondes et ne pose aucune difficulté.

Une fois le tunnel prêt du côté de Hurricane Electric, il faut créer l’autre extrémité, sur mon serveur. Pour ça, j’ai ajouté les lignes suivants dans /etc/network/interfaces :

auto he-ipv6
iface he-ipv6 inet6 v4tunnel
      address 2001:470:1f12:f87::2
      netmask 64
      endpoint 216.66.84.42
      local 46.105.5.1
      gateway 2001:470:1f12:f87::1
      ttl 255
      post-up ip addr add 2001:470:1f13:f87::77/64 dev $IFACE

Le préfixe 2001:470:1f13:f87::/64 est celui qui m’a été attribué par HE. J’ai affecté à mon serveur une adresse quelconque parmi les 264 disponibles.

Mise à jour du pare-feu

Les règles du pare-feu nécessitent deux mises à jour.

D’abord, comme mon pare-feu bloque par défaut tout ce qui n’est pas explicitement autorisé, il faut explicitement autoriser le passage des paquets IPv6 encapsulés dans des paquets IPv4, en provenance ou à destination de l’autre extrémité du tunnel chez Hurricane Electric, via les deux règles suivantes :

# /sbin/iptables -A OUTPUT -p ipv6 -d 216.66.84.42 -j ACCEPT
# /sbin/iptables -A INPUT  -p ipv6 -s 216.66.84.42 -j ACCEPT

Ensuite, un « piège » à ne pas oublier est que Netfilter utilise deux jeux de règles complètement indépendants pour IPv4 et IPv6 ; les règles mises en place avec iptables ne concernent qu’IPv4, il faut utiliser ip6tables pour installer les règles contrôlant le traffic IPv6.

À quelques exceptions près, les règles pour IPv6 sont exactement les mêmes que pour IPv4, donc une façon simple de procéder est de définir, dans le script installant le pare-feu, une fonction shell se chargeant d’appeler les deux commandes iptables et ip6tables :

ipt() {
        /sbin/iptables  "$@"
        /sbin/ip6tables "$@"
}

et d’appeler cette fonction en lieu et place de iptables dans le reste du script.

Une exception notable est la règle relative au protocole ICMP, qui s’écrit différemment pour IPv4 et IPv6 :

# /sbin/iptables  -A INPUT  -p icmp   -j ACCEPT
# /sbin/ip6tables -A INPUT  -p icmpv6 -j ACCEPT
# /sbin/iptables  -A OUTPUT -p icmp   -j ACCEPT
# /sbin/ip6tables -A OUTPUT -p icmpv6 -j ACCEPT

Configuration des serveurs

Le serveur web

Le cas du serveur web, Apache httpd, est vite réglé : par défaut, il écoute déjà à la fois sur IPv4 et IPv6, il n’y a strictement aucune modification à apporter à sa configuration.

Les applications web tournant sur ce serveur (Friendica, Status.net, Horde et Owncloud) sont toutes compatibles avec l’usage d’IPv6.

Le serveur mail

Le serveur IMAP, Dovecot, n’écoute par défaut que sur les interfaces IPv4. Une ligne suffit pour changer ça, dans /etc/dovecot/dovecot.conf1 :

listen = *, [::]

Il en va de même pour le serveur SMTP, Postfix, dans le fichier /etc/postfix/main.cf2 :

inet_interfaces = all
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

Le serveur XMPP

Le serveur XMPP Ejabberd est le seul programme dont la configuration pour IPv6 a posé initialement un léger problème.

Par défaut, le serveur n’écoute qu’en IPv4. La méthode recommandée pour servir les deux protocoles est de dupliquer, dans le fichier de configuration /etc/ejabberd/ejabberd.cfg, toutes les sections définissant un listener et de spécifier explicitement dans chacune d’elle une adresse IPv4 ou IPv6.

Par exemple, le listener suivant :

{5222, ejabberd_c2s, [
        {access, c2s},
        {shaper, c2s_shaper},
        {max_stanza_size, 65536},
        starttls, {certfile, "/etc/ejabberd/ejabberd.pem"}
        ]}

deviendra :

%% IPv4 listener
{{5222, "0.0.0.0"}, ejabberd_c2s, [
        {access, c2s},
        {shaper, c2s_shaper},
        {max_stanza_size, 65536},
        starttls, {certfile, "/etc/ejabberd/ejabberd.pem"}
        ]}

%% IPv6 listener
{{5222, "::"}, ejabberd_c2s, [
        {access, c2s},
        {shaper, c2s_shaper},
        {max_stanza_size, 65536},
        starttls, {certfile, "/etc/ejabberd/ejabberd.pem"}
        ]}

Toutefois, sur une Debian Squeeze, une telle configuration est inopérante ; ainsi configuré, le serveur ne parvient pas à ouvrir simultanément une socket IPv4 et une socket IPv6. La raison en est que par défaut, sous Debian Squeeze, la liaison à une socket IPv6 entraîne automatiquement la liaison à une socket IPv4 sur la même adresse, sauf si le programme demande explicitement le contraire — ce que ne fait pas Ejabberd. Du coup, Ejabberd tente de se lier deux fois à la socket IPv4 : une première fois explicitement, et une seconde fois implicitement lors de la création du listener IPv6. La seconde tentative échoue naturellement avec l’erreur EADDRINUSE, conduisant Ejabberd à avorter son démarrage.

Ce problème peut se corriger de deux façons :

La seconde méthode est selon moi préférable, le comportement consistant à lier automatiquement une socket IPv4 quand on demande une socket IPv6 étant, à mon avis, une authentique Fausse Bonne Idée™.

Il suffit d’ajouter la ligne suivante au fichier /etc/sysctl.d/local.conf :

net.ipv6.bindv6only=1

Mise à jour du DNS

La dernière étape, une fois le bon fonctionnement du tunnel et de tous les serveurs vérifié, consiste simplement à publier un enregistrement AAAA dans le DNS, afin d’informer tous les clients potentiels que le serveur est joignable en IPv6. Le serveur DNS lui-même, qui est géré par le registrar de mon nom de domaine, est également joignable en IPv6, de sorte que le site est accessible par une machine ne disposerait que d’une pile IPv6.

  1. http://wiki.dovecot.org/MainConfig
  2. http://www.postfix.org/IPV6_README.html