lalahop
Categorie: Administration système

De Debian GNU/Linux Squeeze à Wheezy

Le Debian nouveau est arrivé. Malgré que j'ai attendu 2 semaines pour que d'autres essuient les plâtres, j'ai rencontré des problèmes lors de la mise à jour et je vais vous raconter tout ça.

Table des matières

Pour la procédure de mise à jour en elle-même, c'est du classique : apt-get update && apt-get dist-upgrade, changer le sources.list, apt-get update && apt-get upgrade puis dist-upgrade. apt-get install -f pour terminer l'installation après correction d'un truc qu'à foiré. Pour la version longue, voir, par exemple : De Squeeze à Wheezy… sur le blog de NicoLargo.

Backports

Attention, les backports ne sont plus sur une grappe de serveurs séparée des dépôts principaux. Voir l'annonce officielle.

Dovecot

On passe de la branche 1.x à la branche 2.x (sauf ceux qui utilisaient les backports). Le format du(des) fichier(s) de configuration a changé donc vous allez avoir des erreurs du genre :

doveconf: Warning: Obsolete setting in /etc/dovecot/dovecot.conf:1 ...

Ce n'est pas bloquant mais pour éviter de futurs problèmes, il suffit de suivre la procédure : Upgrading Dovecot v1.2 to v2.0. Faites quand même une copie du fichier de configuration actuel, au cas-où.

php5-suhosin

Si vous utilisez suhosin, vous allez avoir cette erreur durant le redémarrage d'Apache pendant la mise à jour :

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib/php5/20100525/suhosin.so' - /usr/lib/php5/20100525/suhosin.so: cannot open shared object file: No such file or directory in Unknown on line 0

La raison est que suhosin n'est plus disponible dans les dépôts Debian. J'avoue ne pas avoir creusé le sujet concernant la raison (manque de support/réactivité ? plus de mainteneurs Debian ? fonctionnalités de suhosin intégrées nativement dans PHP 5.4 ? Autre ?).

Il suffit donc de désinstaller php5-suhosin :

apt-get remove --purge php5-suhosin

sudo

