Introduction

La Direction Générale des Finances Publique fait vraiment un travail formidable sur le domaine de l'Opendata et de l'information géographique. En effet, elle produit, dans un silence relatif si l'on compare à ce qui se passe sur les différentes plateformes Opendata des collectivités locales, un outil essentiel à la connaissance de notre territoire. Cet outil, c'est le Plan Cadastral. Avec la modernité, ce Plan Cadastral est maintenant numérique. Pour aller plus loin, il est même complètement disponible et gratuitement sur le site http://www.cadastre.gouv.fr que je vous recommande de consulter. Depuis quelques années maintenant, le projet OpenStreetMap a obtenu l'autorisation écrite d'utiliser les ressources de cadastre.gouv.fr pour générer du contenu dans OpenStreetMap.

Car il faut bien reconnaître que le cadastre est très intéressant pour cet usage. En effet, c'est un document qui est globalement assez complet, assez précis. Il permet notamment d'importer l'intégralité des bâtiments cadastrés, les emplacements des rues ainsi que les noms des lieux-dits et, pour finir, l'ensemble des surfaces en eaux. C'est également un document dont la couverture est quasi-totale et égale sur le territoire (à de rares exceptions près). Il permet donc de régler un des problèmes majeurs d'OpenStreetMap, à savoir, la faible couverture dans les communes rurales ou isolées qui ne bénéficient pas d'un grand nombre de "mappeurs" OpenStreetMap. Grâce au cadastre, nul besoin de se déplacer pour importer bâti et routes, voire adresses postales.

Si je devais vous montrer l'intérêt du cadastre dans OpenStreetMap, je prendrais un seul exemple sous forme d'images:

A gauche, le coeur d'une ville bien connue: San Francisco. A droite, un petit village perdu du Maine-et-Loire. La différence est saissisante: d'un côté on a bien les rues, de l'autre côté, il y a tout: les maisons, les rues, les lieux-dits, les cours d'eau, les étangs, le tout avec le nommage qui va bien. Il suffit d'un peu de motivation et surtout des bons outils pour réaliser ce travail d'import.

Sur ce point technique, certes il existe l'interrogation du site www.cadastre.gouv.fr qui présente un outil Web pour afficher le cadastre à un niveau de détail avancé. Cette application Web repose sur l'interrogation d'un serveur WMS accessible après connexion (cookie nécéssaire). Néanmoins il existe également un plugin dédié dans JOSM, nomme cadastre-fr. Ce dernier agit en téléchargeant des dalles rasters depuis le serveur WMS du cadastre.

Néanmoins, la solution offerte par JOSM pour télécharger le cadastre comporte quelques inconvénients:

  • d'abord, c'est complexe à configurer: il faut se mettre dans la bonne projection, écrire le nom de la commune tel qu'il sera compris par le serveur du cadastre.
  • ensuite, c'est long à télécharger: quand on importe des données, on a besoin de disposer rapidement de la vision des lieux.
  • enfin, ça consomme de la mémoire à outrance. Télécharger le cadastre entier d'une commune avec ce plugin consomme facilement plus de 2Go de RAM !

Toutes ces raisons m'ont amené à me pencher sur une solution permettant de récupérer une dalle raster du cadastre indépendamment de JOSM pour permettre une visualisation instantanée (ou rapide du moins) dans cet outil pour pouvoir facilement importer des éléments du cadastre. J'ai donc essayé de mettre au point un outil permettant de récupérer ces données directement depuis le site cadastre.gouv.fr.

Utilité et couverture du besoin

L'objectif principal est de créer une dalle raster depuis le serveur WMS de cadastre. Cela permet de disposer d'un document unique manipulable par n'importe quel logiciel de SIG, après récupération.

Voici un bref cahier des charges pour notre outil:

  • Former une dalle raster du cadastre d'une commune.
  • Être facilement installable.
  • S'appuyer sur des outils simples déjà existants.
  • Être simple d'emploi.

Méthode

