8 juil. 2019

Bind : automatiser la mise à jour d'entrées DNS

Lire la suite...

J'ai eu récemment à configurer un accès vers une machine dont l'adresse IP n'est pas fixe (typiquement derrière une box ADSL dont l'abonnement ne propose pas d'IP fixe). J'avais déjà mis en place un accès similaire il y a quelques années, mais je n'en avais pas fait de billet, voici donc l'occasion.

Plantons un peu le décor

Je suis donc dans la situation suivante : la machine, sous NetBSD, dispose d'un accès Internet derrière une box ADSL fournissant une IPv4 dynamique. Je dispose d'un nom de domaine, d'un serveur DNS public, ainsi que d'un serveur web public. En dehors des éléments, je ne souhaite pas compter sur un service tiers supplémentaire. L'idée est donc la suivante : depuis la machine en question, réussir à obtenir son adresse IP publique de sortie, et aller la donner au serveur DNS pour qu'il mette à jour une entrée afin que la dite machine soit accessible (pour un accès SSH ou HTTPS par exemple).

Étape 1 : connaître son adresse IP publique

Pour cette première étape, j'ai choisi d'utiliser un serveur web existant, qui tourne sous Nginx. Celui-ci me permet d'afficher l'adresse IP du client, sans utiliser de script supplémentaire PHP, Python ou autre. J'ai ajouté la configuration suivante dans mon virtual host :

location /myip {
    default_type text/plain;
    return 200 "$remote_addr\n";
}

Une fois Nginx relancé, je peux lancer une requête via un navigateur, wget ou curl pour afficher mon adresse IP :

$ curl http://www.example.org/myip
109.XXX.YYY.ZZZ

Étape 2 : mettre à jour une entrée DNS sans les mains

Cette deuxième étape commence par la création, manuelle, d'une nouvelle entrée de type A dans la zone DNS. Je ne détaille cette création, elle est en théorie assez basique pour toute personne qui a déjà monté un serveur DNS. Par contre il va falloir mettre à jour régulièrement cet enregistrement. Pour ne pas avoir à le mettre à jour manuellement, j'ai utilisé nsupdate. Cet outil repose sur la RFC 2136, ce qui a l'avantage d'être ouvert et documenté, et de ne pas être une solution bricolée maison à base de sed dans le fichier de zone en direct.

Pour utiliser nsupdate, il faut commencer par créer une paire de clés TSIG sur le client, et ensuite autoriser la clé publique au niveau du serveur DNS. L'outil dnssec-keygen va nous aider pour la création de clés :

$ dnssec-keygen -a HMAC-SHA256 -b 256 -n HOST dynamic.example.org
Kdynamic.example.org.+163+16284

On notera que l'option -a permet de choisir l'algorithme cryptographique, -b la taille de clé, et l'option -n spécifie le type d'entrée à laquelle se destine cette paire de clés. 2 fichiers sont alors produits, dans notre exemples ils se nomment Kdynamic.example.org.+163+16284.key (la clé publique) et Kdynamic.example.org.+163+16284.private (la clé privée). La clé publique a cette tête :

$ cat Kdynamic.example.org.+163+16284.key 
dynamic.example.org. IN KEY 512 3 163 EmvYb14yJA+0qgRmqaMng02cQoCAbekP2ou9M1fNWX4=

Quant à la clé privée :

$ cat Kdynamic.example.org.+163+16284.private 
Private-key-format: v1.3
Algorithm: 163 (HMAC_SHA256)
Key: EmvYb14yJA+0qgRmqaMng02cQoCAbekP2ou9M1fNWX4=
Bits: AAA=
Created: 20181112210734
Publish: 20181112210734
Activate: 20181112210734

Note : je n'ai pas de problème à divulguer cette clé, car je l'ai volontairement générée à des fins d'exemple. Bien entendu, il ne fait pas divulguer sa clé privée ;)

Maintenant, autorisons notre clé publique au niveau du serveur DNS Bind. Cela se situe directement dans le fichier de configuration named.conf, et cela se passe en deux parties. La première consiste à déclarer la clé publique :

key "dynamic.example.org." {
        algorithm HMAC-SHA256;
        secret "EmvYb14yJA+0qgRmqaMng02cQoCAbekP2ou9M1fNWX4=";
};

