Tag - planet-libre

Entries feed

Thursday, November 7 2013

De l'acceptabilité d'un "cloud" non maîtrisé

Aujourd'hui, le mot de "cloud" est dans toutes les bouches dans tous les domaines : on proposera au photographe d'envoyer ses photos dans le "cloud", aux étudiants de travailler de manière collaborative grâce au "cloud", aux professionnels d'embrasser ces nouvelles technologies qui permettront des gains d'efficacité et même nos politiques saisissent la tendance et promettent de faire de la France un meneur dans le domaine...

Il y a pourtant d'irréductibles libristes qui prônent l'auto-hébergement et le rejet des plateformes privatrices et avancent pour cela de nombreux arguments (qui me semblent pertinents, vous vous en doutiez) et posent de nombreuses questions.

Revenons ici sur l'une de ces questions : quelle est l'acceptabilité d'une solution "cloud" hébergée par des acteurs non connus, dans des infrastructures informatiques distantes et non localisées ?

Un acteur raisonnable jugera "acceptable" toute technologie dont le bénéfice dépasse le risque et qui apporte un gain d'utilité (par ex. une meilleure efficacité, une meilleure sécurité). Le même acteur refuserait une technologie si le gain (par ex. gain de temps) risque de devenir négatif avec une forte probabilité. C'est finalement l'espérance du gain qui doit être prise en compte pour accepter ou non la nouvelle technologie.

Je prétends que l'espérance de gain est négative avec les solutions "cloud" sur lesquelles aucun contrôle n'est possible.

Pour représenter l'acceptabilité, traçons deux axes :

  • en abscisse, le degré de connaissance technique, compréhension d'une technologie
  • en ordonnée, le degré de délégation pour la mise en place de la technologie

Acceptabilité du risque

On peut découper cet espace en 4 zones :

  • En bas à gauche, nous avons les technologies connues, comprises et réalisées complètement sans délégation à un tiers. C'est la situation optimale car le risque est alors évalué et les mesures appropriées peuvent être prises pour le réduire.
  • En haut à gauche, ce sont les technologies que l'on maîtrise parfaitement et que l'on délègue toutefois à un tiers. La parfaite connaissance permet toutefois de s'assurer de la bonne réalisation par le tiers et cela reste encore acceptable.
  • En bas à droite, la technologie n'est pas du tout comprise mais elle est déployée localement. Le niveau de risque est important mais il est assumé localement. Un effort de formation permettra de revenir vers le quadrant "en bas à gauche". Ou alors il sera décidé de sous-traiter, et on arrive alors dans le dernier quadrant...
  • En haut à droite, la technologie n'est pas comprise et elle est déléguée à un tiers. Tout contrôle est alors illusoire et seule la confiance dans le tiers permet au système de tenir. C'est la situation la plus inacceptable puisque jugement et liberté disparaissent, le tiers devient tout-puissant dans le système.

A mes yeux, la sauvegarde classique ("à l'ancienne" avec par exemple un disque dur externe chez soi, ou alors en déployant un NAS local) appartient au quadrant le plus favorable (en bas à gauche). Les solutions de type "cloud" appartiennent de plus en plus au quadrant le plus défavorable "en haut à droite". En effet, pour simplifier la vie de l'utilisateur, on ne lui donne aucun détail technique et on lui propose des interfaces simplifiées, fonctionnelles seulement au travers de clients (certes bien léchés) non extensibles et pas parfaitement intégrables. Nous sommes alors dans la situation la plus inacceptable car la plus risquée et privatrice de liberté.

Acceptabilité du risque

Il y a toutefois des offres un peu plus responsables : Hubic d'OVH par exemple... A minima, l'utilisateur saura où ses données sont stockées (localisation géographique des datacenters), il connaît la technologie sous-jacente (OpenStack Swift) et une API (qui espérons-le va encore se développer) permet un certain niveau de contrôle. Ce n'est pas suffisant mais c'est un bon début !

Il est indispensable, me semble-t-il, d'éduquer les utilisateurs sur les risques d'un "cloud" non maîtrisé (pertes de données sans recours, aucune garantie autre que celle du marketing sur le soin prêté aux données, accès aux données par des tiers, erreurs inattendues...).

Stocker ses données dans des infrastructures dédiées et protégées est une très bonne démarche, mais elle ne doit absolument pas se faire en perdant de vue la compréhension des mécanismes en place, en renonçant à leur contrôle et en "offrant les clés de sa vie" à des tiers à qui l'on ne peut faire que moyennement confiance !

Friday, November 1 2013

Sécuriser (un peu mieux) MariaDB/MySQL en une ligne de commande

Cette petite astuce ne suffira pas à sécuriser parfaitement votre serveur MariaDB/MySQL mais cela y contribuera fortement ! Et ça ne coûte que quelques secondes donc il serait bête de s'en priver.

La commande :

mysql_secure_installation

va automatiquement durcir votre installation et la rendre plus à même d'être déployée en production en :

  • vérifiant que le(s) compte(s) 'root' dispose(nt) d'un mot de passe
  • supprimer les comptes de test et la base de données de test accessible par défaut à tout utilisateur
  • supprimer les comptes root (si vous le souhaitez) accessibles depuis un hôte autre que 'localhost'
  • supprimer les comptes anonymes

Voilà qui permet d'être plus serein !

Thursday, October 31 2013

Sauvegarder régulièrement ses bases de données MariaDB/MySQL (MàJ)

La commande mysqldump est fort pratique pour effectuer une sauvegarde des bases de données sur un serveur MariaDB/MySQL. On peut bien sûr l'utiliser pour mettre en place des solutions de sauvegarde maison (cf. 2e section de la dépêche). On peut aussi utiliser le petit outil "automysqlbackup" que m'a conseillé Jdrien.

Une solution toute prête : automysqlbackup

Automysqlbackup est un petit script qui fera sans doute tout ce que vous cherchez (et peut-être plus !) : conservation de versions journalières, hebdomadaires des bases, utilisation de l'utilisateur par défaut Debian pour éviter d'avoir à saisir un mot de passe dans un script cron... Je vous laisse le découvrir dans cet article : http://jdrien.net/chronicus/index.php?article66/automysqlbackup-ou-l-art-de-ne-pas-reinventer-la-roue

Merci à Jdrien pour m'avoir présenté cette solution !

Une solution "maison" si automysqlbackup ne vous convainc pas :

Voilà un petit script pour automatiser intelligemment le processus. Prévu pour être lancé une fois par jour, le script effectue les actions suivantes :

  • il liste les bases contenues sur le serveur
  • il exporte chaque base dans un fichier nom_de_la_base.sql.X avec X le numéro du jour (1 pour Lundi, 2 pour Mardi...)
#!/bin/bash
nbday=$(date +"%u")
cd /chemin/backup/mysql
for i in *.sql.$nbday; do rm -f "$i"; done
mysql --user=debian-sys-maint --password="abcdef123456" -e 'show databases' | while read dbname; do mysqldump --user=debian-sys-maint --password="abcdef123456" "$dbname" > "$dbname".sql.$nbday; done

Détaillons le travail ligne à ligne.

On récupère le numéro du jour :

nbday=$(date +"%u")

On se place dans le dossier de sauvegarde des bases SQL :

cd /chemin/backup/mysql

On supprime les sauvegardes de la semaine passée :

for i in *.sql.$nbday; do rm -f "$i"; done

On parcourt la base de données et on exporte avec mysqdump le contenu de chaque base dans un fichier .sql.X (avec X le numéro du jour) :

mysql --user=debian-sys-maint --password="abcdef123456" -e 'show databases' | while read dbname; do mysqldump --user=debian-sys-maint --password="abcdef123456" "$dbname" > "$dbname".sql.$nbday; done