Après avoir passé en revue nos besoins, voici une petite implémentation de cet outil. J'ai commencé à le réaliser en Python3 avant de m'apercevoir que je pouvais tout faire bien plus rapidement avec un simple script Shell (sous Bash). En effet, une requête WMS n'est rien d'autre qu'une requête HTTP GET bien construite qui retourne un fichier image. Des outils comme wget ou curl savent justement bien faire ce genre de travail.

La complexité vient du fait que le serveur WMS du cadastre requiert un cookie pour donner une réponse correcte. Il est donc indispensable de suivre un minimum la procédure de connexion au site cadastre.gouv.fr et son formulaire de recherche. Requêter ce dernier permet de récupérer le cookie qui nous intéresse ainsi que de vérifier que la commune demandée existe. Une fois munis du cookie et de l'existence de la commune, il faut au préalable récupérer la page HTML de navigation WMS car cette dernière contient les coordonnées de l'étendue de la commune (la bounding box). Une fois qu'on dispose de cette étendue, on peut commencer le téléchargement WMS.

Mais au préalable, il faut requêter intelligemment le serveur WMS. En effet, si on souhaite utiliser le cadastre, c'est pour avoir un niveau de détails assez fin. En conséquence, l'étendue de chaque requete WMS sera donc faible. Ainsi, il nous faudra découper notre étendue globale en autant de dalles WMS que nécéssaires. Pour avoir un bon niveau de détails, j'ai utilisé le même pas que celui du plugin cadastre-fr de JOSM, à savoir un carré de 100m de côté. La tâche suivante consiste donc à faire une boucle qui permet de requêter toutes ces dalles WMS qui donnent pour chacune d'entre elles une image PNG. J'utilise le format PNG car l'agorithme de compression est non destructif ce qui permet d'avoir des images plus nettes, sans artéfacts de compression (comme le Jpeg). Pour une commune, le nombre de fichiers PNG peut atteindre les 8000 ! Cela donnera donc 8000 requêtes WMS ! Pour chaque fichier PNG, on va également générer un fichier pngw, un "worldfile" qui permet de préciser les coordonnées de l'emprise de chaque fichier PNG. C'est indispensable pour pouvoir effectuer un assemblage de ces nombreuses dalles rasters.

Une fois tous les fichiers récupérés, on peut utiliser les outils courants de GDAL pour assembler les fichiers en une seule dalle en deux étapes:

  • Constituer un fichier raster virtuel (VRT) avec la commande gdalbuildvrt.
  • Former un seul fichier au format GeoTiff de ce raster virtuel grâce à la commande gdal_translate.

A la fin, on peut ajouter des pyramides (images précalculées avec une définition moindre directement insérées dans le fichier de dalle) pour accélérer la visualisation avec les outils courants de SIG.

Une fois terminé, il faut bien entendu faire du ménage pour ne garder que l'unique dalle finale.

Pour fonctionner le script s'appuiera sur les outils suivants:

  • curl pour le téléchargement. Je le préferre à wget car il gère beaucoup mieux les serveurs mandataires (proxies).
  • sed pour faire un peu de manipulation de données.
  • gdalbuildvrt pour construire le raster virtuel de manière simple
  • gdal_translate pour générer la dalle finale
  • gdaladdo pour générer les pyramides dans la dalle finale.

sous debian, vous aurez donc besoin d'installer le paquet gdal-bin ainsi que curl.

Le Code