Attention, il faut bien préciser le même algorithme que lors de la génération de clés.

La deuxième partie consiste à autoriser cette clé publique au niveau de la configuration de la zone DNS sur laquelle je souhaite agir :

zone "example.org" IN {
        type master;
        file "/var/named/master/example.org";
        allow-transfer {10.13.37.53; };
        allow-query { any; };
        update-policy {
                grant dynamic.anotherhomepage.org. name dynamic.anotherhomepage.org. A CNAME TXT;
                grant dynamic2.anotherhomepage.org. name dynamic2.anotherhomepage.org. A CNAME TXT;
        };
};

Il s'agit d'une déclaration relativement classique, mais on notera la présence d'une directive update-policy dans laquelle j'autorise ma clé (définie par le nom lors de la génération par dnssec-keygen) à modifier un enregistrement DNS (définie par name puis son nom) des types décrits après (ici, mon enregistrement peut être de type A, CNAME ou TXT). L'exemple ci-dessus propose même deux enregistrements modifiés par deux clés différentes.

On peut alors utiliser nsupdate. Créons un fichier qui va contenir les données à pousser vers le serveur DNS :

$ cat dnsupdate.txt
server ns0.example.org
zone example.org.
update delete dynamic.example.org.
update add dynamic.example.org. 180 A 10.13.37.92
show
send

Ensuite, lançons nsupdate :

nsupdate -k ./Kdynamic.example.org.+163+16284.private -v ./dnsupdate.txt

Si tout se passe bien, l'enregistrement DNS devrait être à jour. Pour se faciliter les tests, on peut, lors de la création de celui-ci, mettre une valeur volontairement erronée, et constater qu'une fois nsupdate lancé, la valeur est correcte.

Étape 3 : on secoue bien fort

Maintenant qu'on a tous les outils, il ne reste plus qu'à tout englober ensemble dans un script à glisser dans une tâche cron. Voici, dessous, le script que j'ai fait pour l'exemple. Bien entendu, il utilise la méthode "La Rache" et mériterait un peu plus de rigueur dans son développement. Mais c'est un début, fonctionnel et simple à comprendre.

#!/usr/pkg/bin/bash
set -x
curl_bin=$(which curl)
curl_opts="-s"
dig_bin=$(which dig)
nsupdate_bin=$(which nsupdate)
ip_check_service="http://www.example.org/myip"
keyfile="/home/nils/keys/Kdynamic.example.org.+163+16284.private"
current_ip=$(${curl_bin} ${curl_opts} ${ip_check_service})
current_reverse=$(${dig_bin} +short @ns1.fdn.org -x ${current_ip})
previous_cname=$(${dig_bin} +short @ns0.example.org dynamic.example.org)
dns_server=$(dig +short -t A ns0.example.org)

cat > /tmp/majdnscloud.txt << EOF
server ${dns_server}
zone example.org.
update delete dynamic.example.org.
update add dynamic.example.org. 180 CNAME ${current_reverse}
show
send
EOF

nsupdate -k ${keyfile} -v /tmp/majdnscloud.txt
rm -f /tmp/majdnscloud.txt

Autres possibilités ?

Il se peut qu'on ne dispose pas de ressource pour installer un serveur qui donnerait notre IP publique de sortie, il est alors possible d'utiliser un service tiers. J'en utilise occasionnellement deux : What's My IP et IP chicken.

Pour ce qui est de la mise à jour automatisée d'un enregistrement DNS, selon le registrar, il est possible que celui-ci le propose via une API, comme Gandi LiveDNS par exemple.

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux !

Crédit photo : Jake Givens - Busy freeway traffic at night.

22 déc. 2017

NetBSD : haute disponibilité avec CARP

Lire la suite...

Turner Twins, acrobats, 1937 / by Sam HoodNetBSD dispose depuis la version 4.0 d'une implémentation du protocole CARP. Il s'agit d'un protocole, à l'origine prévu pour les routeurs, permettant à un groupe de machines de disposer d'une adresse IP flottante. Si la machine principale venait à être indisponible, une machine secondaire peut alors prendre le relai. CARP permet donc de mettre en place de la haute disponibilité.