Vous noterez que l'accès à la base est effectuée avec l'utilisateur 'debian-sys-maint'. Cela n'est bien sûr valable que sur les sytèmes Debian. 'debian-sys-maint' est équivalent à un compte 'root' et le mot de passe paramétré par défaut pour ce compte se trouve dans /etc/mysql/debian.cnf. Utilisé par le système pour certaines fonctions de maintenance, il vous permettra dans ce cas de ne pas laisser votre mot de passe 'root' "à vous" en clair dans un fichier !

Bonnes sauvegardes !

Wednesday, October 30 2013

Crypter une partition et l'ouvrir sans crainte d'un keylogger

Nous allons utiliser dm-crypt+LUKS qui se basent sur les outils de cryptographie présents normalement dans le noyau linux. On pourra faire le reproche à cette solution de ne pas permettre mettre en place un déni plausible (i.e. ouvrir une partition avec des données à l'apparence normale sous la contrainte, TrueCrypt le permet).

Création de la partition

La partition à crypter se nomme : /dev/sdaX Choisissons le chiffrement aes-xts-plain avec un taille de clé de 512 bits :

cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/sdaX

Le système demande une 'passphrase' que l'on choisira bien sûr longue, avec de nombreux caractères accentués, des chiffres, des majuscules, des signes de ponctuation... Attention à ne pas perdre la 'passphrase' car sans elle, point de salut !

Puis accédons au périphérique :

cryptsetup luksOpen /dev/sdaX zonecryptee

et formatons l'espace comme souhaité puis montons le :

mkfs.ext3 /dev/mapper/zonecryptee
mount -t ext3 /dev/mapper/zonecryptee /mnt/dossiercrypte/

Pour fermer la partition cryptée :

umount /mnt/dossiercrypte/
cryptsetup luksClose zonecryptee

Pour obtenir des informations sur la partition crypée, on fera :

cryptsetup luksDump /dev/sdaX

Ajouter une clé pour accéder à la partition

Grâce à LUKS, on peut saisir plusieurs clés (jusqu'à 8) pour accéder à un même espace crypé. Commençons par générer une longe clé aléatoire :

dd if=/dev/urandom of=keyfile bs=1024 count=4

et ajoutons cette clé à l'espace crypté :

cryptsetup luksAddKey /dev/sdaX keyfile

On pourra désormais ouvrir l'espace, sans saisir la 'passphrase' secrète et sans crainte d'un keylogger ou d'une caméra qui filmerait nos mains sur le clavier, grâce à la commande :

cryptsetup --key-file=keyfile luksOpen /dev/sdaX zonecryptee

Après ouverture, la clé peut être retirée du système (elle n'est nécessaire qu'à l'ouverture) afin de limiter son exposition aux regards. Bien sûr, il ne faut pas perdre le fichier 'keyfile' et le conserver en sûreté ! S'il était compromis, on pourrait révoquer la clé avec la commande :

cryptsetup luksRemoveKey /dev/sdaX

Refermer la partition

Là rien ne change :

umount /mnt/dossiercrypte/
cryptsetup luksClose zonecryptee

Protégez-vous bien !

Sunday, October 27 2013

Fail2ban veille sur Dotclear, Wordpress et Piwik

Avec les bonnes règles, on peut demander à fail2ban de surveiller un certain nombre de services et de repérer toute tentative d'accès frauduleuse par force brute (i.e. essai de nombreuses combinaisons utilisateur/mot de passe possibles).

On crée d'abord un nouveau fichier de filtre dans /etc/fail2ban/filter.d/bruteforce.conf qui contient :

[Definition]
failregex = <insert here a regex to match in the log files> 
ignoreregex =

Il ne reste plus qu'à spécifier les règles (par expression régulière) nécessaires pour détecter les comportements coupables !

Pour protéger dotclear par exemple, on utilisera la règle suivante :

monblog.mondomain.tld:80 <HOST> - - .* "POST /admin/auth.php HTTP/1.1" 200

Pour Wordpress, on pourra utiliser celle-là :

monblog.mondomain.tld:80 <HOST> - - .* "POST /wp-login.php HTTP/1.1" 200

Et pour Piwik, celle-ci pourra faire l'affaire :

monpiwik.mondomain.tld:80 <HOST> - - .* "POST / HTTP/1.1" 200

Les dernières étapes consistent à ajouter une section dans le fichier /etc/fail2ban/jail.local pour utiliser ces nouveaux filtres et surveiller le fichier de log d'apache !

[apache-services-bruteforce]
enabled  = true
port     = http,https
filter   = bruteforce
logpath = /var/log/apache2/other_vhosts_access.log
maxretry = 8

Saturday, October 26 2013

Entretenir et sécuriser Roundcube avec logrotate et fail2ban

Roundcube entrepose certaines informations dans le dossier logs/ à la racine de l'installation. Le fichier 'errors' contiendra par exemple la trace des tentatives d'accès avec mot de passe erroné.

Pour éviter que ce fichier ne grossisse trop sans surveillance, nous allons : - mettre en place une rotation des logs avec logrotate - surveiller le log avec fail2ban pour bannir toute IP qui tenterait de forcer le passage en multipliant les essais de nom d'utilisateur et de mot de passe.

La rotation des logs

Dans /etc/logrotate.d/roundcube, on placera le paramétrage (assez explicite) suivant :

/var/www/roundcube/logs/errors {
        weekly
        missingok
        rotate 8
        compress
        notifempty
        create 640 www-data www-data
}

et le tour est joué.

On pourra appliquer la même rotation au fichier /var/www/roundcube/logs/sendmail si la volumétrie de votre webmail le nécessite !

Surveillance avec fail2ban

Nous allons créer un nouveau filtre dans /etc/fail2ban/filter.d/roundcube.conf :

[Definition]
failregex = Login failed for .*. from <HOST>

ou, si l'on est placé derrière un Proxy qui transmet la "vraie" adresse d'origine dans le champ X-Forwarded-For :

[Definition]
failregex = Login failed for .*. from .*.(X-Forwarded-For: <HOST>)

et une nouvelle règle :

[roundcube]
enabled  = true
port     = http,https
filter   = roundcube
action   = iptables46-multiport[name=apache, port="http,https", protocol=tcp]
logpath  = /var/www/roundcube/logs/errors
maxretry = 6

(attention, la règle d'action iptables46 correspond à une astuce temporaire pour ajouter le support de l'IPv6 à Fail2ban comme décrit ici)

et désormais, toute tentative d'accès répétée conduira à l'exclusion de l'IP douteuse !

Friday, October 18 2013

Votre service est-il en ligne ou hors ligne ? Le savoir sans délai avec Monit.

La grande frousse pour de nombreux administrateurs (enfin j'imagine), c'est la panne d'un système critique (généralement un samedi matin) qui passe inaperçue... Je vais vous présenter ici le petit utilitaire 'monit' qui, tout simplement, vous permettra de recevoir des notifications en cas de panne d'un de vos services. Et d'effectuer un ensemble de réactions ! C'est très certainement l'allié indispensable aux côtés de Munin que je présentais dernièrement !

Monit (à ne pas confondre avec M/Monit qui est son grand-frère non libre) est un ingénieux petit logiciel auquel on donne des missions de surveillance et des actions à effectuer lorsque certains comportements sont constatés. Je ne résiste pas à la tentation de recopier ici la bannière trouvée sur le site de monit : Monit, barking at daemons!

Un cas typique d'utilisation est le suivant : vous avez un processus P qui doit tourner sur votre machine mais que vous craignez voir s'arrêter... Vous pouvez demander à monit de vérifier toutes les X minutes que ce processus tourne toujours et le redémarrer si monit le trouve éteint. Dans ce cas, vous exécuterez monit sur le serveur qui propulse le processus à surveiller.

Autre scénario : votre serveur HTTP tourne sur l'adresse 2000:aaaa:bbbb:: et le port 80 et vous voulez vous assurer qu'il est toujours joignable. Monit peut se connecter à cette IP (ping) et dialoguer avec le service (voire même effectuer des requêtes HTTP complètes et évaluer la réponse) pour déterminer s'il est vivant. Et cela peut également fonctionner pour surveiller un FTP, un IMAP, un serveur OpenVPN... Dans ce cas, on hébergera monit sur le serveur local ou bien à distance si l'on souhaite également détecter une perte de connectivité (attention toutefois au cas de la coupure du serveur chargé de la surveillance !).

Et Monit permet bien plus encore : vérifier la présence d'un fichier, vérifier les droits sur un dossier, vérifier que la charge CPU ou la mémoire vive n'ont pas éteint des niveaux trop élevés et agir si nécessaire... Monit voit et agit !

L'installation de monit s'effectue (sous Debian) par un classique :

aptitude install monit

Pour le paramétrage, on parcourra d'abord /etc/monit/monitrc :

# Vérifier l'état des services toutes les 2 minutes
set daemon 120
# Raconter le quotidien dans un fichier
set logfile /var/log/monit.log
# Communiquer avec l'ami SMTP pour envoyer des courriels d'alerte
set mailserver monsmtp.domain.tld username "Moi" password "MonMDP" using tlsv1
# Choisir l'expéditeur de son choix quand Monit nous parle
set mail-format { from: monit@monserveur.domain.tld }
# Choisir à qui les alertes sont envoyées
set alert mon@courriel.fr
# Inclure les éléments de configuration compris dans /etc/monit/conf.d/
include /etc/monit/conf.d/*

On pourra s'occuper du ménage concernant le fichier de log (/var/log/monit.log) à l'aide de logrotate comme expliqué ici (section 'envie de rotation?').

Entrons alors dans le vif du paramétrage...

check host monsite.domain.tld with address a.b.c.d
 if failed icmp type echo count 3 with timeout 3 seconds then alert
 if failed port 80 protocol http with timeout 15 seconds then alert
 if failed port 1194 type udp with timeout 15 seconds then alert

La routine ci-dessous ne fait qu'envoyer des alertes : (i) si le serveur ne répond plus au ping, (ii) si un serveur web ne répond plus sur le port 80 et (iii) si un service ne répond pas en UDP sur le port 1194 (OpenVPN par exemple). Monit exécute chaque test les uns après les autres. Lorsqu'un test échoue au sein d'un groupe alors les tests suivants ne sont pas effectués. Monit envoie automatiquement un message lorsque le service est perdu et prévient également (c'est bien aimable de sa part) quand le service est rétabli.

Plus ardu :

check process apache with pidfile /usr/local/apache/logs/httpd.pid
  start program = "/etc/init.d/httpd start" with timeout 60 seconds
  stop program  = "/etc/init.d/httpd stop"
  if cpu > 60% for 2 cycles then alert
  if cpu > 80% for 5 cycles then restart
  if totalmem > 200.0 MB for 5 cycles then restart
  if children > 250 then restart
  if loadavg(5min) greater than 10 for 8 cycles then stop
  if failed host www.tildeslash.com port 80 protocol http
      and request "/somefile.html"
      then restart
  if failed port 443 type tcpssl protocol http
     with timeout 15 seconds
     then restart
  if 3 restarts within 5 cycles then timeout
  depends on apache_bin
  group server

Le script ci-dessous adopte le comportement suivant :

  • une alerte est émise sur la charge CPU est supérieure à 60% au cours de 2 vérifications successives
  • le serveur Apache est redémarré si la charge CPU est supérieure à 80% au cours de 5 vérifications successives
  • le serveur Apache est redémarré si la mémoire consommée est supérieure à 200 MB au cours de 5 vérifications successives
  • le serveur Apache est redémarré si plus de 250 processus fils sont détectés
  • le serveur Apache est stoppé (pas redémarré) si la charge est supérieure à 10 pendant 8 vérifications
  • le serveur Apache est redémarré si l'hôte www.tildeslash.com ou l'appel du fichier somefile.html échouent
  • le serveur Apache est redémarré si l'accès en HTTPS n'est pas disponible
  • et enfin si 3 redémarrages sont constatés en 5 cycles alors on passe à une alerte de niveau supérieur (timeout)

Je ne couvre ici qu'une faible part des possibles et je vous invite à explorer ! Un superbe outil à mettre dans toutes les mains !

Forcer la bascule vers HTTPS derrière un 'reverse proxy'

Pound (déjà évoqué à de nombreuses reprises dans ces lignes) est un 'reverse proxy' (et aussi un 'load balancer' si on souhaite utiliser ces fonctionnalités) très efficace... Il peut notamment gérer toutes les connexions en HTTPS vers vos serveurs web, les décrypter et ensuite les distribuer (bien sûr ce n'est à faire que sur un réseau local hermétique aux oreilles indiscrètes !) en HTTP à vos différents serveurs.

Selon les configurations, on acceptera les connexions en HTTP ou HTTPS ou seulement l'une ou l'autre. Parfois, on souhaite récupérer les utilisateurs qui se connectent en HTTP et les renvoyer automatiquement vers HTTPS.

Il faut alors demander au serveur web sous-jacent de réécrire les adresses, ce qui, sous Apache, se fait de la façon suivante :

        RewriteEngine on
        RewriteCond %{HTTP:X-Forwarded-Proto} !https
        RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

On notera que la réécriture ne s'applique que dans les cas où le drapeau 'X-Forwarded-Proto' n'est pas déjà HTTPS.

On peut bien sûr restreindre ce paramétrage à certains dossiers seulement (même si généraliser le HTTPS aujourd'hui serait une bonne pratique).

Pour restreindre cette ré-écrire (et donc ne forcer la connexion en HTTPS) que sur certains dossiers, on pourra inclure ces instructions dans un champ Directory :

        <Directory /var/www/appli/admin>
                RewriteEngine on
                RewriteCond %{HTTP:X-Forwarded-Proto} !https
                RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
        </Directory>

Ne laissez plus vos mots de passe transités en clair sur le net ! Forcez HTTPS a minima sur les zones sensibles !

Wednesday, October 16 2013

Apache derrière un 'reverse proxy' : la magie du X-Forwarded-For

Si votre serveur Web se trouve "caché" derrière un "reverse proxy" ou toute forme de "load balancer", alors vous serez peut-être embêté en constatant que les logs d'accès d'Apache ne mentionnent par défaut que l'adresse du proxy comme adresse d'origine... Ennuyeux !

Heureusement, les esprits ingénieux qui ont conçu les "reverse proxies" ont pensé à ajouter aux paquets transmis le drapeau "X-Forwarded-For". Il suffit alors de demander à votre serveur web de prendre en compte l'IP spécifiée dans ce champ comme origine de la communication !

Dans le cas d'Apache2, la configuration intiale qui était :

LogFormat "%v:%p %h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%h%l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

devient (on remplace %h par %{X-Forwarded-For}i) :

LogFormat "%v:%p %{X-Forwarded-For}i %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Pour les logs d'erreur (importants par exemple pour permettre à fail2ban, ou un autre démon du genre, d'agir), la version 2.2 d'Apache ne permet malheureusement pas de prendre en compte un format spécifique pour les logs. Il semble que cela soit corrigé dans la version 2.4 d'Apache (cf. ici). Si vous utilisez la version 2.2, alors il faudra installer le module rpaf :

aptitude install libapache2-mod-rpaf
a2enmod rpaf

puis dans /etc/apache2/conf.d/mod_rpaf :

RPAFenable On
RPAFsethostname On
RPAFproxy_ips a.b.c.d e.f.g.h
RPAFheader X-Forwarded-For

en remplaçant a.b.c.d et e.f.g.h par les adresses du reverse proxy. RPAF va veiller, dans les logs d'erreur, à remplacer l'adresse du 'reverse proxy' par l'adresse du client telle que signalée dans "X-Forwarded-For".

Et le tour est joué !

Monday, October 14 2013

Suivre l'état de son serveur avec Munin

Munin est un logiciel libre performant pour surveiller et suivre ("monitorer" si on s'autorise les anglicismes) des ordinateurs ou des serveurs. Il se compose de deux composants :

  • munin-node, l'utilitaire chargé de récupérer les données sur les "noeuds" du réseau
  • munin, le superviseur qui compile les données de tous les "noeuds" surveillés, fabrique des graphiques et des pages HTML pour permettre la visualisation aisée des données au travers d'un serveur web

Nous allons décrire ici le déploiement de munin-node sur un serveur et de munin sur un poste superviseur distinct.

Installer et paramétrer munin-node sur le poste à surveiller

Munin-node s'installera avec votre gestionnaire de paquet favori ; par exemple sous Debian :

aptitude install munin-node

Lors de l'installation, munin-node choisit et paramètre automatiquement un certain nombre de plugins (chaque plugin est un petit programme autonome capable d'aller collecter des données précises : par exemple le plugin cpu collecte des informations sur la charge du processeur, postfix_mailstats extrait des logs le nombre de courriels transmis par postfix, ...). Le paramétrage de munin-node s'effectue dans /etc/munin/munin-node.conf.

On pourra notamment prêter attention à ces paramètres :

#Spécifier le nom de l'hôte surveillé
host_name serveur_surveille1.domain.tld
#Adresse IPv4 du superviseur qui aura le droit de se connecter au noeud pour récupérer les informations
allow ^192\.168\.1\.200$
#Port sur lequel le service est disponible
port 4949

Une fois le paramétrage terminé, on redémarre le client par la commande

service munin-node restart

Installer le superviseur

Le superviseur Munin s'installe avec :

aptitude install munin

Il faut ensuite indiquer au superviseur quels sont les noeuds à interroger et éventuellement donner des indications spécifiques pour les graphes à construire. Cela s'effectue dans /etc/munin/munin.conf :

[serveur_surveille1.domain.tld]
    address 192.168.1.45
    use_node_name yes

Le travail de génération des graphes et des pages HTML est effectué régulièrement grâce à une tâche cron (dont la fréquence pourra être modifiée dans le fichier /etc/cron.d/munin). Il est également possible de paramétrer le système pour générer les graphes lors des consultations à l'aide d'un recours à des scripts cgi - cela n'est pas détaillé ici. Les travaux de munin ne sont pas silencieux, les logs (bien pratiques pour comprendre une éventuelle panne) sont situés dans /var/log/munin/.

On redémarrer munin par

service munin restart

et après quelques minutes d'attente, les premiers graphes doivent être générés et accessibles dans /var/cache/munin/www/.

On pourra alors rendre accessible ce dossier au travers d'un serveur web bien paramétré !

Load munin

Pour aller plus loin avec les plugins sur le noeud

Tous les plugins disponibles sont regroupés dans /usr/share/munin/plugins/ et on pourra les rendre actifs par la commande :

ln -s /usr/share/munin/plugins/pluginchoisi /etc/munin/plugins/pluginchoisi

Pour tester un plugin et visualiser les données qu'il retourne, on pourra utiliser la commande :

munin-run postfix_mailstats

La configuration des plugins s'effectue dans le fichier /etc/munin/plugin-conf.d/munin-node suivant les instructions que l'on trouvera dans les en-têtes des fichiers de plugins.

Bonne surveillance de vos serveurs !

Sunday, October 13 2013

Onduleur et Raspberry Pi, détecter et agir en cas de panne de courant

Dans cet article, nous allons voir comment faire communiquer un onduleur Eaton Ellipse 650 (mais le mode opératoire peut s'adapter à d'autres modèles d'onduleurs compatibles avec Linux) et un Raspberry Pi sous Raspbian. Le Raspberry Pi pourra alors accomplir une série d'actions : par exemple, dans le cas exposé ici, envoyer une notification de coupure électrique par courriel.

On commence par installer l'utilitaire NUT sous Linux :

aptitude install nut nut-usb

Puis on choisit le mode STANDALONE dans /etc/nut/nut.conf. Ensuite on ajoute un paragraphe correspondant à l'onduleur connecté en USB au Raspberry Pi dans /etc/nut/ups.conf :

[eaton]
driver = usbhid-ups
port = auto
desc = "MGE UPS Systems"

On peut alors vérifier que la connexion à l'onduleur fonctionne par la commande :

/lib/nut/usbhid-ups -DDD -a eaton

SI l'utilitaire nous retourne une erreur similaire à "failed to claim USB device" alors cela peut signifier que les droits ne sont pas suffisants pour accéder à la ressource. On peut alors essayer la connexion avec la commande :

/lib/nut/usbhid-ups -DDD -u root -a eaton

Si cela fonctionne, on pourra alors régler (attention, c'est une méthode un peu brutale !) le problème en modifiant la section "usbfs-like devices" du fichier /lib/udev/rules.d/91-permissions.rules :


 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", \
-                               MODE="0664"
+                               MODE="0666"

(attention au risque potentiel de sécurité de cette modification, à n'effectuer qu'en connaissance de cause !)

Une fois l'onduleur correctement reconnu, on ajoutera un utilisateur à la liste des utilisateurs autorisés à se connecter au service de l'onduleur. Ce paramétrage s'effectue en modifiant le fichier /etc/nut/upsd.users - on ajoutera par exemple


[utilisateur]
        password = monmotdepasse
        upsmon master

Enfin, on modifiera le fichier /etc/nut/usbmon.conf pour modifier les options de suivi :

MONITOR eaton@localhost 1 utilisateur monmotdepasse master

On pourra spécifier un script spécifique à exécuter lors des événements électriques :

NOTIFYCMD /path/to/notification/script

Et on pourra modifier le contenu des messages à envoyer pour chaque événement électrique reconnu :

NOTIFYMSG ONLINE        "Electrical power is back ON - UPS %s on line power"
NOTIFYMSG ONBATT        "Loss of electrical power - UPS %s on battery"
NOTIFYMSG LOWBATT       "Loss of electrical power continues - UPS %s"

Pour chaque état de l'onduleur, on pourra spécifier les actions à effectuer : - EXEC = exécuter le script de notification paramétré plus haut - SYSLOG = mentionner l'événement dans le syslog du système - WALL = faire apparaître le message dans la console de tous les utilisateurs connectés

NOTIFYFLAG ONLINE       EXEC+SYSLOG+WALL
NOTIFYFLAG ONBATT       EXEC+SYSLOG+WALL
NOTIFYFLAG LOWBATT      EXEC+SYSLOG+WALL

On pourra par exemple utiliser un scrit de notification de la sorte :

#! /bin/bash
#Send email with detailed UPS report
o=$(upsc eaton)
d=$(date)
echo -e "$d" "\n\nEvent: " "$*" "\n\n======Details on UPS=====\n" "$o" |mail -s "Evénement électrique" courriel@domain.tld
#Add any other actions: send SMS, launch shutdowns of critical systems...

Bonne surveillance de votre onduleur !

Friday, October 11 2013

Reverse IPv6 avec DNSMasq, chez Online.net

Comme raconté ici, le postmaster de Google a adopté une position très stricte de rejet de tout courriel provenant d'un serveur SMTP se connectant en IPv6 mais ne disposant pas de champ 'reverse' concordant.

On peut déplorer cette très grande rigidité et s'en étonner, surtout dans une période d'adoption progressive de l'IPv6. Pour ceux dont le fournisseur d'accès (plus précisément le fournisseur de votre bloc d'adresses IPv6) ne donne aucun moyen d'avoir un 'reverse', une solution temporaire est proposée ici : connexion en IPv4 à Google.

Dans le cas d'Online.net, la possibilité d'une délégation DNS est apparue récemment en production. Elle permet d'indiquer à quel serveur DNS se raccrocher pour effectuer la translation de nom inverse (i.e. d'adresse IP vers nom de domaine) pour les adresses du bloc.

Etape 1 : disposer d'un serveur DNS capable de répondre aux requêtes "reverse"

La grande référence du DNS est bind, mais on peut également monter ce petit service en moins de 10 lignes de configuration avec DNSMasq (dont je parlais déjà ici).

On installe dnsmasq par

aptitude install dnsmasq

et voici un exemple de configuration complète :

log-facility=/var/log/dnsmasq.log
log-queries
no-resolv
no-hosts
ptr-record=0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa,monreverse1.domain.tld
ptr-record=1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa,monreverse2.domain.tld

Les paramètres log-facility et log-queries indiquent que l'on souhaite garder une trace de toutes les requêtes DNS dans /var/log/dnsmasq.log

no-resolv et no-host ainsi que l'absence de paramètre server indiquent que l'on ne souhaite répondre positivement qu'aux requêtes correspondant à l'un des enregistrements mentionnés dans le fichier de configuration.

Et enfin, sont indiqués les 2 enregistrements PTR qui correspondent à 2 adresse IPv6 pour lesquelles on souhaite avoir un reverse IPv6.

La première adresse est 2001:abcd:efgh:100:: et la seconde est 2001:abcd:efgh:100::101. On voit que l'adresse est mentionnée dans l'enregistrement PTR en l'écrivant "à l'envers" et en séparant chaque caractère (y compris les 0 que la convention nous permet de ne pas faire apparaître dans les adresses IPv6) par un point.

Etape 2 :

On rend ce serveur DNS très simple (et capable de ne répondre qu'à ces 2 requêtes reverse IPv6) accessible à l'adresse dns.domain.tld. Si on est placé derrière un firewall, on n'oubliera pas d'ouvrir le port 53 en TCP et en UDP.

Etape 3 : paramétrer la délégation DNS chez le fournisseur du bloc IPv6

Cette étape diffère selon le fournisseur du bloc IPv6. Chez Online, il faut se rendre dans la console, onglet "Serveur" puis "Paramétrage du réseau". On choisit le bloc IPv6 de son choix et on clique sur l'option "Paramétrer la délégation DNS". On saisit alors l'adresse du serveur DNS capable de répondre aux éventuelles requêtes reverse IPv6.

Délégation DNS chez Online

Etape 4 : on peut à nouveau écrire aux destinataires de GMail

Si on expédie un message à un destinataire @gmail.com, quelques secondes plus tard, on voit apparaître dans les logs la requête DNS suivante :

Oct 6 14:04:59 dnsmasq[21288]: query[PTR] 
1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.h.g.f.e.d.c.b.a.1.0.0.2.ip6.arpa **from 74.125.18.211**

74.125.18.211 est une adresse (IPv4 !) de Google qui vient s'enquérir du reverse IPv6. Et le courriel est expédié sans encombre !

Bons paramétrages de reverse IPv6 à tous !

Thursday, October 10 2013

Ajouter un disque additionnel à un RAID 1 en 5 lignes de commande

Un RAID 1 (mirroring) constitue ne bonne garantie contre une panne de disque dur sur une machine (serveur, poste de bureau, NAS) contenant des données critiques. Avec une bonne maintenance, on peut espérer conserver des données avec un faible taux de risque de perte sur de longues durées : une bonne méthode consistant par exemple à ajouter des disques plus récents à la grappe RAID.

Nous allons détailler ici les opérations nécessaires pour ajouter un disque dur de X Go à une grappe (RAID 1) de 2 disques durs de même capacité, gérée par les fonctionnalités de RAID logiciel sous Linux.

La première étape consiste à copier la table des partitions des disques durs actifs dans le RAID (appelons les /dev/sda et /dev/sdb) sur le nouveau disque (/dev/sdc). En effet, le nouveau disque doit être structuré (en termes de partitions) rigoureusement comme les anciens.

Attention, il existe aujourd'hui couramment deux types de table de partition : l'ancien système à base de MBR (Master Boot Record) et le nouveau système nommé GPT (Globally Unique Identifier Partition Table). En MBR, vous pouvez utiliser l'utilitaire fdisk/sfdisk (non détaillé ici). Si vos disques sont formatés avec des tables GPT (le nouveau standard), voici comment faire.

On enregistre d'abord la table de partition du disque sda dans un fichier 'table' :

sgdisk --backup=table /dev/sda

puis on applique cette table au disque /dev/sdc (attention à ne pas se tromper de disque, cela pourrait être destructeur !) :

sgdisk --load-backup=table /dev/sdc

Et comme dans le système GPT chaque partition est identifiée par un unique GUID et que celui-ci est inclus dans la table GPT, alors il faut modifier les GUID pour des valeurs aléatoires dans le disque fraîchement ajouté :

sgdisk -G /dev/sdc

Le nouveau disque dur est maintenant prêt à intégrer le RAID.

mdadm --detail /dev/md0

va nous permettre de regarder les partitions inclues dans cette première partition en RAID. Par exemple, on verra que ce sont les partitions /dev/sda2 et /dev/sdb2 qui sont concernées. On saura donc qu'il faut ajouter /dev/sdc2 :

mdadm --manage /dev/md0 --add /dev/sdc2

Puis

mdadm --detail /dev/md0

doit montrer que le nouveau disque a été ajouté.

Il est toutefois fort probable que le disque ait été monté en 'spare device' i.e. en périphérique activé uniquement en cas de perte d'un autre disque. Si vous souhaitez que les données soient répliquées dès maintenant sur ce disque, il faudra agrandir le RAID :

mdadm --grow /dev/md0 --raid-devices=3

Et le tour est joué, la reconstruction du RAID (i.e. la copie des données vers le nouveau disque) doit s'effectuer de manière transparente. /dev/md0 est désormais répliqué sur 3 disques durs.

Bien sûr, une procédure similaire pourra être déployée en cas de disque défectueux pour ajouter un nouveau disque dans la grappe !

Monday, September 23 2013

L'état d'un RAID logiciel Linux résumé par courriel

Voilà un petit script très simple pour recevoir automatiquement par courriel l'état d'un RAID logiciel sous Linux :

#!/bin/sh
# cron.weekly/mdadm-status -- weekly status of the RAID
# 2013 Pierre-Alain Bandinelli
# distributed under the terms of the Artistic Licence 2.0

# Get status from the RAID array and send the details by email.
# Email will go to the address specified in the commandline.
set -eu

MDADM=/sbin/mdadm
[ -x $MDADM ] || exit 0 # package may be removed but not purged

DEST="administrateur@cestmoi.fr"
exec $MDADM --detail /dev/md0 /dev/md1 /dev/md2 |mail -s "RAID status" $DEST

On peut placer ce script dans cron.weekly pour recevoir ces informations manière hebdomadaire par exemple.

Longue vie à votre RAID !

Tuesday, September 10 2013

Partager un fichier, le faire disparaître après partage et savoir (approximativement) qui l'a téléchargé

J'utilise souvent demo.ovh.eu (le service de partage mis en place par OVH, qui, contrairement à beaucoup d'autres, n'oblige pas à visualiser des publicités) pour partager aisément des fichiers sur internet. Toutefois, je souhaiterais parfois que le fichier soit effacé après téléchargement et savoir quand celui-ci a été téléchargé. Certains services proposent sans doute cela et l'outil Jyraphe (dont le développement est stoppé ?) le permet. Je vous propose toutefois une solution maison toute simple à mettre en place et extrêmement simpliste à déployer sur serveur web + PHP !

Soit le fichier mon_archive.7z à proposer au téléchargement. Soit /var/www/ la racine du serveur web accessible sur le net. On place le fichier mon_archive.7z dans un dossier /var/www/hidden/ qu'un fichier .htaccess protège de toute ouverture. On place ensuite le code suivant dans un fichier /var/www/telechargement-ici_chaîne_unique_non_devinable.php :

<?php
    $yourfile = "hidden/mon_archive.7z";

    if (file_exists($yourfile)) {
        $file_name = basename($yourfile);

        header("Content-Type: application/zip");
        header("Content-Disposition: attachment; filename=$file_name");
        header("Content-Length: " . filesize($yourfile));

        readfile($yourfile);
        unlink($yourfile);
        if (file_exists($yourfile)) {
            mail('moi@courriel.fr', 'Fichier téléchargé mais pas supprimé !', 'Le fichier "'.$file_name.'" a bien été téléchargé par '.$_SERVER["REMOTE_ADDR"].' et n\'a pas été supprimé.');
        }
        else {
            mail('moi@courriel.fr', 'Fichier téléchargé et supprimé !', 'Le fichier "'.$file_name.'" a bien été téléchargé par '.$_SERVER["REMOTE_ADDR"].' et a été supprimé.');
        }
    }
    else {
        print "Unknown file...";
        mail('moi@courriel.fr', 'Tentative de téléchargement infructueuse.', 'Qqn ('.$_SERVER["REMOTE_ADDR"].') a tenté en vain de télécharger le fichier "'.$yourfile.'".');
    }
    exit;
?>

Le fichier php propose donc le fichier au téléchargement quand l'utilisateur appelle https://monserveur/telechargement-1g2j0a7j8.php puis l'efface du serveur et vous préviens (par courriel) que le téléchargement a eu lieu. Il enregistre également l'adresse IP de la personne qui a effectué le téléchargement (certes, c'est très approximatif comme identification). Le mot de passe est en fait la chaîne arbitrairement complexe et longue placée dans l'URL pour accéder au fichier .php permettant le téléchargement.

On pourrait améliorer encore la sécurité en récupérant le mot de passe (la chaîne arbitraire) dans un paramètre GET (?pass=1g2j0a7j8 par exemple) et bannir une IP qui ferait plus de 3 ou 4 tentatives d'accès infructueuses.

Le cahier des charges est respecté, ce n'est pas tout à fait automatique mais ça ne devrait pas être trop difficile à scripter si vous avez de nombreux fichiers de la sorte à mettre à disposition. Et surtout, votre archive (peut-être très confidentielle) ne transite pas sur un serveur tierce.

Sunday, September 8 2013

DNS local et filtrage DNS tout simplement

Il est très simple de mettre en place un petit DNS local dans un environnement domestique (ou professionnel de petite taille). Les avantages peuvent être nombreux : accélérer (un peu) la connexion à internet en gardant en cache les résultats des requêtes DNS les plus fréquentes (soyons toutefois réalistes, le gain restera modeste), attribuer des noms résolus à chacun de vos périphériques et... bloquer certains sites par filtrage DNS .

Le filtrage DNS a l'avantage de concerner tous les périphériques connectés au réseau et d'interdire également la connexion en HTTPS aux sites choisis, ce que le filtrage simple par URL ne permet pas en HTTPS. Ce type de filtrage pourra être pratique pour interdire l'accès à certains sites et couper certains serveurs de publicité. Il existe également des listes de sites aux contenus choquants en libre accès sur le net (souvent générées pour SquidGuard) que l'on pourra également réutiliser. Un utilisateur pourra bien sûr contourner ce filtrage en spécifiant des serveurs DNS différents ou en utilisant un proxy ou tunnel de son choix.

Pour la mise en place du filtrage DNS, déployons le logiciel dnsmasq qui est à la fois un serveur DHCP et un serveur DNS. Bien sûr, la fonction DHCP peut-être désactivée si elle est déjà réalisée par un autre service sur le réseau. Toutefois, notons que dnsmasq ne pourra alors pas automatiquement inclure dans les DNS les entrées correspondantes aux noms d'hôte des périphériques connectés (et auxquels une adresse a été attribuée par DHCP).

DNSMasq

Commençons par installer dnsmasq avec le sélecteur de paquet de son choix - l'exemple ci-dessous est valable pour Debian ou les distributions dérivées : aptitude install dnsmasq

Nous allons ensuite paramétrer le service dans /etc/dnsmasq.conf :

Paramétrage du DNS

  • Par défaut, dnsmasq cherche à effectuer la résolution de nom en consultant les associations du fichier /etc/hosts et en relayant les requêtes aux serveurs DNS spécifiés dans /etc/resolv.conf (ces 2 fichiers se trouvant sur la machine hébergeant dnsmasq). Si ce comportement ne vous sied pas, il est possible de commander à dnsmasq de ne pas prendre en compte ces fichiers (toute la configuration sera donc faite dans /etc/dnsmasq.conf)
no-resolv
no-hosts
  • On précise ensuite l'adresse des serveurs DNS à qui il faut relayer toute requête que dnsmasq n'aura pas su résoudre en local :
server=8.8.8.8
server=8.8.4.4
  • On ajoute ensuite les entrées spécifiques que l'on souhaite voir résolues par dnsmasq :
address=/site-interdit.com/192.168.1.1
address=/autre-site-interdit.biz/192.168.1.1

Les 2 sites mentionnés seront donc résolus vers 192.168.1.1. On peut imaginer que 192.168.1.1 héberge un serveur web qui affichera une page signalant à l'utilisateur le blocage.

  • Pour activer le cache DNS, on prendra le soin d'ajouter la ligne :
cache-size=500

500 requêtes sont donc toujours conservées en mémoire par dnsmasq. A modifier à votre volonté selon la RAM disponible et le nombre de requêtes reçues...

  • Et pour activer les logs et garder une trace de toutes les requêtes DNS reçues (par exemple pour analyser l'utilisation du cache et son optimisation) :
log-facility=/var/log/dnsmasq.log
log-queries

Paramétrage du DHCP

  • Voici maintenant le paramétrage du DHCP si l'on décide d'utiliser cette fonctionnalité. On commencera par définir les adresses que le serveur peut allouer ainsi que la durée de renouvellement :
dhcp-range=192.168.1.5,192.168.1.199,255.255.255.0,12h
  • On pourra ensuite ajouter des adresses fixes pour certains hôtes reconnus par leur adresse MAC :
dhcp-host=00:00:ab:cd:ef:12,ordinateur1,192.168.1.5
dhcp-host=00:00:ab:cd:ef:34,ordinateur2,192.168.1.6
  • Le serveur DHCP peut également communiquer à tous les clients l'adresse de la passerelle vers internet :
dhcp-option=option:router,192.168.a.b

Pour expliquer à tous les clients d'utiliser dnsmasq comme seul serveur DNS, on ajoutera finalement :

dhcp-option=6,192.168.c.d

en remplaçant bien sûr 192.168.c.d par l'adresse à laquelle dnsmasq répondra !

  • Last but not least, il faut bien sûr que le serveur DNS soit accessible. Donc il faudra faire le nécessaire pour que le pare-feu accepte les communications entrantes et sortantes sur le port 53. Si le pare-feu est iptables, voilà qui devrait faire l'affaire :
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

Voilà votre petit serveur DHCP et DNS accessible sur votre réseau local avec les éventuels raccourcis ou filtrages de vos choix !

Thursday, September 5 2013

Utilisateur de Firefogg, méfie-toi de la perte d'internet et du mode off-line !

Depuis fort longtemps, Firefogg est mon allié de choix quand il s'agit de convertir une vidéo vers le format webM (plus d'infos ici et ici), libre, efficace et reconnu par de nombreux navigateurs.

Ainsi, au mariage d'un beau-frère, quand je devais finaliser LA vidéo qui allait faire pleurer belle-maman, rire beau-papa et faire swinger les mariés, je comptais sur Firefogg pour m'aider comme à l'accoutumée.

C'était sans compter sur l'absence d'internet ! Impossible de lancer Firefogg sur mon ordinateur coupé d'internet (jolie salle de mariage isolée oblige, pas de réseau téléphonique non plus...). O rage et désespoir !

En effet, Firefogg ne se lance pas s'il ne se connecte pas à la page http://firefogg.org/. Il ne s'agit bien sûr pas d'une compression réalisée sur un serveur distant mais la conception même de Firefogg demande une page web. Firefogg a été pensé comme un plugin mobilisable par un site internet pour déporter la compression d'une vidéo sur le poste client (et ensuite la rapatrier sur le service en ligne). Il est donc nécessaire, pour mettre en branle Firefogg, de l'appeler au travers d'une API JavaScript. C'est ce que la page http://firefogg.org/ fournit par défaut.

Il suffisait de le savoir et d'avoir éventuellement la-dite page (ou tout sous-ensemble compatible avec l'API) avec soi en local. En suivant ce lien, vous trouverez une copie au 5 septembre 2013 de la page http://firefogg.org/. Elle permet de lancer Firefogg en absence de toute connexion internet. Utile dans certaines situations !

PS Pour ceux qui s'inquiètent, j'ai réussi à sauver ma journée cette fois-là en encodant à l'aide de ffmpeg... qui lui n'a *vraiment* pas besoin d'internet, nah !

PS2 En suivant cet autre lien, un patch au plugin Firefogg qui ajoute un bouton "Make Video Offline"... à toute fin utile !

Accélérer matériellement Firefox pour des effets CSS3 plus fluides !

Je découvrais récemment les pouvoirs... non pas de la force... mais des fonctions de transformation et d'animation de CSS3 (c'est un peu comme la force penserez-vous peut-être). J'étais alors bluffé mais également chagriné car je constatais une certaine lenteur (des saccades) dans les animations.

Par exemple, l'introduction "à la Star Wars" mentionnée ici n'était pas tout à fait fluide. Je décidais alors d'investiguer...

Mon navigateur étant Mozilla Firefox et, à la recherche de pistes, j'entrai l'adresse about:support dans la barre d'adresse du navigateur et descendis jusqu'à la section 'Graphics'. Voici ce que j'y lus:

Firefox GPU acceleration does not work

La valeur "0/1 Basic" pour "GPU Accelerated Windows" ne me disait rien qui vaille... Je tentais alors de forcer l'accélération matérielle en me rendant dans "about:config" et en activant à "true" l'option "layers.acceleration.force-enabled".

Après un redémarrage du navigateur et un retour à "about:support", j'avais la satisfaction de lire :

Firefox GPU acceleration works

Et toutes les animations CSS3 étaient maintenant tout à fait fluides et ne souffraient plus d'aucune saccade.

Attention toutefois, forcer l'accélération matérielle n'est pas sans risque. J'observe effectivement depuis l'activation de cette option (et de manère aléatoire) un noircissement total de la fenêtre de Firefox, que je peux résoudre en jouant sur sa taille. Mystérieux, mais pour profiter de l'intro de Star Wars en CSS3 ET fluide, je suis prêt à ce sacrifice !

Mise à jour (08 Sep 2013) : on rapporte également ici (poste de P.Scoffoni) une fuite de mémoire qui aurait (conditionnel) pu être causée par l'activation de l'option, méfiance à donc !

Friday, August 16 2013

Des cartes avec Kartograph

Nous allons décrire ici comment générer une carte de France à partir de Kartograph.py et l'afficher avec des données à l'aide de Kartograph.js.

Logo Kartograph

Kartograph.py et Kartograph.js sont deux librairies libres (open source et sous licence LGPL) développées par Gregor Aisch et disponibles ici : http://www.kartograph.org.

La première, Kartograph.py écrite en python, permet de générer des fonds de carte sous forme vectorielle (fichier *.svg) avec des tracés géoréférencés.

La seconde, Kartograph.js écrite en javascript, qui s'appuie sur la librairie de manipulation d'objets vectoriels RaphaelJS, parcourt le fichier vectoriel généré par Kartograph.py et affiche la carte au sein d'une page web. Il est également possible d'ajouter des données géographiques sur la carte à l'aide de l'API Kartograph.js.

Générer un fond de carte de France

Les données géographiques source sont disponibles sur GADM. L'archive française contient 5 niveaux d'information : FRA_adm0 contient les frontières nationales, FRA_adm1 contient les frontières des régions françaises, FRA_adm2 contient les tracés des départements, FRA_adm3 inclut les tracés des arrondissements, FRA_adm4 les tracés des cantons et enfin FRA_adm5 les tracés des villes.

La génération de la carte s'effectue à l'aide de l'outil Kartograph.py en lui spécifiant un certain nombre de paramètres à l'aide d'un fichier .json.

Voici un exemple de fichier :

{
    "layers": {
        "boundaries": {
		      "src": "FRA_adm0.shp",
		      "simplify": 3,
		      "attributes": ["ISO", "NAME_ISO"]
	      },
        "regions": {
		      "src": "FRA_adm1.shp",
		      "simplify": 3,
		      "attributes": ["ISO", "NAME_1"]
	      },
	      "departments": {
		      "src": "FRA_adm2.shp",
		      "simplify": 3,
		      "attributes": ["ISO", "NAME_1"]
	      },
	      "background": {
          "special": "sea"
        }
    },
    "proj": {
        "id": "laea",
        "lon0": 2.37556359389,
        "lat0": 49.9701576233
    }
}

On voit que ce fichier définit 2 catégories d'objet : des calques (layers) et une projection. On note que plusieurs calques sont créés et que pour chacun on précise : - "src" : la source de données sous la forme d'un fichier ShapeFile (*.shp) - "simplify" : un degré de simplification du tracé pour réduire la taille du svg généré - "attributes" : la liste des méta-données (informations) que l'on souhaite voir inclus dans le fichier vectoriel. Les données inclues dans le vectoriel seront accessibles depuis Kartograph.js. Chaque calque pourra être traité séparément par Kartograph.js, notamment avec des styles différents pour chacun.

Quand les paramètres de la carte sont satisfaisants, on lance la génération à l'aide de :

kartograph mes_parametres.json -o fichier_genere.svg

Le traitement peut prendre plusieurs minutes et le fichier est généré.

Dans le cade de l'exemple, voici le fichier .svg généré : Carte de France, svg

Utilisation du fond de carte dans une page web

La page web à créer doit contenir les librairies Javascript RaphaelJS, JQuery et Kartograph.

        <script src="lib/jquery.min.js"></script>
        <script src="lib/raphael.min.js"></script>
        <script src="lib/kartograph.min.js"></script>


Le fichier doit également contenir un bloc div dans lequel la carte sera placée :

    <body>
        <div id="map"></div>
    </body>

et le javascript suivant permet de générer la carte :

          var map = kartograph.map('#map'); // #map fait référence au div répondant à id="map"
          map.loadMap('fr.svg', function() {
            // ici, on précisera toutes les options pour l'affichage sur le carte
          }, {padding: "20"} );

Comme on peut le voir avec l'option {padding: "20"}, certains paramètres d'affichage peuvent être placés sous forme de dictionnaire après la fonction de génération.

Au sein de la fonction de génération, on ajoute la définition des couches à construire :

            map.addLayer('departments', {
                styles: {
                  'stroke-width': 1,
                  'stroke': "#C0C0C0",
                  'fill': "#fff"
                }
            });


L'exemple précédent récupère la couche 'departments' (qui avait été créé dans le fichier .json défini plus haut) et l'affiche avec les options de style (couleur et épaisseur du trait, couleur de remplissage) définies ici.

On peut ensuite ajouter des objets sur le carte à l'aide de la fonction 'addSymbols'. Par exemple, pour ajouter une bulle,

            map.addSymbols({
                type: kartograph.Bubble,
                data: myData,
                location: function(item) {
                    return [item.lon, item.lat];
                },
                radius: function(item) {
                    return item.radius;
                },
                sortBy: 'radius desc',
                style: function(item) {
                    return 'fill:'+item.color+';';
                },
            });

Dans l'exemple précédent, on récupère les données depuis un tableau myData contenant une collection d'objets aux caractéristiques lon/lat/radius/color. D'autres types sont possibles : kartograph.Label, kartograph.PieChart, kartograph.StackedBar...

Pour ajouter des formes diverses, on peut utiliser la fonction :

map.addGeoPath([kartograph.LonLat(lon1, lat1),kartograph.LonLat(lon2, lat2)]).attr( 'stroke-width', '2');

Les objets sont des objets RaphaelJS et il est donc possible d'utiliser toutes les fonctions de RaphaelJS pour attribuer des styles ou des comportements.

L'outil permet d'obtenir de jolies cartes et représentant les jeux de données que l'on souhaite. De nombreux exemples (avec le code source correspondant) sont disponibles ici : http://kartograph.org/showcase/.

Exemple Kartograph sur carte UK

Sunday, June 9 2013

Transformer un Raspberry Pi en passerelle vers Hubic d'OVH : Nginx, script Toorop & Cloudfuse

10 mars 2014 - Attention, il semble que le code de https://github.com/Toorop/HubicSwiftGateway ne soit plus fonctionnel aujourd'hui... Il faudrait vraisemblablement se rabattre vers https://github.com/oderwat/hubic2swiftgate...

Hubic est une intéressante offre de stockage en ligne proposée par OVH, le champion français de l'hébergement web. Elle dispose notamment d'un bon rapport qualité/prix (60€ HT/an pour 500 Go). Mais elle souffre de plusieurs défauts : pas de client Linux disponible au moment de l'écriture de ces lignes, et le client Windows/MacOs se résume à un client de synchronisation comme le client d'ownCloud ou celui de Dropbox et peut être insuffisant pour réaliser des sauvegarde de données (par exemple des photos).

Voici une reprise de plusieurs bonnes idées glanées sur le net pour pallier ces défauts : nous allons transformer un Raspberry Pi en passerelle Hubic ce qui permettra à tous les périphériques du réseau local d'accéder à Hubic en se passant du client d'OVH.

Introduction technique

Hubic s'appuie (si la presse spécialisée dit vrai) sur OpenStack, et plus précisément sur OpenStack Object Storage encore appelé Swift. Il est donc possible de se connecter à Hubic à l'aide d'un client swift que l'on pourra installer sur son système avec son gestionnaire de paquets préféré (pour les non-linuxiens, Cyberduck intègre normalement les fonctionnalités d'un client swift).

Toutefois, OVH a ajouté à Hubic une couche d'authentification qui n'est pas gérée par défaut par les clients swift. Heureusement entrent alors en jeu les talents de Toorop et son fort utile script que nous allons déployer plus bas.

Un script PHP pour passer l'étape d'authentification

Toorop a développé un script fort utile qui se charge de l'authentification auprès d'Hubic et permet ensuite une "libre" communication avec un client swift. Le script en question est codé en PHP et est disponible ici : https://github.com/Toorop/HubicSwiftGateway.

Installons d'abord un serveur web + PHP sur le Raspberry Pi (que l'on considèrera dans la suite propulsé par Raspbian, dérivée de Debian). Par souci de légèreté, nous déploierons ici Nginx :

aptitude install nginx php5-fpm

puis téléchargeons le script de Toorop :

cd /var/www
git clone https://github.com/Toorop/HubicSwiftGateway.git
cp -R /var/www/HubicSwiftGateway-master/src/www /var/www/HubicSwiftGateway

et créons un nouvel hôte virtuel dans la configuration de nginx qui pointera vers /var/www/HubicSwiftGateway :

touch /etc/nginx/sites-available/hubicgw

Le fichier de configuration pourra contenir :

server {
       server_name hubicgw.raspberry.lan;
       root /var/www/HubicSwiftGateway;
       index index.html index.htm index.php;

       location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }
}

On active cet hôte virtuel par :

cd /etc/nginx/sites-enabled
ln -s ../sites-available/hubicgw

et on redémarre nginx :

service nginx restart

La première étape est passée : si on appelle dans le navigateur hubicgw.raspberry.lan alors le système devrait répondre "Headers AUTH_USER and/or AUTH_KEY are missing" ce qui est normal et atteste d'un bon fonctionnement du script php. Le travail sur le Raspberry Pi s'achève ici : il est fin prêt à jouer le rôle de passerelle vers Hubic.

Se connecter alors avec le client swift

A partir de maintenant, les actions sont à effectuer sur les postes depuis lesquels on souhaite accéder à Hubic. On peut dès lors se connecter à Hubic à l'aide du client swift que l'on aura préalablement installé sur la machine de son choix (par ex. aptitude install swift sous Debian) :

swift -A http://hubicgw.raspberry.lan/ -U login_hubic -K motdepasse_hubic

(bien sûr, si le réseau local sur lequel on se trouve n'est pas parfaitement sécurisée Wifi, CPL..., on veillera à activer une connexion https pour éviter que des oreilles indiscrètes ne viennent écouter notre login et notre mot de passe Hubic !)

Simplifier l'accès grâce à cloudfuse

Nous allons poursuivre en installant sur le poste local le petit utilitaire cloudfuse que l'on trouvera ici : https://github.com/redbo/cloudfuse. Une fois téléchargé, il faut le compiler et l'installer par :

./configure
make
make install

On créera alors un fichier .cloudfuse à la racine du compte utilisateur :

username=login_hubic
authurl=http://hubicgw.raspberry.lan
cache_timeout=20

et la commande suivante permettra d'effectuer le montage de l'accès hubic comme un dossier classique de votre ordinateur :

cloudfuse /mnt/hubic/ api_key=password_hubic

Il nous est dès lors possible de naviguer au sein de l'espace hubic depuis le gestionnaire de fichiers favori.

Faire ses sauvegardes avec rsync sur Hubic

Tout est en place pour la dernière étape : nous pouvons désormais utiliser rsync (fameux logiciel unix de sauvegarde) pour synchroniser notre répertoire de photos avec sa sauvegarde en ligne :

rsync -var --size-only /path/to/my/photos /mnt/hubic/default/mon/dossier/photos

Bonnes sauvegardes !

- page 5 of 6 -