Après les concepts, voici le code. Je le place en lecture directe pour faciliter sa compréhension. Un simple copier coller et il est à vous !

    #!/bin/bash

    # Script de téléchargement de dalles raster de communes depuis cadastre.gouv.fr

    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.

    # TODO:
    # Gestion de la projection

    # Vérification de la présence des outils indispensables: sed, gdalbuildvrt, gdal_translate, curl
    CMDS="curl sed gdalbuildvrt gdal_translate gdaladdo"
    for i in $CMDS
    do
    command -v $i >/dev/null && continue || { echo "Vous devez installer $i pour que ce script fonctionne..."; exit 1; }
    done

    if [ ! -n "$1" ]
    then
      echo "Usage: $(basename $0) DEP COMMUNE"
      exit 1
    else
      if [ "${#1}" -ne "3" ]
      then
    echo "Le département doit être écrit sur 3 caractères."
    echo "Ex: 049 pour le Maine-et-Loire."
    exit 1
      fi
      DEP=$1
      COM=$(echo $2 | tr a-z A-Z)
    fi

    echo "Téléchargement de la commune $COM du département $departement..."
    cook=$(mktemp cookie.XXXXXX)
    curl_options="-s -c $cook"
    rm $cook

    # Gestion du proxy
    if [ -n "$http_proxy" ]
    then
      echo "Utilisation du proxy: $http_proxy"
      curl_options="$curl_options --proxy-anyauth -x $http_proxy"
    fi

    # Etape 1: Connexion et récupération du cookie de session
    curl $curl_options "http://www.cadastre.gouv.fr/scpc/rechercherPlan.do" >> /dev/null
    curl_options="-b $cook $curl_options"

    # Etape 2: Vérifier que la commune existe dans le département
    data="numeroVoie=&indiceRepetition=&nomVoie=&lieuDit=&ville=${COM}&codePostal=&codeDepartement=${DEP}&nbResultatParPage=10&x=45&y=11"
    code_com=$(curl --data "$data" $curl_options http://www.cadastre.gouv.fr/scpc/rechercherPlan.do | grep -m 1 -o "afficherCarteCommune.do?c=*" | head -n 1 | cut -d "=" -f 2)


    # Récupération du code de la commune
    echo "Code commune: $code_com"
    #if not alf:
    #    print("Desolé mais la commune {0} est introuvable dans le département {1}".format(args.COMMUNE, args.DEP))
    #    exit(1)

    #print("{0} a pour code commune: {1}".format(args.COMMUNE, code_commune))

    # Etape 3: Connexion à la carte en ligne
    # et récupération de la boundingbox
    url="http://www.cadastre.gouv.fr/scpc/afficherCarteCommune.do?c=${code_com}&dontSaveLastForward&keepVolatileSession="
    coords=$(curl $curl_options "$url" | grep -A 4 "new GeoBox(" | tail -n 4 | sed -e 's/,//g' -e 's/)//g' -e 's/\t//g' | tr '\n' ' ')
    echo $coords | read -d " " -a bbox
    OLDFS=$FS
    FS=
    read -a bbox <<EOF
      $coords
    EOF
    FS=$OLDFS

    # Calcul des coordonnées de bounding box à prendre en compte
    xmin=$(expr ${bbox[0]%.*} / 100)
    xmin=$(expr $xmin \* 100);
    xmax=$(expr ${bbox[2]%.*} / 100)
    xmax=$(expr $xmax + 1)
    xmax=$(expr $xmax \* 100)
    ymin=$(expr ${bbox[1]%.*} / 100)
    ymin=$(expr $ymin \* 100);
    ymax=$(expr ${bbox[3]%.*} / 100)
    ymax=$(expr $ymax + 1)
    ymax=$(expr $ymax \* 100)

    stat_x=$(expr $xmax - $xmin)
    stat_x=$(expr $stat_x / 100)
    stat_y=$(expr $ymax - $ymin)
    stat_y=$(expr $stat_y / 100)
    nb_dalles=$(expr $stat_x \* $stat_y)

    echo "Téléchargement de $nb_dalles fichiers de dalles..."
    # Etape 4: Boucle de récupération des fichiers au format PNG
    x="$xmin"
    i=0
    while [ "$x" -lt "$xmax" ]
    do
      y="$ymin"
      # Définition de la bbox à télécharger:
      a="${x}.0"
      c=$(expr $x + 100)
      c="$c.0"
      while [ "$y" -lt "$ymax" ]
      do
    b="$y.0"
    d=$(expr $y + 100)
    d="$d.0"
    this_bbox="${a},${b},${c},${d}"
    # récupération du fichier PNG
    url="http://www.cadastre.gouv.fr/scpc/wms?version=1.1&request=GetMap&layers=CDIF:LS3,CDIF:LS2,CDIF:LS1,CDIF:PARCELLE,CDIF:NUMERO,CDIF:PT3,CDIF:PT2,CDIF:PT1,CDIF:LIEUDIT,CDIF:SUBSECTION,CDIF:SECTION,CDIF:COMMUNE&format=image/png&bbox=${this_bbox}&width=1000&height=800&exception=application/vnd.ogc.se_inimage&styles=LS3_90,LS2_90,LS1_90,PARCELLE_90,NUMERO_90,PT3_90,PT2_90,PT1_90,LIEUDIT_90,SUBSECTION_90,SECTION_90,COMMUNE_90"
    filename="$i.png"
    echo "Ecriture de $filename ..."
    curl -o $filename $curl_options "$url"

    # Gestion du world file:
    pngw="${filename}w"
    echo -e "0.10\n" > $pngw
    echo -e "0\n" >> $pngw 
    echo -e "0\n" >> $pngw
    echo -e "-0.125\n" >> $pngw
    echo -e "$a\n" >> $pngw
    echo -e "$d\n" >> $pngw

    y=$(expr $y + 100)
    i=$(expr $i + 1)
      done
      x=$(expr $x + 100)
    done

    # Fabrication du fichier VRT
    gdalbuildvrt ${COM}.vrt *.png

    # Génération au format GeoTiff
    gdal_translate -of GTiff -co TILED=YES -co COMPRESS=DEFLATE -co BIGTIFF=IF_NEEDED -co ZLEVEL=9 ${COM}.vrt ${COM}.tiff

    # Ajout des pyramides au GéoTiff
    gdaladdo -r average ${COM}.tiff 2 4 8 16

    # Nettoyage:
    rm $cook *.png *.pngw

    exit 0

Utilisation et limites

L'utilisation de l'outil est très simple, la commande suivante:

$ ./wms_cadastre.sh 049 ANGRIE

permet de télécharger un raster cadastre dans le répertoire courant de la commune ANGRIE située dans le département 049.

Le téléchargement va prendre pas mal de temps puisqu'il faudra réaliser de nombreuses requêtes WMS. L'assemblage est, en comparaison, assez rapide avec les options de création. Il faudra toutefois un peu plus de temps pour générer les pyramides.

Cet outil est loin d'être parfait (mais vous pouvez l'améliorer). Déjà, il est intolérant aux pannes serveurs ou de connexion réseau: si votre requête plante au milieu d'un téléchargement, il vous manquera vraisemblablement un fichier ce qui occasionnera un trou dans la dalle. Mais dans la pratique, il est tout à fait possible de télécharger 8000 dalles sans incidents.