Je me suis amusé à mettre en place une configuration CARP sur les deux serveurs DNS de mon LAN. Pourquoi ? J'ai remarqué que bien souvent, selon les OS, quand on spécifie deux serveurs DNS dans les paramètres réseau, même si la redondance est là, on peut sentir un ralentissement :

  • le client va faire du round-robin et donc régulièrement des requêtes vont échouer ;
  • le client va d'abord s'adresser au premier serveur DNS de sa liste, et si celui-ci est indisponible, il attendra un timeout avant de passer au suivant.

Il y a probablement d'autres moyens d'adresser ces problèmes, mais cela m'a fourni une excuse de jouer avec CARP, c'est le plus important :)

CARP se présente en fait sous forme d'une carte réseau fictive dont le pilote est disponible dans le noyau. Quand je dis disponible, c'est qu'en théorie l'option est compilée dans le noyau GENERIC, mais cela n'est pas forcément le cas sur toutes les plateformes. Ainsi, j'ai dû recompiler un noyau contenant pseudo-device carp.

Une fois que CARP est bien disponible, il suffit tout simplement de créer une nouvelle interface réseau sur chaque machine. La machine principale aura un poids plus fort que la machine secondaire, et portera l'adresse IP flottante en temps normal.

Sur la machine principale :

# ifconfig carp0 create
# ifconfig carp0 vhid 101 pass motdepassehalakon 10.13.37.42 netmask 255.255.255.0

Sur la machine secondaire :

# ifconfig carp0 create
# ifconfig carp0 vhid 100 pass motdepassehalakon 10.13.37.42 netmask 255.255.255.0

On peut alors vérifier que l'adresse IP flottante est joignable. A noter la présence d'un mot de passe permettant de limiter les cas de "vol d'IP flottante", ici positionné à "motdepassehalakon"

Pour que cela tienne au redémarrage, il faut bien entendu que la configuration soit enregistrée quelque part. En fait, en terme de configuration, il s'agit tout simplement de la configuration de la carte réseau carp0, ici sur la machine principale :

$ cat /etc/ifconfig.carp0
create
up
vhid 101 pass motdepassehalakon 10.13.37.42 255.255.255.0

Ensuite sur la machine secondaire :

$ cat /etc/ifconfig.carp0
create
up
vhid 100 pass motdepassehalakon 10.13.37.42 255.255.255.0

Maintenant, il ne reste plus qu'à tester... en débranchant la prise !

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux !

Crédit photo : State Library of New South Wales - Turner Twins, acrobats, 1937 / by Sam Hood.

17 déc. 2017

Quelques statistiques du blog

Lire la suite...

Suite au commentaire de Xate dans un récent billet, quelques statistiques sur les billets (blogmas ou pas) sur la première quinzaine de décembre. Pour cela, je me suis servi de mes one-liners en awk décrits ici et .

Les billets les plus vus

Commençons par les billets les plus visités :

root@vhost2:~/tmp# grep "GET /post/" ./access.log | awk '{frequencies[$7]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' | sort -nr -k 2,2 | head -20
/post/python-3-outils-anaylser-code     1527
/post/make-automatiser-quelques-taches-avec-un-makefile 260
/post/livre-apprendre-a-programmer-avec-python  243
/post/xz-pour-une-meilleure-compression-de-ses-fichiers 224
/post/centos-7-desactiver-firewalld-reactiver-iptables  209
/post/2016/12/29/Vous-naviguez-toujours-sur-un-site-HTTPS       192
/post/livre-introduction-au-langage-c   168
/post/logrotate-exemple-vite-fait       165
/post/paris-open-source-summit-2017-jour-2      161
/post/en-retard 152
/post/paris-open-source-summit-2017     143
/post/centos-7-desactiver-firewalld-reactiver-iptables/ 124
/post/Trouver-des-fichiers-doublons-avec-fdupes 123
/post/raspberry-pi-attention-alimentation       112
/post/2009/11/09/Utilisation-transparente-d-une-passerelle-SSH  83
/post/2011/10/03/Installation-de-phpMyAdmin-sur-CentOS-6        76
/post/pbulk-aller-plus-loin-sur-les-parametres  72
/post/systemd-reconfigurer-unite-service        71
/post/2017/02/13/clamav-installation-et-scan-antivirus-sur-macos        69
/post/2016/12/29/Vous-naviguez-toujours-sur-un-site-HTTPS&fromurl=redirect.asp  67