NicoLargo prévient d'un problème avec sudo. En prévision, j'ai gardé une copie du fichier /etc/sudoers puis j'ai procédé à la mise à jour. Durant celle-ci, on m'a proposé de garder ma version de ce fichier ou de la remplacer. J'ai accepté le remplacement. J'ai ensuite remis mes 2 lignes personnelles (issues de l'ancienne version) dans la nouvelle version du fichier. Je ne déplore aucun dysfonctionnement.

rsyslog

Si vous n'avez pas accepté le remplacement du fichier /etc/logrotate.d/rsyslog (je l'ai refusé car j'avais effectué des modifs), vous aurez le message suivant :

Usage: /etc/init.d/rsyslog {start|stop|rotate|restart|force-reload|status}
invoke-rc.d: initscript rsyslog, action "reload" failed.
error: error running non-shared postrotate script for /var/log/syslog of '/var/log/syslog

La raison est que rsyslog n'a plus de commande « restart » mais « rotate ». Il suffit donc de corriger ça dans la directive « postrotate » de /etc/logrotate.d/rsyslog :

invoke-rc.d rsyslog rotate > /dev/null

Apache (dans un chroot uniquement)

Si vous avez créé un chroot pour votre Apache, vous aurez cette erreur :

Cannot load /lib/libnss_dns.so.2. into server: /lib/libnss_dns.so.: cannot open shared object file: No such file or directory

Cette lib a tout simplement été déplacée vers /lib/x86_64-linux-gnu/libnss_dns.so. Il suffit donc de corriger le fichier de configuration de votre Apache pour en tenir compte.

Mysql (dans un chroot uniquement)

Si vous avez créé un chroot pour votre MySQL, vous aurez cette erreur :

[ERROR] Error message file '/usr/share/mysql/english/errmsg.sys' had only 641 error messages, but it should contain at least 728 error messages.
Check that the above file is the right version for this program!

Il suffit de procéder à une mise à jour d'un fichier du chroot :

cp /usr/share/mysql/english/errmsg.sys /chemin/vers/le/chroot/usr/share/mysql/english/errmsg.sys

Sympa (plus précisément : wwwsympa, l'interface web)

Après la mise à jour, on a une erreur 500 et le log Apache qui dit :

(104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server
Premature end of script headers: wwsympa-wrapper.fcgi

et le log sympa indique :

err [robot ] Config error: wwsympa should run with UID 112 (instead of 33). *** Switching to maintenance mode. ***

J'utilise le wrapper donc je vérifie les permissions de /usr/lib/cgi-bin/sympa/wwsympa-wrapper.fcgi : sympa:sympa/755 ... De tête, là comme ça, je ne vois rien de nouveau. Ha si, il manque le setuid bit. Corrigeons :

chmod u+s /usr/lib/cgi-bin/sympa/wwsympa-wrapper.fcgi

Je redémarre sympa, je kill le processus wwwsympa et je reteste : l'erreur 500 est toujours là, l'erreur dans le log Apache aussi. Par contre, l'erreur a disparu du log de sympa.

Je vérifie les permissions dans /usr/lib/cgi-bin/sympa/ et /etc/sympa/. Dans le premier, tout est en sympa:sympa/755. Dans le second, tout est en sympa:sympa/644. Je ne vois rien à redire.

Quelques recherches sur le web plus tard, j'ai trouvé la solution : sympa: mod_fcgid fails with "Premature end of script headers: wwsympa-wrapper.fcgi".

ÉDIT du 16/06/2013 à 15h30 :
Si un /usr/sbin/apache2ctl graceful tue votre apache (« [apache2] <defunct> ») et que vous avez l'erreur suivante dans le log d'erreur apache (error.log par défaut) :

[error] FastCGI process 13780 still did not exit, terminating forcefully

Alors, il faut activer suexec :

a2enmod suexec && service apache restart

Fin de l'édit

ÉDIT du 25/06/2013 à 02h30 :
Si Sympa envoi le mail suivant au listmaster de manière intempestive :

file error - help_suspend.tt2: not found

C'est qu'un bot (lié à un moteur de recherche comme Google ou non) ou un humain a cliqué sur Aide -> une documentation destinée aux utilisateurs des listes de diffusion ; -> suspendre ou reprendre votre abonnement pour chaque liste; et que cette page (/wws/help/suspend) cause une erreur :

Sympa n'a pas pu renvoyer la page demandée pour la raison suivante :
file error - help_suspend.tt2: not found
Veuillez contacter le listmaster

Un tour sur un moteur de recherche permet de constater que mon installation de Sympa n'est pas la seule à rencontrer ce problème.

Comme j'ai installé Sympa avec apt-get, il est donc passé de la version 6.0.1 à 6.1.11. En récupérant Sympa sur le site officiel, on remarque que la version 6.1.11 ne dispose pas du fichier /web_tt2/help_suspend.tt2 :

tar tf sympa-6.1.11.tar.gz  | grep help_suspend

En revanche, on remarque que la version 6.1.12 dispose d'un tel fichier. Je l'ai donc récupéré de la version 6.1.12 pour le mettre dans le dossier /usr/share/sympa/default/web_tt2/ de ma version 6.1.11 by Debian. Cela fonctionne. Plus de messages d'erreur et l'utilisateur désireux d'avoir l'information peut l'obtenir.

Néanmoins, cette page reste en anglais comparé à toutes les autres pages de wwsympa. Je n'ai pas encore compris comment interagissent les fichiers de langues (fichiers po/gmo dans le source officiel) avec la version Debian ...Fin de l'édit

OpenDNSSEC

Je ne m'attendais pas à avoir de problèmes avec ce logiciel qui passe de la version 1.3.2-1 à 1.3.9-5 (numéro de version mineur tout ça tout ça) et pourtant, ils ont changé le schéma de la base de données sqlite utilisée comme le dit le message durant la mise à jour :

ERROR: database version number incompatible with software; require 2, found 1. Please run the migration scripts

Je n'ai trouvé que très peu d'infos, même le changelog, /usr/share/doc/opendnssec/changelog.gz, n'indique pas un changement de la base de données.

Apparemment, le script de migration est : /usr/share/opendnssec/migrate_keyshare_sqlite3.pl. Évidemment, ce script n'a pas fonctionné chez moi sinon c'est trop facile.

J'ai remarqué que la commande « ods-ksmutil key list » ne m'affiche plus les clés/les zones et qu'un message apparaît dans le log opendnssec :

Key (xxx) has gone straight to active use without a prepublished phase

Le problème est sérieux et je n'ai trouvé aucune solution viable : toutes mes tentatives, forcer la signature des zones, nettoyer les états, ..., ont échouées.

Partant du principe que tout était perdu (OpenDNSSEC n'a plus l'état des zones, les clés associées, rien ...), j'ai décidé de faire une sauvegarde des fichiers de configuration actuels, de réinstaller complètement OpenDNSSEC et de refaire la configuration à partir des fichiers sauvegardés. Solution radicale (mes zones sont temporairement invalides) mais efficace.

ÉDIT du 24/05/2013 à 19h30 :

LXC et le réseau

Suite à la mise à jour, il m'étais parfois impossible de me connecter en SSH avec l'un de mes conteneurs LXC. Une connexion SSH vers l'hôte fonctionnait parfaitement et le conteneur était démarré. J'allais commencer à chercher une solution à ce problème quand j'ai reçu un mail du robot de sécurité d'OVH qui me disait que, depuis quelques temps, ma machine émettait de la merde en ARP. Il s'avére que ce « quelques temps » était en fait depuis le moment où j'ai redémarré mon serveur (nouveau noyau tout ça tout ça) après la mise à jour. Étrange coïncidence, non ?

Je regarde les IPs mentionnées dans les requêtes ARP ... Tiens, le premier octet est toujours le même que l'IP du conteneur LXC : 87. ... À qui sont allouées ces IPs ? Des whois plus tard, je trouve de tout : OVH, Bouygues et d'autres ... Bizarre ... Mon conteneur se croirait-il sur un réseau /8 alors que son IP est explicitement configurée comme étant un /32 (config IP FailOver chez OVH) ? Vérification avec ifconfig : oui. Et c'est ainsi pour tous mes conteneurs LXC. Pourtant, les fichiers /etc/network/interfaces sont corrects et n'ont pas changé d'un octet ...

En fait, dans le fichier de config de chacun de mes conteneurs, j'avais une ligne comme ça :

lxc.network.ipv4 = 87.98.183.12

Elle n'a jamais posé problème avant, le fichier /etc/network/interfaces devait prendre le relai lors du démarrage du conteneur, je ne sais pas ... LXC doit désormais intervenir plus tard dans le processus de boot et doit croire qu'il s'agit d'une IP du réseau 87/8. Préciser un /32 dans ce fichier ne change rien car les up/down script prévus dans /etc/network/interfaces ne seront pas exécutés donc la gateway ne sera pas précisée donc vous perdrez l'accès à votre conteneur depuis l'extérieur.

La solution est bêtement de commenter la ligne ci-dessus. On ne touche pas aux autres lignes concernant le réseau (type, flags, link, ...), hein ! Un redémarrage des LXC plus tard, le problème est résolu.
Fin de l'édit

ÉDIT du 03/08/2013 à 20h00 :

postfix-policyd-spf-python

Depuis mon passage à Wheezy, j'avais remarqué, en lisant les logs, que la réception d'un mail par postfix prenait plus de temps. En fait, le MTA distant semble être mis en attente 1 minute. Tout le temps. Exemple :

Jun 30 01:28:14 localhost postfix/smtpd[29532]: connect from [...]
Jun 30 01:29:14 localhost postfix/smtpd[29532]: ADC3A271CA: client= [...]

Et c'est comme ça pour toutes les connexions entrantes. Ça ressemble fortement à l'expiration d'un timer. En mai/juin, je n'ai rien trouvé, ni dans le changelog de Postfix, ni en faisant quelques recherches, qui pourrait expliquer cette mise en attente.

Puis, j'ai quand même voulu résoudre ce problème. Le problème ne se produit pas sur une installation toute fraîche dans une VM. L'installation est minimaliste : juste Postfix, aucun milter, aucune policy, rien.

En désactivant tous les milter et policy, le problème disparaît. Après quelques recherches complémentaires, je trouve que c'est postfix-policyd-spf-python qui foire.

Le log de postifx-policyd-spf-python n'indique rien, si ce n'est Temperror pour tous les mails entrants depuis la mise à jour vers Wheezy. Exemple :

Jun 30 01:28:44 localhost policyd-spf[29538]: Temperror; identity=helo; client-ip= [...]
Jun 30 01:29:14 localhost policyd-spf[29538]: Temperror; identity=mailfrom; client-ip= [...]

Je ne sais pas d'où vient le problème avec précision : peut-être un problème dans les bibliothèques sous-jacentes comme pydns. J'utilise Python 2.7 donc ce bug ne semble pas me concerner.

Je me suis contenté de passer à la version codée en Perl : postfix-policyd-spf-perl. Ça juste marche ...
Fin de l'édit

Forcer l’IPv4 avec apt-get

Sur certaines de mes machines, j'ai de la connectivité IPv6, que ça soit en natif ou via un tunnel 6in4. Parfois, des hôtes ne sont pas atteignables en IPv6. Et quant ça arrive avec les serveurs de dépôt des paquets logiciels, comment on fait ?

Cela m'est arrivé avec backports.debian.org dont une des IPv6s du pool n'est pas atteignable depuis un bloc OVH mais ne pose pas de problème à travers un tunnel 6in4 HE. Cela arrive en ce moment avec mirror.ovh.net et, pour une fois, ça n'arrive pas qu'à moi, j'ai vu l'info tourner hier. Par contre, rien ne semble avoir été remonté à OVH ...

Je suis sûr qu'il y a plusieurs solutions pour forcer l'usage d'IPv4 avec apt-get (apt.conf, résolution, gai.conf ...).

Personnellement, j'ai choisi d'utiliser le processus de résolution du nom pour résoudre ce problème. En gros, je rajoute les lignes suivantes dans mon /etc/hosts :

#Modification temporaire (17/03/2013)
91.121.125.139 mirror.ovh.net
91.121.124.139 debian.mirrors.ovh.net

Et ça marche.

Dès la fin de l'apt-get update, je commente les lignes ajoutées afin de ne pas avoir une rustine qui me créera des problèmes dans le futur.

Quand root n’a plus l’autocomplétion

Depuis peu, sur mes machines, l'utilisateur root, via su/sudo (mais le problème doit être le même en login direct), l'autocomplétion, même des commandes les plus basiques, ne fonctionne plus.

J'ai résolu le problème en copiant le petit morceau suivant, que l'on trouve dans le .bashrc de tout utilisateur, dans le .bashrc de root (/root/.bashrc) :

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

L'autocomplétion juste re-fonctionnera dès le prochain login.

IPv6 pour Noël

Aux alentours de Noêl (2012 hein :P), j'ai décidé de passer mes "serveurs" en IPv6. Ce billet est donc une sorte de retour d'expérience/un avis et surtout pas un tutoriel. Il y a suffisamment de tutoriels sur les sujets que je vais aborder. Il n'y aura pas non plus trop d'explications théoriques ni de prêches "pourquoi il est temps de se bouger pour IPv6" (il est évident que c'est uniquement pour voir la tortue dansante sur http://www.kame.net/).

Table des matières

Ressources

Si vous débutez avec IPv6, je vous recommande la lecture suivante : Yet Another Reference for Delivering IPv6 to the Next Generation.

Vous y trouverez, entre autres, des explications détaillées des notions que je vais employer dans ce billet sans forcement les expliciter.

Passer à IPv6

Utiliser IPv6, ce n'est pas difficile, ça ne nécessite pas des connaissances d'un niveau extraordinaire en réseaux informatiques. Il n'y a même pas besoin de comprendre tout ce que je vais raconter ici car c'est de la garniture. Pour débuter par la pratique, il y a une montagne de tutoriels sur Internet, il suffit de les suivre et, ensuite, si l'intérêt vient, de se documenter pour comprendre petit à petit.

Pour moi, il y a clairement deux étapes :

  • Fournir une connectivité v6 à une machine. Cette étape est, comme je me tue à le répéter depuis le début de ce billet, facile. Sauf si comme moi, vous étudiez les différents "modes de fourniture", "for ze lulz".
  • Dans le cas d'un serveur, il convient également de vérifier que les services (httpd, dnsd, smtpd, ...) soient bien disponibles sur IPv6 comme sur IPv4. Cette étape est juste de la rigolade : la documentation de tous les logiciels serveurs sérieux indiquent, clairement et de manière évidente, la directive de configuration "kivabien". La palme revient à Dovecot (serveur POP/IMAP) dont la directive de configuration pour du dual-stack est indiquée dans le fichier de configuration lui-même, il n'y a plus qu'à décommenter la ligne.

La connectivité

Différence entre les méthodes de transition

Il y a plusieurs modes de fourniture d'adresses v6 : natif (votre opérateur réseau vous alloue un bloc), 6in4 (typiquement un tunnel chez Hurricane Electric), 6to4 (passerelles qui encapsulent de l'IPv6 dans de l'IPv4), Teredo (encapsulation au niveau UDP), ... En terme de qualité du service, il est souvent admis que l'on a : natif > 6in4 > 6to4 > Teredo.

Certaines sont obsolètes ou sur le point de l'être (6to4), d'autres méthodes existent mais ne conviennent pas à ma situation (je veux une connectivité IPv6 sur mes serveurs disposant d'une connectivité v4 uniquement).

Dans la suite, je ne parlerai que de natif, de 6in4 et de 6to4.

Natif

Bon, on va faire ça rapidement car ça se configure le plus simplement du monde. Chez OVH, il suffit de regarder quel bloc vous a été attribué dans le manager et ensuite d'ajouter quelque chose comme ça dans votre /etc/network/interfaces :

iface eth0 inet6 static
        address 2001:41d0:1:2345::1
        netmask 64
        up ip -6 r a 2001:41d0:1:23FF:FF:FF:FF:FF dev eth0 && ip -6 r a default via 2001:41D0:1:23FF:FF:FF:FF:FF

address doit avoir pour valeur une des IPs dans le bloc qui vous a été attribué. Le masque est fixe : /64. La passerelle est celle du /56 qui englobe votre /64. Donc réseau /56 complété par « ff ». Pour pouvoir l'ajouter, comme elle est hors de votre /64, il faut ajouter une route (première partie de la commande passée à « up ») puis ensuite ajouter la définition de la passerelle par défaut elle-même (deuxième partie de la commande). Attention : le guide OVH concernant l'IPv6 n'est pas à jour. Voir ce post sur le forum OVH anglais.

Bien sûr, si vous avez un bridge (LXC, tout ça), la première ligne sera "iface br0 inet6 static" 😉 .

ÉDIT du 03/08/2013 à 18h45 : mise à jour de cette sous-partie pour apporter quelques précisions. Fin de l'édit

Pour appliquer les modifications :

service networking restart

Ici les avantages et inconvénients sont vite vus : c'est tout pareil que d'avoir une IPv4.

6in4

Là aussi, c'est plutôt simple : il suffit de se créer un compte chez un tunnel broker (Hurricane Electric, SixXS, Freenet6, ...) et d'utiliser les paramètres qu'il nous donne pour configurer notre réseau. Vu le plus grand bien que j'ai entendu d'Hurricane Electric, j'ai décidé de prendre mon tunnel chez eux.

Pour la configuration, je vous recommande : Tunnelled IPv6 via Hurricane Electric on Ubuntu.

Dans mon cas, avec le bloc qui m'a été attribué et en utilisant le POP de Londres, ça donne ça dans mon /etc/network/interfaces :

auto he-ipv6
iface he-ipv6 inet6 v4tunnel
        address 2001:470:1f08:751::2
        netmask 64
        remote 216.66.80.26
        local 87.98.183.12
        endpoint any
        up      ip -6 route add 2000::/3 via ::216.66.80.26 dev he-ipv6
        up      ip -6 addr add 2001:470:1f09:751::1/128 dev he-ipv6
        down    ip -6 route flush dev he-ipv6

he-ipv6 est un label choisi arbitrairement.

Le piège bateau qui peut vous arriver est de confondre l'adresse v6 de sortie du tunnel, qu'il faut mettre dans addresss et l'adresse que vous allez réellement attribuer à la machine, qui doit être prise dans le bloc qui vous a été attribué. Le débbogage n'est pas évident : une inversion semblera fonctionner, surtout depuis d'autres tunnels HE mais cela ne fonctionnera pas depuis partout, tout le temps.

Pour appliquer les modifications :

service networking restart

Au niveau des avantages et des inconvénients :
Cela ajoute un saut de réseau et une dépendance supplémentaire. Quand le POP d'Hurricane Electric sur lequel vous êtes tombe en rade, comme en septembre/octobre dernier pour celui de Paris, votre connectivité IPv6 tombe. On nuancera en disant qu'HE semble sérieux (donc les pannes n'arrivent pas tous les jours) et qu'après tout, il ne s'agit que d'une solution de transition librement consentie.

Ce qui me dérange plus, c'est la centralisation du réseau que cela induit. Rappelez-vous : Internet est un réseau acentré : il n'y a jamais eu de centre ni dans la technique ni dans les usages. Pour les usages, c'est loupé (Google, Facebook, ...) donc si l'on se met aussi à le faire techniquement ... Tout le monde se concentre chez un, deux, maximum trois fournisseurs de tunnels qui accumulent mécaniquement du pouvoir.

Avant, je dégainais aussi l'argument "vie privée" mais j'ai dû retrousser chemin. Certes, nos données (votre demande et la réponse de mon serveur) passent chez HE mais, même sans HE, et même en v4, nos données transitent par quelques fournisseurs de connectivité avant d'atteindre leur destination. C'est le principe d'Internet. Les a-t-on choisi ? Certainement pas : cela dépend des accords passés par notre opérateur réseau et par des choix automatiques de la route optimale. Au moins, HE est un choix librement consenti. Pour la protection de la vie privée, il faut utiliser le chiffrement.

6to4

Là,je pense qu'on atteint des sommets de simplicité : pas d'allocation à avoir ni de compte à créer chez un tiers.

Pour la mise en pratique, on cherche notre bloc préfixé par 2002. Dans mon cas, avec mon IPv4 (ipv6calc se trouve dans le package Debian du même nom) :

ipv6calc --action conv6to4 87.98.183.12
No input type specified, try autodetection...found type: ipv4addr
No output type specified, try autodetection...found type: ipv6addr
2002:5762:b70c::

Ensuite, on édite le fichier /etc/network/interfaces. Dans mon cas, cela donne :

auto tun6to4
iface tun6to4 inet6 v4tunnel
        address 2002:5762:b70c::1
        netmask 48
        local 87.98.183.12
        endpoint any
        gateway ::192.88.99.1

tun6to4 est un label choisi arbitrairement. La gateway et le netmask sont fixe. L'adresse est choisie dans le bloc. Attention, il y a des morceaux de configuration erronées qui traînent sur le web et comme pour un tunnel, le débbogage n'est pas forcement évident.

Pour appliquer les modifications :

service networking restart

Au niveau des avantages et des inconvénients :
Le préfixe 2002::/16 et l'adresse 192.88.99.1 sont anycastés. Donc on ne sait jamais sur quelle instance on va atterrir. Et cela peut varier d'un échange réseau à un autre. L'effet de concentration visible avec les tunnels 6in4 est moins accentué. C'est cela qui m'a intéressé dans cette solution.

La conséquence du point précédent est que la connectivité dépend d'une infrastructure qu'on ne maîtrise pas : le relai n'est-il pas malveillant ? Ne va-t-il pas mettre en danger ma vie privée ? Et si un opérateur fait, volontairement ou non, une fausse annonce des préfixes alors qu'il n'a pas de relai 6to4 opérationnel ? Et si le relai choisi automatiquement est victime de congestion, quid de ma connectivité ?

Une autre conséquence est que le trafic est asymétrique. À l'aller, vos paquets passent par le relai le plus proche de vous (au sens réseau). Au retour, ils passeront par le relai le plus proche de la destination. Ces relais peuvent donc être différents et de qualité inégale. Le chemin ne sera donc pas optimal : s'il n'y a pas de relai proche de la destination ? Et si ce relai n'est pas également le plus proche de vous ?

J'ai remarqué que l'initialisation d'une communication en utilisant 6to4 est clairement plus longue qu'avec de l'IPv6 natif ou qu'avec un tunnel. J'ai aussi remarqué que la qualité est toute relative. J'ai testé ma connectivité sur le top 10 des sites web les plus fréquentés (donc pas sur des infrastructures isolées/possiblement mal-configurées) sans tenter le diable : des pertes de paquets surviennent à une fréquence relativement haute.

En 2011, les RFC décrivant 6to4 ont fait l'objet d'une demande de passage à un statut "historique". Même si cette demande n'a pas aboutie, cela montre un désintérêt certain pour cette méthode de transition. De ce fait, on peut estimer qu'aucun nouveau relai 6to4 ne sera mis en place, que les relais en place ne seront plus la priorité de leurs administrateurs donc ils ne seront plus maintenus "au top". On peut supposer aussi que le nombre de relais à même déjà diminué et qu'il y a donc autant de concentration de trafic avec 6to4 qu'avec un tunnel 6in4.

J'ai aussi remarqué que le préfixe 2002::/16 ne semble pas prioritaire. Soit une machine source qui sélectionne l'adresse de destination de la cible qu'elle veut atteindre. Si elle a le choix entre une IPv6 6to4 et une IPv4, elle choisira l'IPv4. Je ne dis pas que mes tests et mon panel sont représentatifs mais du coup, ça me jette tout de même un froid vis-à-vis de 6to4. Après, il y a sûrement moyen de prioriser le choix du préfixe 6to4 (dans le fichier /etc/gai.conf pour la libc sous GNU/Linux, par exemple) mais cela se fait sur le client. Comme la masse n'éditera pas ce fichier, l'intérêt de 6to4 en prend un coup.

Question de découpage

On pourrait se demander pourquoi je n'ai pas utilisé une partie de mon bloc IPv6 natif by OVH pour adresser le serveur de ce blog. La réponse se fait en plusieurs temps.

D'une part, j'ai plusieurs domaines différents, qui n'ont pas grand chose en commun. On considère qu'un /64 est le minimum syndical pour un utilisateur final. Je considère chacun de mes domaines comme un utilisateur final. Chacun doit donc avoir son bloc v6. Une autre manière de le formuler est de dire que cela préserve un minimum de cohérence entre l'adressage des domaines si l'on considère, qu'un /64 v6 est l'équivalent d'un /32 v4. Même si l'autoconfiguration (qui ne marche plus au délà d'un /64) n'est pas activée chez OVH, ne pas découper au delà d'un /64 permet de former son esprit aux bonnes pratiques.

D'autre part, cela met en place une sorte de "redondance" (je ne sais pas comment qualifier ça, en fait) : chez OVH, j'ai déjà eu des problèmes sur un bloc précis (un bloc plus joignable ou partiellement). Néanmoins, cela dure très peu de temps. En utilisant des IPv4 dans des blocs différents, on peut diminuer le risque. En utilisant des bloc v6 différents, c'est le même principe.

Enfin : tester les différentes méthodes pour de vrai "for ze fun". Les labos (Netkit ou autres) ne permettent pas de se rendre compte de tous les aspects d'une méthode. Et surtout car si l'on doit attendre un déploiement natif pour se former en pratique, on ne s'en sortira pas !

Configuration des services

Pour vous montrer que la configuration pour un usage en double pile des grands logiciels serveurs massivement utilisés est facile, je vais vous donner quelques directives de configuration :

  • OpenSSHd : AddressFamily any;
  • BIND : listen-on { interface v4/toute interface v4; }; listen-on-v6 { interface v6/toute interface v6; };
  • Unbound : interface: interface-v4 interface: interface-v6
  • Apache HTTPD : Listen 80 / Listen 443 par défaut suffisent.
  • Postfix : inet_protocols = ipv4,ipv6 dans main.cf
  • Dovecot : listen = *, [::]
  • Ngnix : listen [::]:80 default_server ipv6only=off;
  • ejabberd : inet6, dans les blocs ejabberd_c2s et ejabberd_s2s_in,

Il faudra redémarrer le service pour prendre en compte la modification.

Pensez au DNS

La première chose à faire est d'indiquer que vous utilisez IPv6. Cela se fait en ajoutant les enregistrements AAAA qui vont bien dans votre zone. Ces enregistrements fonctionnent pareil que les A mais pour IPv6. Si le serveur faisant autorité sur votre zone passe aussi en v6, et que son nom fait partie de la zone (exemple : ns1.guiguishow.info fait partie de la zone guiguishow.info), pensez à soumettre un glue record AAAA à votre zone parente sinon une résolution totalement en v6 de votre zone sera impossible.

Reverse v6

La deuxième chose sera d'affecter la bonne valeur à vos reverse. Vous savez, le truc qui dit que 87.98.183.12 c'est viki.guiguishow.info (et qui est bien différent de la requête qui dit viki.guiguishow.info c'est 87.98.183.12). Il faut le faire aussi en v6. C'est surtout utile pour les vérifications faites par les serveurs SMTP mais c'est une bonne pratique en général.

Tunnel 6in4

Pour les tunnels Hurricane Electric, HE vous délègue la zone reverse qui correspond au bloc qu'ils vous ont attribué. Pour la mise en œuvre, tout est expliqué ici : Reversing IPv6 Addresses to Names.

Pour vous aider à trouver votre zone reverse/vos enregistrements PTR, je vous conseille l'usage d'ipv6calc (package du même nom sous Debian). Exemple :

ipv6calc --addr2ip6_arpa 2001:470:1f09:751::1
No input type specified, try autodetection...found type: ipv6addr
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.5.7.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa.

Là, c'est un enregistrement complet. Pour votre zone, comme HE vous attribue, pour simplifier, un /64, il s'agira des 4 derniers groupes de 4 chiffres (64 bits pour la partie réseau de l'adresse donc 4 groupes de 4 chiffres hexadécimaux). Ici : 1.5.7.0.9.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa. est la zone reverse.

6to4

Pour le 6to4, vous pouvez aussi obtenir une délégation de la zone reverse, ce que je trouve "énorme" ! Il suffit d'aller à l'adresse suivante : https://6to4.nro.net/, qui est gérée par les différents RIR. On remarquera tout de suite que le certificat x509 a expiré en juillet 2012, ce qui tend à confirmer 6to4 comme une solution de seconde zone.

Pour obtenir la délégation, il faut aller sur ce site avec une IPv6 préfixée par 2002::. Sur un serveur, on pourra donc avoir recours à du bon vieux ssh port forwarding :P.

Vous devez remplir le formulaire en indiquant, entre autres, l'adresse d'au moins 2 serveurs de noms qui distribue la zone indiquée. Pour la suite, je ne peux pas vous aider plus puisque j'ai été confronté à une erreur aléatoire : soit je n'avais aucun message en retour, soit une erreur m'informant que je n'ai pas l'autorisation pour effectuer l'opération demandée ... Dommage car j'ai trouvé le concept formidable.

IPv6, ce futur

Je reste dubitatif sur le déploiement massif d'IPv6 dans les années à venir ... Après tout, les vieux routards vous diront que cela fait déjà quasiment 10 ans qu'on leur dit qu'IPv6 c'est demain.

Je vais tenter d'argumenter (peu de noms car je fais des statistiques, pas une distribution de blâmes) :

  • Les principaux FAI commerciaux français ne sont pas prêts (pour les particuliers). Orange ne prévoit rien avant mi-2014. Bouygues devait proposer du v6 sur son offre ADSL fin 2012 mais ça semble encore repoussé. Free fait du 6rd (évolution 6to4) sur l'ADSL et du natif sur la fibre. Dans les 2 cas, il s'agit d'un /64. Autrement dit, mettre la freebox en bridge serait impossible sans manipulations crades (proxy NDP, tout ça) et cela amène d'autres problématiques (contrôle du terminal vers Internet, liberté, ...). SFR propose aussi du v6 encapsulé (un /64). FDN fournit un /48. Pour les autres, je vous laisse chercher.
  • Les opérateurs en général, pas seulement les FAI, sont-ils prêts ? Pour me donner une idée, j'aime bien regarder la table de routage des Internets et comparer le nombre d'annonces v4/v6, le nombre d'AS v4/v6, la moyenne du nombre d'annonces v4/v6 par AS, ... C'est par ici que ça se passe. Normalement, ça se passe de commentaires.
  • Les services ne sont pas disponibles en IPv6. Et là, je ne parle pas du top 10 des sites web les plus visités mais de la réalité, des sites que je visite très régulièrement. Faisons un tour rapide : les sites web des 3 banques que je connais : raté ; les sites web principaux des 3 universités que je connais et qui ont une formation orientée réseaux informatiques : raté ; les serveurs de mails que j'utilise : 1/5 = raté ; Parmi la centaine de flux RSS que je consulte tous les jours (et j'ai un profil atypique de passionné d'informatique qui consulte des sites de passionnés donc il y a un biais statistique ...) : 1/4 = raté. Et parmi ces sites web disponibles en IPv6, environ 3/4 le sont par un tunnel 6in4 comme Hurricane Electric. Note : pour les calculs relatifs aux flux RSS, je n'ai pas pris en compte les sites utilisant feedburner mais n'ayant pas une v6 pour leur site. Les contenus n'ayant rien en commun mais étant hébergés sur une même plateforme (Blogger, Twitter, ...) ne sont pris en compte qu'une seule fois.
  • Mais IPv6, c'est aussi des gens pour le déployer et le maintenir. Je ne suis pas compétent pour estimer les personnes compétentes "en IPv6" sur le marché du travail. Par contre, je suis compétent pour "évaluer" l'offre de formation française. Une école d'ingénieurs en informatique ne le fait toujours pas étudier au niveau bac+4. Au-delà, je ne sais pas. Un IUT informatique ne le fait pas étudier en DUT Informatique. Une fac ne le fait toujours pas étudier au niveau bac+4 d'une formation informatique, au-delà, je ne sais pas. Une autre fac le fait étudier au niveau bac+4. Une dernière fac le fait étudier en M2 d'une formation orientée réseaux informatiques. Je n'ai pas eu de retour sur les formations professionnelles de type L3 Pro/Master Pro. Je sais que certains nuanceront ce point en disant que l'enseignement supérieur donne les bases et que c'est à l'étudiant de faire sa veille technologique. Je n'ai pas de problèmes avec ça. Juste pourquoi ne pas donner les bases v6 ?

J'ai du oublier des paramètres et des biais statistiques mais ça me semble toujours aussi mal parti pour qu'Internet soit majoritairement IPv6 demain. Au moins je ne suis pas tout seul à penser ça dans mon coin : IPv6, je t’aime mais tout le monde s’en fout chez iMil.

DDNS indépendant sur OpenWRT

Table des matières

But

D'un côté, j'ai mon WRT54GL sous OpenWRT derrière une ligne ADSL (chez un FAI classique) avec une IP dynamique. Pour maintenir une correspondance entre un nom et l'adresse IP changeante, j'utilise les services de dyn.com.

De l'autre, j'ai un nom de domaine dont je gère moi-même le serveur de nom primaire. J'utilise BIND comme logiciel serveur.

Il serait bien que je prenne moi-même en charge la correspondance entre le nom de mon OpenWRT et son adresse IP. Pour ceux qui se demandent encore l'intérêt de la manip' : indépendance et tout ce que ça implique.

Contraintes

On parle de mon WRT54GL donc :

  • La méthode traditionnelle est de faire du DDNS (Dynamic DNS) dont l'échange est sécurisé grâce à une paire de clés grâce à un client comme nsupdate. Néanmoins, je n'ai pas la place pour installer un client sur mon OpenWRT.
  • Je n'ai pas la place pour installer les libs nécessaires au fonctionnement d'HTTPS avec curl ou wget. Or, si je fais mon propre système, je veux que tout soit sécurisé (de la récupération de l'IP jusqu'à sa mise à jour sur le serveur de nom.
  • Mon modem donne une IP RFC 1918 à mon WRT54GL donc le seul moyen de récupérer mon IP externe est de faire appel à un service externe. Or, je ne veux pas.

Ce que l'on va faire

OpenWRT dispose d'un client SSH ... donc toute la partie sécurité sera gérée par SSH lui-même.

Pour la périodicité de la vérification, OpenWRT dispose, par défaut, du classique cron.

Pour obtenir l'adresse IP de l'OpenWRT, pas besoin d'aller la récupérer sur un site web : on l'a récupérera depuis la variable d'environnement "SSH_CLIENT".

Pour mettre à jour la zone, on utilisera nsupdate qui sera déporté sur le serveur. Pas besoin de sécuriser l'échange avec une paire de clé vu que l'échange se fera sur localhost.

Pour résumer : Sur l'OpenWRT, cron lancera, de manière répétée, le client ssh. Le client SSH présent sur l'OpenWRT ira se connecter au serveur de nom en utilisant sa clé privée. Il lancera un script présent sur le serveur de nom. Ce script prendra la nouvelle IP en paramètre, fera quelques vérifications et utilisera nsupdate pour mettre à jour la zone.

Mise en œuvre

Dans la suite, "serveur" désignera le serveur de nom, "OpenWRT" désignera mon WRT54GL sous OpenWRT et "openwrt.guiguishow.info" sera le nom de domaine attribué à mon OpenWRT.

Script

#!/bin/bash
 
if [ $# -ne 1 ]
then
        echo "Trop ou pas assez d'arguments"
        logger "DDNS openwrt - Trop ou pas assez d'arguments"
        exit 2
fi
 

echo $1 | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" > /dev/null
if [ $? -ne 0 ]
then
        echo "La paramètre \"IP\" n'est pas au bon format."
        logger "DDNS openwrt - Paramètre IP pas au bon format."
        exit 2
fi
 
# Un petit délire pas utile : vérifier rapidement l'AS à qui a
# été distribuée l'IP passée en paramètre. Si ce n'est pas l'AS
# de mon FAI, alors soit il y a une erreur, soit le script
# n'est pas lancé depuis l'OpenWRT ... de là à parler d'une
# usurpation ... 
as=`whois $1 | grep origin | grep -oE "AS[0-9]{1,5}"`
if [ $? -eq 0 ] && [ $as != "AS5410" ]
then
        logger "DDNS openwrt - Usurpation"
        echo "." | mail -s "DDNS openwrt - USURPATION" guigui chez guiguishow pointinfo
        exit 1
fi
 
# Si l'IP passée en paramètre est la même que celle 
# actuellement dans la zone, on ne fait rien.
ipActuelle=`dig +short @127.0.0.1 openwrt.guiguishow.info`
if [ $ipActuelle !=  $1 ]
then
        cat > ./majDNSopenwrt << EOF
server 127.0.0.1
zone guiguishow.info
update delete openwrt.guiguishow.info. A
update add openwrt.guiguishow.info. 60 A $1
show
send
EOF

        nsupdate -v ./majDNSopenwrt > /dev/null 2>&1
 
        if [ $? -eq 0 ]
        then
                logger "DDNS openwrt - MAJ OK"
                echo "." | mail -s "DDNS openwrt - MAJ OK" guigui chez guiguishow pointinfo
        else
                logger "DDNS openwrt - MAJ NEEDED BUT FAIL"
                echo "." | mail -s "DDNS openwrt - MAJ NEEDED BUT FAIL" guigui chez guiguishow pointinfo
        fi
fi

ÉDIT du 06/08/2014 à 16h20 : b4n propose une version mieux écrite de ce script :

#!/bin/bash
 
EMAIL="guigui chez guiguishow pointinfo"
 
if [ $# -ne 1 ]
then
  echo "Trop ou pas assez d'arguments" >&2
  logger "DDNS openwrt - Trop ou pas assez d'arguments"
  exit 2
fi
 
if ! grep -qxE '([0-9]{1,3}\.){3}[0-9]{1,3}' <<<"$1"
then
  echo "Le paramètre \"IP\" n'est pas au bon format." >&2
  logger "DDNS openwrt - Paramètre IP pas au bon format."
  exit 2
fi
 
# Un petit délire pas utile : vérifier rapidement l'AS à qui a
# été distribuée l'IP passée en paramètre. Si ce n'est pas l'AS
# de mon FAI, alors soit il y a une erreur, soit le script
# n'est pas lancé depuis l'OpenWRT ... de là à parler d'une
# usurpation ...
if [ "$(whois "$1" | grep origin | grep -oE 'AS[0-9]{1,5}')" != "AS5410" ]
then
  logger "DDNS openwrt - Usurpation"
  mail -s "DDNS openwrt - USURPATION" "$EMAIL" <<<"."
  exit 1
fi
 
# Si l'IP passée en paramètre est la même que celle
# actuellement dans la zone, on ne fait rien.
if [ "$(dig +short @127.0.0.1 openwrt.guiguishow.info)" != "$1" ]
then
  if nsupdate -v /dev/stdin >/dev/null 2>&1 <<EOF
server 127.0.0.1
zone guiguishow.info
update delete openwrt.guiguishow.info. A
update add openwrt.guiguishow.info. 60 A $1
show
send
EOF
  then
    logger "DDNS openwrt - MAJ OK"
    mail -s "DDNS openwrt - MAJ OK" "$EMAIL" <<<"."
  else
    logger "DDNS openwrt - MAJ NEEDED BUT FAIL"
    mail -s "DDNS openwrt - MAJ NEEDED BUT FAIL" "$EMAIL" <<<"."
  fi
fi

Fin de l'édit

Chez moi, ce script s'appelle "DDNSOpenWRT.sh".

Installer nsupdate sur le serveur

Sous Debian, nsupdate se trouve dans le package dnsutils :

apt-get install nsupdate

Réglage de BIND

Il faut autoriser le DDNS sur la zone depuis localhost. Cela se passe dans la déclaration de la zone, donc normalement dans le fichier /etc/bind/named.conf.local. Il faut ajouter la directive "allow-update { 127.0.0.1; };". Exemple :

zone "guiguishow.info." IN {
        type master;
        [...]
        allow-update { 127.0.0.1; };
};

Au niveau des droits, BIND doit avoir le droit d'écrire (w) sur le fichier qui défini la zone ainsi que sur le dossier contenant ce fichier car BIND écrit des journaux (fichiers avec une extension .jnl).

Utilisateur dédié et paire de clés

Sur le serveur, on va créer un utilisateur (openwrt) qui sera dédié uniquement à l'activité DDNS.

adduser openwrt

Mettre un mot de passe.

On met le script dans le home directory de cet utilisateur (/home/openwrt).

On génére une paire de clé pour l'utiliser avec SSH :

ssh-keygen -t rsa

La partie publique va sur le serveur, dans /home/openwrt/.ssh/authorized_keys, comme d'habitude.

La clé privée doit aller sur l'OpenWRT. Néanmoins, dropbear accepte les clés uniquement sous un certain format (sinon erreur "ssh: Exited: String too long"). On installe dropbear sur notre machine de travail et on converti la clé openwrt.rsa -> openwrt.dropb) :

sudo apt-get install dropbear
/usr/lib/dropbear/dropbearconvert openssh dropbear openwrt.rsa openwrt.dropb

On transfère la clé sur l'OpenWRT :

scp openwrt.dropb root@openwrt:.

Un peu de sécurité

L'utilisateur openwrt ne doit rien pouvoir faire sur le serveur à part lancer le script. On va donc restreindre les commandes possibles à une seule avec la directive de configuration ForceCommand de SSH. On ajoute donc ceci au fichier /etc/ssh/sshd_config :

Match User openwrt
ForceCommand ~/DDNSOpenWRT.sh `env | grep SSH_CLIENT | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}"`

Créer un cron sur OpenWRT

Par défaut, crond n'est pas lancé s'il n'y a aucun fichier dans /etc/crontabs/ (voir le script dans /etc/init/ pour vous en convaincre).

Il suffit de créer un fichier /etc/crontabs/root avec le contenu suivant :

*/5 * * * * /usr/bin/ssh -i /path/to/cle/privee openwrt@serveur_de_nom '~/DDNSOpenWRT.sh `env | grep SSH_CLIENT | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}"`'

Ainsi, toutes les 5 minutes, une vérification sera faite.

Au prochain reboot, crond démarrera tout seul mais cette fois-ci, c'est à vous de le lancer :

/etc/init.d/cron start

Pour terminer, il ne reste plus qu'à supprimer les ddns-scripts. Pour cela, je commence à killer les processus (ps aux + kill -9). Ensuite je supprime le package (opkg remove --autoremove). Pensez aussi à supprimer luci-app-ddns si jamais vous l'avez. Puis je supprime les paramètres conservés par uci (uci delete ddns.myddns) . Enfin : reboot.

Inspiration

L'idée d'utiliser nsupdate côté serveur, dans un script, me vient de : Mise à jour dynamique d’entrée DNS chez GuiguiABloc.