Un deuxième inconvénient majeur, se situe au niveau de la transparence. Lorsqu'on télécharge une commune donnée, on télécharge tout ce qui se trouve dans une emprise qui est rectangulaire. Les espaces situés en dehors des limites communales retournent du blanc. Ainsi, on télécharge une grosse dalle par commune et il est impossible de l'assembler avec celle d'une autre commune qui serait limitrophe. Il est donc difficile (mais pas impossible si l'on joue avec les options de transparence de GDAL) d'obtenir une dalle raster d'un groupe de communes ou d'un département.

Enfin, le script ne gère pas la projection. Pour ma part, comme je compte travailler sur un secteur limité, la projection sera toujours identique (RGF CC47 soit le code EPSG:3947). Vous pouvez toujours modifier le code EPSG dans la commande gdal_translate si vous souhaitez travailler sur une autre zone.

Intégration dans JOSM

Nous disposons maintenant d'une dalle raster du cadastre d'une commune. Il faut pouvoir la visualiser dans JOSM. J'ai testé plusieurs méthodes pour y parvenir. La première consistait à utiliser un plugin nommé ImportImagePlugin. Son but est simplement de charger une dalle raster géoréférencée dans JOSM. Mais ce plugin est complètement buggé et je n'ai jamais réussi à le faire fonctionner.