Le billet le plus populaire est donc celui sur les outils d'analyse de code Python, et de loin ! Je note que j'ai mal écrit "analyser" dans l'URL, il faudra vraiment que je fasse attention à cela à l'avenir ! Il m'arriver d'ailleurs régulièrement de dépublier puis republier un billet en m'apercevant que l'URL ne me convient pas. J'en profite pour remercier Dashie pour notre conversation sur Mastodon, sans ça je n'aurais pas eu l'idée d'écrire ce billet.

Les tag les plus vus

Quels tags sont les plus populaires ?

root@vhost2:~/tmp# grep "GET /tag/" ./access.log | awk '{frequencies[$7]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' | sort -nr -k 2,2 | head -20
/tag/NetBSD     73
/tag/Apache     55
/tag/CentOS     50
/tag/PHP        47
/tag/Linux/page/3       46
/tag/Linux      41
/tag/Perl       40
/tag/ssl        38
/tag/blogmas    34
/tag/Awstats    32
/tag/Mac%20OS%20X       31
/tag/RHEL       31
/tag/mp3        29
/tag/pkgsrc     29
/tag/RPM        29
/tag/macOS      28
/tag/Xen        27
/tag/ssh        27
/tag/tls        27
/tag/https      25

Visiblement, je commence à devenir populaire pour NetBSD, Apache, CentOS et PHP ! Dommage que pkgsrc soit un peu bas à mon goût. Le tag blogmas n'est pas non plus super populaire.

Les referers

D'où viennent les visites ?

root@vhost2:~/tmp# grep "GET /post/" ./access.log | awk '{frequencies[$11]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' | sort -nr -k 2,2 | head -20
"-"     5077
"http://www.google.co.uk/url?sa=t&source=web&cd=1"      468
"https://blog.anotherhomepage.org/"     203
"https://www.google.fr/"        196
"https://www.journalduhacker.net/"      193
"http://blog.anotherhomepage.org/"      124
"https://blog.anotherhomepage.org/post/centos-7-desactiver-firewalld-reactiver-iptables/"       66
"http://blog.anotherhomepage.org/post/centos-7-desactiver-firewalld-reactiver-iptables/"        58
"https://blog.anotherhomepage.org/post/centos-7-desactiver-firewalld-reactiver-iptables"        52
"https://blog.anotherhomepage.org/post/python-3-outils-anaylser-code"   45
"https://www.google.com/"       31
"https://blog.anotherhomepage.org/category/Humour"      29
""      28
"https://socialmediascanner.eset.com"   24
"https://blog.anotherhomepage.org/page/2"       22
"https://blog.anotherhomepage.org/post/2009/11/09/Utilisation-transparente-d-une-passerelle-SSH"        19
"https://www.google.fr" 19
"https://www.journalduhacker.net/s/asxn1a/python_3_outils_pour_analyser_son_code"       16
"https://blog.anotherhomepage.org"      15
"https://blog.anotherhomepage.org/feed/tag/Linux/atom"  15

Pas grand-chose à dire de ce côté, si ce n'est que beaucoup n'ont pas de referer, et en creusant un peu, le lien vers Google UK est utilisé par la même IP, et toutes les visites vont sur le billet sur les outils d'analyse de code Python. J'ai par contre été cité par le Journal du Hacker, ce qui fait bien plaisir !

Des erreurs ?

Quelques trucs étranges :

root@vhost2:~/tmp# awk '{frequencies[$9]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' < ./access.log | sort -nr -k 2,2 | head -10
200     48038
301     17578
304     10958
404     834
"-"     716
503     464
302     229
400     143
206     22
403     17

Voyons voir les erreurs 404 :