Une autre technique consiste à fabriquer un ensemble de tuiles incorporables dans JOSM grâce à sa gestion des couches TMS. Gdal fournit un utilitaire nommé gdal2tiles.py pour faire ce travail de découpage. Mais encore une fois, je n'ai pas réussi à faire correspondre les tuiles à celles requêtées par JOSM. Il y avait toujours un décalage sur les coordonnées y. Impossible de corriger ça, même à la main. De plus, gdal2tiles n'est pas très performant il lui faut quelques heures pour générer un tas de tuiles proposant un bon niveau de détails.

J'ai finalement mis la main sur la bonne méthode qui consiste à utiliser le protocole WMS. Le principe est assez simple: on installe un serveur WMS sur sa machine (en localhost) et on lui demande de servir la couche raster du cadastre téléchargée. Bien entendu, il faut un serveur WMS. Le plus simple que j'ai trouvé est celui qui est installé avec Qgis. Dans Debian, il suffit d'installer le paquet qgis-mapserver. Ce dernier installe un programme accessible en CGI (vous aurez besoin d'un serveur HTTP. Apache2 sera votre ami). Si vous avez une configuration par défaut d'Apache, le serveur WMS est simplement accessible via l'url http://localhost/cgi-bin/qgis_mapserv.fcgi.

Le serveur WMS de Qgis est finalement très simple à configurer. Vous aurez besoin de créer un fichier de projet (.qgs) contenant votre couche raster, de renommer cette couche en CADASTRE dans QGis et d'enregistrer le fichier de projet en ayant soin d'indiquer la bonne projection qui sera celle que vous utiliserez dans JOSM. Je vous invite à utiliser le RGF CC de la commune que vous comptez importer. Bien entendu, le fichier de projet doit être situé dans un répertoire accessible en lecture à l'utilisateur Apache (www-data sous Debian).

Pour configurer la couche WMS dans JOSM, vous aurez besoin de faire un tour dans les Préférences (Menu Modifier -> Préférences) et d'ouvrir l'onglet "WMS/TMS". Ajoutez l'URL vers la bonne couche WMS. En voici un exemple:

wms:http://localhost/cgi-bin/qgis_mapserv.fcgi?MAP=/opt/OSM/WMS.qgs&FORMAT=PNG&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&LAYERS=CADASTRE&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}

Décomposons le contenu de cette URL pour mieux la comprendre:

  • wms: indique qu'on utilise le protocole WMS et non TMS.
  • http://localhost/cgi-bin/qgis_mapserv.fcgi est l'emplacement du binaire CGI du serveur WMS de QGis (sous Debian).
  • Le premier argument de la requête: MAP=/opt/OSM/WMS.qgs est l'emplacement de votre fichier de projet QGis, celui que vous avez fabriqué avec la dalle raster du cadastre.
  • On trouve ensuite des éléments classiques d'une requête WMS: le Format, la version du protocole, le service
  • Un point important se trouve au niveau du paramètre LAYERS. Celui contient le nom de la couche telle qu'elle est présentée dans le fichier de projet QGis. Voilà pourquoi nous l'avions nommée CADASTRE à cette occasion.
  • Les paramètres SRS,WIDTH,HEIGHT et BBOX sont laissés à JOSM qui se charge de les remplir avec ses variables proj,width,height et bbox.

Une fois la couche WMS configurée, vous pouvez l'activer dans JOSM et commencer à importer votre cadastre.

En termes de format, j'ai remarqué que les données les plus rapides sont celles qui sont issues d'une source en GéoTiff avec pyramides internes. A l'utilisation, sur une machine moyenne, l'affichage de la couche WMS est assez rapide et dans tous les cas, bien plus qu'en passant par le plugin cadastre-fr.

Il vous faudra modifier votre fichier de projet Qgis (.qgs) lorsque vous souhaiterez travailler sur une autre commune.

Conclusion

Avec le script exposé dans cet article, il est tout à fait possible de récupérer un fichier raster de cadastre et de l'afficher dans JOSM. Le temps de capture de la dalle raster peut sembler un peu long mais il faut le relativiser par rapport au travail d'import manuel du contenu du cadastre dans OpenStreetMap. En effet, il faut compter à peu près 1 heure de travail pour intégrer les routes, les rues et les lieux-dits d'une petite commune. Pendant ce temps, rien n'empêche de télécharger une autre commune en tâche de fond !

Posted dim. 13 oct. 2013 20:05:35 Tags:

Introduction

Ce blog fonctionne avec Ikiwiki. J'ai mis en place la gestion du contenu de ce site web dans un arbre git depuis quelques temps déjà. Avec le recul, c'est un investissement payant: je peux revenir en arrière facilement et je peux facilement cloner le dépôt pour en faire une sauvegarde. Ce dépôt est accessible en écriture à distance via HTTPS afin de me permettre de publier des articles depuis l'extérieur. Maintenant que je travaille (trop) loin de mon domicile, je ne peux plus faire autrement: je dois utiliser ce mode de publication.

L'ensemble est sécurisé par un accès HTTP via TLS et par login/password d'authentification. Dernièrement, j'ai rencontré un problème avec l'accès à mes dépôts: impossible de récupérer les données, il y avait toujours une erreur liée à la certification TLS. Ne pouvant plus rien publier sur mon blog, il fallait bien que je trouve un correctif.

Qu'est-ce-qui cloche ?

Si vous avez une erreur du type:

error: gnutls_handshake() failed: A TLS packet with unexpected length was received. while accessing ...
fatal: HTTP request failed

c'est que vous avez le même symptôme que moi. L'explication est assez simple. Pour gérer ses connexions réseau, Git utilise Curl (enfin sa bibliothèque). Cette dernière peut utiliser la bibliothèque gnuTLS ou bien Openssl. Sous Debian, c'est gnuTLS qui a été retenu et il se comporte de manière plus stricte sur la gestion du TLS. Dans mon cas précis, j'utilise un certificat auto-signé et c'est ce qui déclenche l'erreur TLS. Il est malheureusement impossible de la contourner, même en utilisant l'option Git http.sslverify.

Après quelques recherches, j'ai fini par mettre la main sur une correction un peu barbare mais qui a le mérite de marcher.

Correction

Il suffit de refabriquer le paquet git en lui demandant d'utiliser la bibliothèque Curl qui repose sur OpenSSL (libcurl4-openssl-dev). Dit comme ça, ça semble simple. Dans la pratique, il y a juste un petit effort à fournir:

# Installer de quoi fabriquer des paquets
apt-get install build-essential fakeroot dpkg-dev
# Un petit répertoire temporaire pour la création du paquet
mkdir ~/git-openssl
cd ~/git-openssl
# On récupère les sources du paquet Git de Debian.
apt-get source git
# On récupère les dépendances pour fabriquer le paquet Git:
apt-get build-dep git
# On installe bien sûr la bonne bibliothèque Curl
apt-get install libcurl4-openssl-dev
# On dépaquette l'archive source en vue de la compilation
dpkg-source -x git_1.7.10.4-1+wheezy1.dsc
# On se place dans le bon répertoire
cd git-1.7.10.4/
# Ensuite,  il reste à transformer toute mention de libcurl4-gnutls-dev
# en libcurl4-openssl-dev dans le fichier debian/control
emacs debian/control
# Une fois ce travail effectué, on peut lancer la fabrication du paquet.
# Attention, cette action lance également la batterie de tests unitaires
# de git: c'est donc extrèmement long, même sur une machine moderne...
dpkg-buildpackage -rfakeroot -b
# Enfin, on peut l'installer:
cd ..
dpkg -i ./git_1.7.10.4-1+wheezy1_amd64.deb

Pour que ça marche, il vous faudra disposer du dépôt APT source (deb-src). C'est une méthode un peu bourrine mais elle a le mérite de fonctionner. Ce qui me paraît étrange, c'est qu'il n'y a aucun rapport de bugs dans le paquet Git ni dans la libcurl3-gnutls... A noter que la version de git qui est disponible dans le dépot backports de Wheezy est également affectée.

Conclusion

Avec le correctif proposé, je peux à nouveau accéder à mes dépôts Git en lecture et en écriture, sans aucun problème. J'ai trouvé l'astuce à l'emplacement suivant (rendons à César ce qui est à César): http://askubuntu.com/questions/186847/error-gnutls-handshake-falied.