root@vhost2:~/tmp# grep -w "404" access.log | awk '{frequencies[$7]++;} END {for (field in frequencies) printf "%s\t%d\n" , field , frequencies[field];}' | sort -nr -k 2,2 | head -10
/post/centos-7-desactiver-firewalld-reactiver-iptables/ 66
/pages/Welcomerobots.txt        64
/wp-login.php   45
/ads.txt        20
/tag/Apachepage/2       12
/pages/Welcomelicense.txt       12
/a2billing/common/javascript/misc.js    11
/post/2017/01/21/macOS-installer-pkgsrc-pour-beneficier-de-plus-de-logiciels    11
/apple-app-site-association     11
/post/  11

Résultat : sans doute des tentatives de bruteforce du blog, pensant qu'il s'agit d'un Wordpress ou d'autre chose. Par contre, il faudra que je regarde plus attentivement les billets à propos de firewalld et de pkgsrc sur macOS.

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux !

Crédit photo : Bernard Spragg. NZ - Passing Time 2010 ).

15 déc. 2017

NetBSD : recompilation d'un noyau pour intégrer NPF dans un domU

Lire la suite...

Dans un billet précédent, j'abordais l'installation d'une machine virtuelle Xen NetBSD en mode paravirtuel. NetBSD, comme Linux, dispose en plus d'un noyau, de modules permettant d'étendre ses fonctionnalités. Ainsi, l'une des briques de pare-feu de NetBSD, NPF, est disponible sous forme de module. Le problème avec ce module, c'est qu'il n'est pas compatible avec un noyau domU. Il est donc nécessaire de recompiler un noyau NetBSD pour en profiter, en incluant le pilote NPF directement dedans plutôt qu'en module.

Récupération des sources

Recompiler un noyau NetBSD est assez facile. D'abord, je récupère les sources, ici celles de NetBSD 7.1 :

nils@shell2:/srv$ export CVSROOT="anoncvs@anoncvs.NetBSD.org:/cvsroot"
nils@shell2:/srv$ export CVS_RSH="ssh"
nils@shell2:/srv$ cvs checkout -r netbsd-7-1-RELEASE -P src

La documentation officielle le fait dans /usr/src, mais je le fais dans /srv/src, cela ne pose pas de problème.

Si vous souhaitez recompiler un système complet (et pas juste le noyau), il faudra aussi récupérer xsrc, ce que je ne ferai pas ici.

Création d'une configuration noyau personnalisée

Maintenant que les sources sont disponibles, je crée un fichier de configuration pour notre nouveau noyau. Pour cela pas besoin de repartir de zéro, je vais tout simplement copier un fichier existant, et ajouter l'option qui m'intéresse. A noter que les configurations de noyau pour NetBSD sont placées dans les sous-arborescences des différentes architectures. Dans mon cas, mes machines virtuelles sont en x86_64, ce qui correspond à amd64 côté NetBSD :

nils@shell2:/srv$ cd src
nils@shell2:/srv/src$ sys/arch/amd64/conf

Le fichier de configuration du noyau utilisé par défaut est GENERIC, et il en existe aussi un spécialisé pour un invté Xen : XEN3_DOMU. Je vais copier ce dernier au lieu de le modifier pour facilement différencier ma configuration de l'officielle :

nils@shell2:/srv/src/sys/arch/amd64/conf$ cp -vp XEN3_DOMU XEN3_DOMU_NPF

Je peux ensuite éditer mon nouveau fichier, et aller chercher cette ligne :

#pseudo-device  npf                     # NPF packet filter

Il suffit alors de commenter cette ligne, et de sauvegarder le fichier. Passons maintenant à la compilation en elle-même.

Compilation du noyau NetBSD personnalisé

La compilation d'un noyau NetBSD peut se faire de deux manières : manuellement ou via l'aide d'un script nommé build.sh. Ce script est capable, depuis n'importe quel OS compatible, de créer très simplement non seulement un noyau, mais aussi une release complète de NetBSD. Ce script est fourni dans les sources, et se trouve d'ailleurs à la racine.

D'abord, compilons les outils nécessaires :

nils@shell2:/srv/src/sys/arch/amd64/conf$
nils@shell2:/srv/src$ ./build.sh -U -u -m amd64 tools

Autre détail intéressant, et c'est aussi la raison de la présence de l'option -U dans la commande précédente, je n'ai pas besoin d'être root pour ces opérations :) Passons donc à la compilation du noyau à proprement parler :

nils@shell2:/srv/src$ ./build.sh -U -u -m amd64 kernel=XEN3_DOMU_NPF

Selon la puissance de la machine, quelques minutes plus tard un résultat similaire au suivant devrait apparaître :

===> Kernels built from XEN3_DOMU_NPF:
  /srv/src/sys/arch/amd64/compile/obj/XEN3_DOMU_NPF/netbsd
===> build.sh ended:      Sun Jun 18 20:29:39 CEST 2017
===> Summary of results:
         build.sh command:    ./build.sh -U -u -m amd64 kernel=XEN3_DOMU_NPF
         build.sh started:    Sun Jun 18 20:29:26 CEST 2017
         NetBSD version:      7.1
         MACHINE:             amd64
         MACHINE_ARCH:        x86_64
         Build platform:      NetBSD 7.1 amd64
         HOST_SH:             /bin/sh
         MAKECONF file:       /etc/mk.conf
         TOOLDIR path:        /srv/src/obj/tooldir.NetBSD-7.1-amd64
         DESTDIR path:        /srv/src/obj/destdir.amd64
         RELEASEDIR path:     /srv/src/obj/releasedir
         Updated makewrapper: /srv/src/obj/tooldir.NetBSD-7.1-amd64/bin/nbmake-amd64
         Building kernel without building new tools
         Building kernel:     XEN3_DOMU_NPF
         Build directory:     /srv/src/sys/arch/amd64/compile/obj/XEN3_DOMU_NPF
         Kernels built from XEN3_DOMU_NPF:
          /srv/src/sys/arch/amd64/compile/obj/XEN3_DOMU_NPF/netbsd
         build.sh ended:      Sun Jun 18 20:29:39 CEST 2017
===> .

Il me suffit donc de copier le fichier /srv/src/sys/arch/amd64/compile/obj/XEN3_DOMU_NPF/netbsd sur mon dom0 et de l'utiliser dans un fichier de configuration Xen pour un domU !

Et NPF alors ?

Une fois notre domU démarré à l'aide de ce noyau, il suffit de suivre la documentation de NPF.

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux ! Si en plus vous avez des remarques, ou des propositions d'améliorations, n'hésitez pas : les commentaires sont là pour ça !

Crédit photo : D - 15 photography - GT3 RS.

14 déc. 2017

pbulk : aller plus loin sur les paramètres

Lire la suite...

Aujourd'hui, je me suis dit que j'allais encore parler de mon Raspberry Pi 2. Oui, celui-là même qui en ce moment passe sont temps à compiler des paquets pkgsrc. J'avais commencé par parler de la mise en place de pbulk, puis il y a peu j'ai abordé les problèmes d'alimentation rencontrés suite à cette mise en place.

Cette fois-ci, ce n'est pas une question d'alimentation, mais de limites systèmes. J'indiquais dans mon billet les options suivantes en tête du fichier pbulk.conf :

ulimit -t 3600 # set the limit on CPU time (in seconds)
ulimit -v 2097152 # limits process address space

Le premier problème que j'ai eu s'est matérialisé sous la forme d'un pur et simple kill lors de la compilation d'un paquet. Difficile ensuite de comprendre que celui-ci arrivait au bout d'une heure ! J'ai donc compilé le dit paquet manuellement et me suis rendu compte que cela mettait bien plus d'une heure. Cela peut sembler surprenant au premier abord, mais j'avais oublié que même en ayant 4 coeurs, un Raspberry Pi 2 est bien moins puissant qu'un PC classique x86_64. Il met donc, logiquement, bien plus de temps pour créer un même paquet. J'ai donc fini par commenter ces deux directives, pour voir si d'autres paquets, auparavant en échec pour des raisons obscures, peuvent compiler sans soucis.

A l'heure où j'écris ceci, le bulk build n'est pas terminé, mais j'ai déjà pu voir que le paquet qui m'a mis sur la voie est créé avec succès, ainsi que d'autres qui ne pouvaient pas être créés du fait de l'absence de ce premier.

Vous avez aimé cet article ? Alors partagez-le sur les réseaux sociaux ! Si en plus vous avez des remarques, ou des propositions d'améliorations, n'hésitez pas : les commentaires sont là pour ça !

Crédit photo : Joe deSousa - Gears.

Propulsé par Dotclear