Posted mar. 29 oct. 2013 21:05:35 Tags:

Introduction

Cela fait maintenant quelques années que j'ai mis en fonctionnement une chaîne de gestion de courrier électronique sur ce serveur auto-hébergé. Dernièrement, j'ai eu quelques ennuis avec un des maillons de cette chaîne: le serveur IMAP Dovecot. Ce dernier a changé de version sous Debian (passage de la version 1 à la version 2) ce qui m'a demandé une bonne reconfiguration car les fichiers et les directives de configuration ont complètement changé entre ces deux versions. Mais j'ai également constaté un autre problème: lors du redémarrage du serveur, Dovecot n'est pas lancé au démarrage. Je devais toujours le lancer manuellement malgré sa présence dans les scripts Sysinit.

En conséquence, à chaque fois que le serveur reboote, par suite d'un arrêt électrique comme une coupure, il fallait que je relance dovecot manuellement. Avec la tempête des derniers jours, il semble qu'il y ait eu quelques coupures de courant électrique et tout ce travail supplémentaire de lancement manuel m'a donc donné de la motivation pour changer tout ça.

Qu'est-ce-qui cloche ?

A force de recherches, j'ai trouvé ce bug référencé dans le paquet Debian de Dovecot. Le phénomène est identique chez moi. L'erreur typique est de trouver dans les logs (généralement /var/log/syslog) des lignes du type:

Mar 29 10:14:00 debianplug dovecot: bind([votre ipv6], 143) failed: Cannot assign requested address
Mar 29 10:14:00 debianplug dovecot: Fatal: listen([votre ipv6], 143) failed: Cannot assign requested address

Cela indique que dovecot n'a pas pu utiliser l'adresse IP(v6) sur le périphérique réseau. Ma configuration est des plus classique: j'utilise une adresse IP(v6) fixe, configurée dans /etc/network/interfaces, le système de configuration classique de Debian. Le problème vient du fait que la mise en fonctionnement d'IPv6 sur un périphérique réseau prend un peu de temps, notamment, le fait de trouver les routeurs qui fournissent des attributions d'adresse automatique. Sur un sheevaplug, il semble que Dovecot se lance avant que la pile IPv6 soit complètement fonctionnelle et disponible.

Si vous lisez le contenu du bug, vous constaterez qu'à ce jour, il n'y a pas de correction ! Mes souvenirs d'administrateur système m'ont donné une piste à suivre...

Correction

Si Dovecot démarre trop tôt, il suffit de la faire démarrer plus tard ! C'est l'idée assez simple pour corriger le problème.

Par défaut, mon système démarre sur le runlevel 2 (défaut dans Debian) et dovecot est lancé de bonne heure:

ls /etc/rc2.d/
-rw-r--r-- 1 root root 677 juil. 14 19:24 README
lrwxrwxrwx 1 root root  14 oct.   8  2012 S01motd -> ../init.d/motd
lrwxrwxrwx 1 root root  17 oct.   8  2012 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root  17 juin  28 09:14 S02apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root  17 oct.  31 10:23 S02dovecot -> ../init.d/dovecot
...

L'idée est de le lancer plus tard. Pour que ça fonctionne, vous devez modifier manuellement l'ordre de lancement (en modifiant le chiffre après S du lien symbolique vers /etc/init.d/dovecot). En effet, l'utilitaire update-rc.d qui permet de gérer les ordres de lancement des scripts sysinit se base sur les dépendances pour attribuer le classement. Pour que ça fonctionne, je vous recommande de mettre un chiffre élevé (genre S90dovecot) et ce, dans les runlevels 2 3 4 5.

Une fois les noms de fichiers modifiés, plus de problème: dovecot se lance suffisamment tard pour que la pile IPv6 soit disponible. Le tour est joué !

Conclusion

En attendant que Debian corrige le problème du paquet Dovecot, on peut utiliser cette méthode old-school artisanale. Bien entendu, si vous utilisez systemd, c'est un autre problème que je n'aborderai pas ici ;-).

Posted mer. 30 oct. 2013 20:25:35 Tags: