December 08, 2016

Florent Gallaire

Base LEGI et système de fichiers : ext4 vs XFS

Comme je l’indiquais dans mon article sur la base LEGI, cette dernière est assez volumineuse et structurée d’une manière très complexe. Ainsi, la dernière version de la base est composée de 1 624 783 fichiers XML, répartis dans une arborescence absconse de 1 537 949 sous-répertoires pour une taille d’une dizaine de Go.

Cette structure est suffisamment extrême pour nous amener à nous interroger sur le choix et sur les performance de notre système de fichiers, alors que la plupart des gens utilisent un système de fichiers sans même en avoir vraiment conscience et a fortiori sans le choisir.

Le première chose si vous souhaitez travailler sur la base LEGI, qui est composée d’un très grand nombre de petits fichiers, c’est de privilégier l’utilisation d’un SSD à celle d’un disque dur classique. En effet, les performances seront 10 à 20 fois meilleures avec un SSD.

Les systèmes de fichiers sont un sujet très technique et de très bas niveau, sur lequel peu de personnes sont compétentes et où les convictions affichées relèvent parfois plus de la croyance que de l’analyse scientifique. Voici donc trois éléments de comparaison objectifs et compréhensibles des systèmes de fichiers ext4 – le choix par défaut sous Linux – et XFS.

1) Taille de la base LEGI

Dans mon article je mentionnais que la base LEGI pouvait varier de taille selon le système de fichier, sans citer explicitement ext4 et XFS.

ext4 : 15 Go
XFS : 9 Go

Pourquoi une telle différence ? C’est Jean-Baptiste Denis qui m’a aidé à percer ce mystère. En fait XFS possède des Shortform Directories qui permettent de stocker les petits répertoires directement dans leur inode. Les 6 Go supplémentaires correspondent donc aux 1 537 949 blocs de 4 Ko créés par ext4 pour chacun des sous-répertoires.

Vainqueur : XFS

2) Nombre d’inodes

Un inode est utilisé par fichier et par répertoire lors de la décompression de la base LEGI. Il faut donc que la partition dans laquelle est stockée la base possède au minimum 1 624 783 + 1 537 949 = 3 162 732 inodes. Or le nombre d’inodes varie selon les systèmes de fichiers et les options de formatage. Pour visualiser le nombre d’inodes de vos partitions il suffit d’utiliser la commande df -ih.

ext4 : 65 000 inodes/Go
XFS : 1 000 000 inodes/Go

Ceci n’est pas du tout anecdotique, car beaucoup d’hébergeurs ne permettent pas de choisir votre système de fichier : ce sera ext4 avec ses options de formatage par défaut et rien d’autre. Avec seulement 65 000 inodes par Go, il faudra une partition d’une taille minimale de 50 Go pour pouvoir stocker la base entière. Cela implique que certaines offres de VPS peu chères, avec une capacité de stockage SSD de petite taille, ne vous permettront pas d’exploiter la base LEGI.

Vainqueur : XFS

3) Performances

J’ai évalué les performances des deux systèmes de fichiers avec plusieurs commandes parcourant la base LEGI sur un serveur Xeon 8 cœurs 3,7 GHz doté de 16 Go de RAM et d’un SSD. Les résultats permettent de comparer Ext4 et XFS, mais les performances sur votre ordinateur risquent d’être nettement inférieures.

J’ai utilisé la commande echo 3 | sudo tee /proc/sys/vm/drop_caches pour vider les caches avant chaque essai (merci Jean-Baptiste bis).

Commandeext4XFSext4/XFS
du -hsc legi3'08"0'53"3,5
find legi -type d | wc -l3'06"0'56"3,3
find . -name "*.xml" | wc -l2'54"0'51"3,4
tar xzf Freemium_legi_global.tar.gz2'26"1'18"1,9

On peut ici conclure que XFS se révèle globalement 3 fois plus rapide qu’ext4.

Vainqueur : XFS

XFS sort donc grand vainqueur de cette comparaison avec ext4, et je ne peux que vous encourager à l’utiliser si vous voulez exploiter la base LEGI. À titre personnel, j’ai décidé de ne plus utiliser que XFS.

08 December, 2016 01:34PM by fgallaire

December 07, 2016

Carl Chenet

htop expliqué, partie 2 : le load average

Après une première partie consacrée à la notion d’uptime, voici la seconde partie traduite de l’excellent article htop explained : Explanation of everything you can see in htop/top on Linux (1er sur Hacker News, 1er sur /r/sysadmin, 2nd sur /r/linux), traduit avec l’accord de son auteur Pēteris Ņikiforovs, article présentant la commande htop et les notions de base d’un système GNU/Linux présentées par ce programme.

Aujourd’hui : le load average (charge moyenne du système).


Capture d'écran de htop

Une capture d’écran de htop

Load average

En plus de l’uptime, il y avait aussi 3 nombres qui représentent le load average.

$ uptime
 12:59:09 up 32 min, 1 user, load average: 0.00, 0.01, 0.03

Ils sont pris depuis le fichier /proc/loadavg. Si vous jetez un oeil à la sortie de strace, vous verrez que ce fichier est aussi ouvert.

$ cat /proc/loadavg
 0.00 0.01 0.03 1/120 1500

Les trois premières colonnes représentent la charge moyenne du système durant les 1, 5 et 15 minutes précédentes. La quatrième colonne montre le nombre de processus s’exécutant en ce moment et le nombre total de processus. La dernière colonne affiche le dernier identifiant (ID) de processus utilisé.

Commençons avec le dernier nombre.

Quand vous lancez un nouveau processus, il lui est assigné un numéro identifiant (ID). Les IDs de processus en général sont croissants, à moins qu’eils soient épuisés et sont ré-utilisés. Le processus avec l’ID 1 appartient à /sbin/init, lequel est lancé au moment du démarrage du système.

Jetons de nouveau un oeil au contenu du /proc/loadavg et exécutons ensuite la commande sleep en arrière-plan. Quand il est lancé en arrière-plan, son ID de processus sera affiché.

$ cat /proc/loadavg
 0.00 0.01 0.03 1/123 1566
 $ sleep 10 &
 [1] 1567

Donc le 1/123 signifie qu’il y a un processus s’exécutant ou prêt à être exécuté à ce moment et qu’il y a 123 processus au total.

Quand vous exécutez htop et que vous ne voyez qu’un seul processus, cela signifie qu’il s’agit du processus htop lui-même.

Si vous exécutez sleep 30 et que vous exécutez htop de nouveau, vous constaterez qu’il n’y a qu’un seul processus en cours d’exécution. C’est parce que sleep ne s’exécute pas, il dort ou tourne au ralenti (idling) ou en d’autres mots attend que quelque chose se produise. Un processus en cours d’exécution est un processus qui s’exécute en ce moment sur le CPU physique ou attend son tour pour s’exécuter sur le CPU.

Si vous exécutez cat /dev/urandom > /dev/null qui génère de façon répétée des octets aléatoires et les écrit vers un fichier spécial depuis lequel on ne peut jamais lire, vous verrez qu’il y a maintenant deux processus en cours d’exécution.

$ cat /dev/urandom > /dev/null &
 [1] 1639
 $ cat /proc/loadavg
 1.00 0.69 0.35 2/124 1679

Donc nous avons maintenant deux nous processus (la génération de nombres aléatoires et le cat qui lit le contenu de /proc/loadavg) et vous remarquerez que les load averages ont augmenté.

Le load average représente la charge du système moyenne pendant une période de temps.

Le nombre du load est calculé en comptant le nombre de processus en cours d’exécution (s’exécutant en ce moment ou en attente d’exécution) et les processus non-interruptibles (attente d’accès au disque ou activité réseau). Donc c’est simplement un nombre de processus.

Les load averages sont donc le nombre moyen de ces processus durant les 1, 5 et 15 dernières minutes, n’est-ce pas ?

En fait ça n’est pas aussi simple que ça.

Le load average est la moyenne exponentiellement amortie/pondérée en mouvement du chiffre du load. Dixit Wikipedia (en) :

Mathématiquement parlant, toutes les trois valeurs créent une moyenne de la charge système depuis le démarrage du système. Elles se désagrègent exponentiellement mais elles se désagrègent à des vitesses différentes. Donc, la charge sur une minute va ajouter 63% de charge de la dernière minute, plus 37% de la charge depuis le démarrage en excluant la dernière minute. Donc, il n’est pas techniquement juste que la charge sur une minute inclut l’activité des 60 dernières secondes (puisqu’elle inclut 37% du passé), mais qui inclut majoritairement la dernière minute.

C’est ce que vous attendiez ?

Retournons à notre génération des nombres aléatoires.

$ cat /proc/loadavg
 1.00 0.69 0.35 2/124 1679

Bien que techniquement incorrecte, c’est la façon dont je simplifie les load averages pour en parler plus facilement.

Dans ce cas, la génération de nombres aléatoires est limitée par le CPU, donc le load average de la dernière minute est 1.00 ou en moyenne un processus en cours d’exécution.

Comme il n’y a qu’un CPU sur mon système, l’utilisation CPU est de 100% puisque mon CPU ne peut exécuter qu’un processus à la fois.

Si j’avais deux coeurs, mon utilisation CPU serait de 50% puisque mon ordinateur peut exécuter deux processus en même temps. Le load average d’un ordinateur avec deux coeurs qui a 100% d’utilisation CPU serait de 2.00.

Vous pouvez voir le nombre de coeurs ou de CPUs dans le coin en haut à gauche de htop ou en exécutant nproc.

Parce que le chiffre du load inclut également les processus dans des états non-interruptibles, lesquels n’ont pas beaucoup d’effet sur l’utilisation CPU, il n’est pas tout à fait correct de déduire l’utilisation CPU depuis les load averages comme je l’ai fait. Cela explique également pourquoi vous pourriez constater un load average élevé mais peut de charge sur le CPU.

Mais il y a des outils comme mpstat qui peuvent montrer l’utilisation CPU instantanée.

$ sudo apt install sysstat -y
 $ mpstat 1
 Linux 4.4.0-47-generic (hostname) 12/03/2016 _x86_64_ (1 CPU)

10:16:20 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
 10:16:21 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 10:16:22 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 10:16:23 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 # ...
 # kill cat /dev/urandom
 # ...
 10:17:00 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
 10:17:01 PM all 1.00 0.00 0.00 2.00 0.00 0.00 0.00 0.00 0.00 97.00
 10:17:02 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00

Pourquoi utilisons-nous les load averages alors ?

$ curl -s https://raw.githubusercontent.com/torvalds/linux/v4.8/kernel/sched/loadavg.c | head -n 7
 /*
 * kernel/sched/loadavg.c
 *
 * This file contains the magic bits required to compute the global loadavg
 * figure. Its a silly number but people think its important. We go through
 * great pains to make it work on big machines and tickless kernels.
 */

Traduction du commentaire dans le fichier source : Ce fichier contient des bits magiques requis pour calculer le chiffre du loadavg global. C’est un nombre idiot mais les gens pensent que c’est important. Nous éprouvons de grandes douleurs pour le faire marcher sur les grosses machines et les noyaux tickless.


Ce sera tout pour aujourd’hui 🙂 J’espère que comme moi vous aurez appris des éléments sur le load average de votre système. Nous continuerons cette série dès lundi avec les processus dans htop.

07 December, 2016 11:00PM by Carl Chenet

December 05, 2016

htop expliqué, partie 1 : l’uptime

Avec l’accord de Pēteris Ņikiforovs, auteur original de l’excellent article htop explained : Explanation of everything you can see in htop/top on Linux (1er sur Hacker News, 1er sur /r/sysadmin, 2nd sur /r/linux), j’entreprends une série d’articles visant à traduire en français son excellente explication de htop et des notions de base d’un système GNU/Linux présentées par ce programme.

L’approche didactique m’est apparue excellente et me semble pouvoir être d’une grande aide à toutes les personnes intéressées par ce qui se passe sur leur système GNU/Linux. Une traduction en français s’imposait donc 🙂

Aujourd’hui : l’uptime.


htop expliqué

Explication de tout ce que vous pouvez voir dans htop/top sur Linux

Bien longtemps je n’ai pas su ce que toutes les valeurs dans htop signifiaient.

Je pensais qu’un load average de 1.0 sur ma machine à deux coeurs signifiait que l’utilisation CPU était de 50%. Ce n’est pas tout à fait vrai. Et entre autre, pourquoi 1.0 ?

J’ai alors décidé de tout chercher et de le documenter ici.

Il est aussi dit que le meilleur moyen d’apprendre quelque chose est de tenter de l’enseigner.

htop sur Ubuntu Server 16.04 x64

Voici une copie d’écran de htop que je vais décrire.

htop

Uptime

L’uptime montre depuis combien de temps un système s’exécute.

Vous pouvez voir les mêmes informations en exécutant la commande uptime :

$ uptime 12:17:58 up 111 days, 31 min, 1 user, load average: 0.00, 0.01, 0.05

Comment le programme uptime sait-il cela ?

Il lit ces informations depuis le fichier /proc/uptime.

9592411.58 9566042.33

Le premier nombre est le nombre total de secondes pendant lequel le système s’exécute. Le second nombre est combien de secondes la machine a tourné au ralenti (idle). La seconde valeur peut être plus grande que l’uptime du système sur les systèmes avec de multiples coeurs puisqu’il s’agit d’une somme.

Comment l’ai-je su ? j’ai observé quels fichiers le programme uptime ouvrait lorsqu’on l’exécute. Nous pouvons utiliser l’outil strace pour cela.

$ strace uptime

Il va s’afficher beaucoup de choses. Nous pouvons utiliser grep pour l’appel système open. Mais cela ne marchera pas vraiment puisque strace redirige tout sur le flux de l’erreur standard (stderr). Nous pouvons rediriger stderr vers le flux de la sortie standard (stdout) avec 2>&1.

$ strace uptime 2>&1 | grep open
...
open("/proc/uptime", O_RDONLY) = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY) = 4

qui contient le fichier /proc/uptime que j’ai déjà mentionné.

Il se trouve que vous pouvez aussi utiliser strace -e open uptime et ne pas vous embêter avec grep.

Mais pourquoi avons-nous besoin du programme uptime si nous pouvons juste lire le contenu du fichier ? La sortie de la commande uptime est joliment formatée pour les humains tandis que le nombre de secondes est plus utile à réutiliser dans nos programmes ou scripts.


Premier partie en forme de mise en bouche, nous continuerons dans le second article de cette série par la notion de load average.

05 December, 2016 11:00PM by Carl Chenet

Florent Gallaire

Ruby est mourant (Python, Node.js, Go et Elixir l’ont tué)

En août 2015 GitHub publiait le classement des langage de programmation les plus populaires depuis son lancement en 2008. L’article mettait l’accent sur la progression de Java, lié à l’adoption des services de GitHub par les entreprises friandes de ce langage, mais c’est bien l’évolution de la popularité de Ruby qui m’avait le plus interpellé.

Leader aux premiers jours de 2008, avec en particulier la présence immédiate de Ruby on Rails sur GitHub (GitHub est une application Ruby en Rails), Ruby est passé 2ème en 2013, puis 3ème en 2014 et enfin 4ème en 2016.

github

Suivant de près la popularité des langages sur GitHub, j’ai eu la chance de capturer hier l’improbable moment où PHP – le grand-père du web en net regain de forme depuis la sortie de PHP 7 – a dépassé l’enfant prodige pour le reléguer à la 5ème place !

classment2

Mais si Ruby est mourant, quels sont donc ses meurtriers ?

Python pour la diversité d’utilisation

Python est un peu le concurrent historique de Ruby, tant ces deux langages semblaient occuper la même « niche » de langage de programmation moderne, dynamique et orienté objet. Ce que l’on peut faire avec Python on peut le faire avec Ruby, et réciproquement, le choix entre les deux est plus une question de feeling sur la syntaxe du langage ou l’ambiance de la communauté.

Oui mais justement, que fait-on avec ces langages ? En première page du site web du langage Python on peut trouver une section « Use Python for… » qui donne une réponse à cette question dans le but de conforter les débutants dans leur choix de Python : ils ne vont pas seulement apprendre un langage de programmation puissant et facile d’utilisation, mais aussi un outil pour faire plein de choses utiles et très diverses.

python

Car si Python est bien sûr utilisé pour la programmation web et qu’il a son alter ego de Rails avec Django, il est aussi énormément utilisé dans bien d’autres domaines. Python est installé par défaut sur toutes les distributions GNU/Linux et sur macOS, il est largement utilisé en administration système, s’est imposé pour des utilisations scientifiques et pédagogiques et représente le choix le plus simple et efficace pour développer des interface graphiques, avec de nombreux bindings vraiment fonctionnels et maintenus.

Ruby et sa communauté sont en comparaison par trop web-centric. Rails, Sinatra et Jekyll sont formidables, et ils étaient même très innovants, mais de nombreux projets s’en sont inspiré, des équivalents ont été développés dans d’autres langages et ils ne peuvent plus à eux seuls justifier d’apprendre le Ruby. Ruby a percé grâce à Rails et au web, mais il n’a jamais su s’en émanciper et c’est ce qui est en train de causer sa perte.

Node.js pour le buzz

D’une manière qui a parfois pu irriter les pythonistes, Ruby a longtemps eu l’image d’un langage cool, et tout ce qui s’y rapportait de près ou de loin faisait facilement le buzz. Oui mais voilà, Node.js est passé par là, amenant au JavaScript l’ubiquité, cette exceptionnelle singularité d’être le seul langage de programmation présent à la fois côté serveur et côté client.

trend

Node.js a bénéficié d’une large et dynamique communauté préexistante de développeurs JavaScript, ce qui a permis son adoption à une vitesse incomparable à celle d’un « nouvel entrant ». Node.js a donc attaqué frontalement Ruby sur sa niche web tenue par Ruby on Rails et l’a en quelque sorte dépossédé de son buzz.

Go et Elixir pour les performances

Deux langages de programmation récents ont aussi causé beaucoup de tort à Ruby en l’attaquant sur le terrain des performances, son point faible historique. On peut ainsi développer rapidement de beaux et fonctionnels sites web avec Ruby on Rails, mais quand le succès arrive, il est alors très difficile de scaler. Le remplacement de Ruby on Rails par du Java par Twitter en 2011 en est bien sûr l’exemple le plus cinglant.

Go est un langage de programmation compilé créé par Google en 2007 et rendu disponible en 2009. Alors que l’on pensait que ce langage allait attirer les développeurs C et C++ à la recherche de plus de confort, il a en fait attiré beaucoup de développeurs de langages dynamiques à la recherche de plus de performances. Ainsi de nombreuses personnes réécrivent leur application Rails en Go et constatent des gains de performances leur permettant par exemple de passer de 30 à 2 serveurs pour l’hébergement, ce qui implique des économies de travail, de temps et d’argent colossales.

Elixir est un langage de programmation fonctionnel datant de 2012 qui utilise BEAM, la formidable machine virtuelle massivement concurrente développée pour Erlang. La particularité d’Elixir est de reprendre la sémantique d’Erlang et de la proposer aux développeurs sous la forme d’une nouvelle syntaxe… inspirée du Ruby ! Cela n’est pas très surprenant quand on sait qu’Elixir a été créé par José Valim, un des principaux développeurs de Ruby on Rails. Et ce sont bien sûr les problèmes de performance de Ruby qui ont motivé sa démarche. Elixir se positionne donc clairement comme un nouveau Ruby, mais qui scale.

Il est très probable que Go et Elixir vont continuer à devenir de plus en plus populaires dans les années qui viennent, et que Ruby va avoir beaucoup de difficultés à s’en relever. Un dernier petit exemple en passant, sur les cinq logiciels libres dont je parlais dans mon article sur la base LEGI, deux sont en Python, un en PHP, un en Go, un en Julia… et aucun en Ruby.

05 December, 2016 06:18AM by fgallaire

December 04, 2016

Carl Chenet

L’édito de décembre 2016

Au cours du mois de novembre j’ai publié 8 billets relatifs aux usages et pratiques dans le Logiciel Libre et aux projets de logiciels que j’ai créés, comme Retweet ou PyMoneroWallet. La série d’articles Dans le Libre plaît bien et je m’en réjouis car il ne s’agit pas de billets simples en général, mais je pense qu’ils apportent vraiment des aspects souvent mal compris (ou compris trop tard) aux lecteurs qui iront au bout 🙂

monero-logo

Le Monero, crypto-monnaie dont j’ai déjà parlé ici, pour lequel j’ai écrit une bibliothèque PyMoneroWallet

Spéciale dédicace à mon billet sur Pourquoi je préfère la licence GPL aux licence permissives type BSD/MIT. C’est un sujet délicat et je ne voulais surtout pas imposer mon point de vue comme une vérité et que ça parte en troll complet. Ma démarche a été comprise et les commentaires ont été de grande qualité.

bsdvsgpl

GPL vs BSD, une opposition ancienne reposant sur des conceptions différentes de la liberté

Le réseau social Diaspora*

J’ai investi beaucoup de temps dans le réseau social Diaspora* récemment. Je prends beaucoup de plaisir à relayer du contenu vers ce réseau social, à y créer des liens et à y lire ce qui s’y passe. Le format plus expansif que Twitter permet, je trouve, des bons formats intermédiaires, entre les 140 caractères et les classiques billets de blog.

diaspora

Le logo de Diaspora*

Je vous conseille vraiment d’y jeter un coup d’œil si tout ce qui touche au Libre, aux mouvements alternatifs d’idées et à l’art actuel vous intéressent. J’ai personnellement un compte sur le Framasphere de Framasoft, merci à eux pour cette initiative, même si j’attends maintenant impatiemment l’implémentation de la fonctionnalité d’import/export d’un compte d’un pod à l’autre, fonctionnalité pour laquelle un financement participatif a été réalisé.

Journal du hacker

Le mois de novembre m’a réservé quelques surprises. Après la très réussie soirée anniversaire du Journal du hacker le 5 novembre dernier (merci à tout ceux qui étaient présents), j’ai repris mon travail sur la version 2 et les choses ont avancé beaucoup plus vite que je l’avais imaginé.

logo-journal-du-hacker

Le 20 novembre le blog du Journal du hacker ainsi que les services relatifs aux réseaux sociaux migraient vers le nouveau serveur. Et après un dernier coup de collier de la part de toute l’équipe sur la version 2, nous étions prêts à migrer le site principal vers le nouveau serveur. La migration du site principal ne saurait tarder.

Perspectives pour le mois de décembre 2016

Bon, on s’en doute, l’activité va fortement ralentir dans la seconde partie du mois de décembre avec les fêtes toussa, mais j’espère placer quelques articles d’ici-là, surtout qu’il y a des bonnes choses dans les cartons qui ne demandent plus qu’à en sortir (pas les cadeaux, les projets). Et ce dès mercredi 😉 À bientôt !

 

04 December, 2016 11:00PM by Carl Chenet

December 03, 2016

hackergotchi for Vincent Bernat

Vincent Bernat

Modification d'une dépendance à la compilation d'un projet Android

Dans cet article, je présente une méthode pour modifier une dépendance externe dans un projet Android lors de la compilation avec Gradle. Cette méthode met en œuvre l’API « Transform » et Javassist, un utilitaire de manipulation du bytecode Java.

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.+'
        classpath 'com.android.tools.build:transform-api:1.5.+'
        classpath 'org.javassist:javassist:3.21.+'
        classpath 'commons-io:commons-io:2.4'
    }
}

À noter que je ne suis pas un programmeur expérimenté avec Android. Il est donc possible que cet article contienne des erreurs plus ou moins grossières.

Contexte§

Cette section contextualise l’exemple qui va servir de support. Sa lecture n’est pas essentielle.

Dashkiosk est une application qui permet de gérer des tableaux de bords sur divers écrans. Elle dispose d’une application Android compagnon que l’on peut installer sur les clefs Android bon marché. En coulisses, l’application embarque une webview gérée par le projet Crosswalk. Cela permet d’avoir un moteur de rendu web à jour, quelle que soit la version d’Android1.

Récemment, une vulnérabilité a été découverte dans la mémorisation des certificats invalides. Quand un certificat ne peut être vérifié, la webview délègue la décision à l’application en invoquant la méthode onReceivedSslError() :

Indique à l’application qu’une erreur SSL a eu lieu en chargeant une ressource. L’application doit appeler callback.onReceiveValue(true) ou callback.onReceiveValue(false). La décision peut être réutilisée pour d’autres erreurs SSL. Le comportement par défaut est d’afficher une boîte de dialogue.

Le comportement par défaut est spécifique à Crosswalk : la webview d’Android se contente d’annuler le chargement de la resssource. Malheureusement, le correctif appliqué dans Crosswalk est différent et a pour effet de bord de ne plus tenir compte de la méthode onReceivedSslError().

Dashkiosk propose une option pour ignorer les erreurs TLS2. Le correctif casse cette fonctionnalité. L’exemple qui suit montre comment modifier Crosswalk pour restaurer l’ancien comportement3.

Remplacement d’une méthode§

Nous allons remplacer la méthode shouldDenyRequest() de la classe org.xwalk.core.internal.SslUtil avec cette version :

// Dans la classe SslUtil
public static boolean shouldDenyRequest(int error) {
    return false;
}

Squelette de la transformation§

L’API de transformation de Gradle permet de manipuler les fichiers de classes avant que ceux-ci ne soient convertis au format DEX. Pour déclarer une transformation, nous ajoutons le code suivant au fichier build.gradle:

import com.android.build.api.transform.Context
import com.android.build.api.transform.QualifiedContent
import com.android.build.api.transform.Transform
import com.android.build.api.transform.TransformException
import com.android.build.api.transform.TransformInput
import com.android.build.api.transform.TransformOutputProvider
import org.gradle.api.logging.Logger

class PatchXWalkTransform extends Transform {
    Logger logger = null;

    public PatchXWalkTransform(Logger logger) {
        this.logger = logger
    }

    @Override
    String getName() {
        return "PatchXWalk"
    }

    @Override
    Set<QualifiedContent.ContentType> getInputTypes() {
        return Collections.singleton(QualifiedContent.DefaultContentType.CLASSES)
    }

    @Override
    Set<QualifiedContent.Scope> getScopes() {
        return Collections.singleton(QualifiedContent.Scope.EXTERNAL_LIBRARIES)
    }

    @Override
    boolean isIncremental() {
        return true
    }

    @Override
    void transform(Context context,
                   Collection<TransformInput> inputs,
                   Collection<TransformInput> referencedInputs,
                   TransformOutputProvider outputProvider,
                   boolean isIncremental) throws IOException, TransformException, InterruptedException {
        // Il faudrait faire quelque chose ici...
    }
}

// Enregistrement de la transformation
android.registerTransform(new PatchXWalkTransform(logger))

La méthode getInputTypes() retourne un ensemble de types de données gérés par la transformation. Dans notre cas, nous allons transformer des classes. Une autre possibilité est de transformer des ressources.

La méthode getScopes() indique la portée de la transformation. Dans notre cas, nous ne voulons transformer que les dépendances externes. Il est aussi possible de transformer ses propres classes.

Telle qu’implémentée, la méthode isIncremental() indique que l’on sait gérer la construction incrémentale. Ce n’est pas très compliqué à faire.

La méthode transform() prend un ensemble de fichiers en entrée et doit les copier (avec ou sans modifications) à l’endroit que lui indique son quatrième argument. Nous n’avons pas encore implémenté cette fonction. Du coup, actuellement, la transformation retire juste toutes les dépendances externes de l’application.

Transformation à vide§

Pour garder toutes les dépendances externes sans apporter de modifications, nous devons copier les fichiers fournis :

@Override
void transform(Context context,
               Collection<TransformInput> inputs,
               Collection<TransformInput> referencedInputs,
               TransformOutputProvider outputProvider,
               boolean isIncremental) throws IOException, TransformException, InterruptedException {
    inputs.each {
        it.jarInputs.each {
            def jarName = it.name
            def src = it.getFile()
            def dest = outputProvider.getContentLocation(jarName, 
                                                         it.contentTypes, it.scopes,
                                                         Format.JAR);
            def status = it.getStatus()
            if (status == Status.REMOVED) { // ❶
                logger.info("Remove ${src}")
                FileUtils.delete(dest)
            } else if (!isIncremental || status != Status.NOTCHANGED) { // ❷
                logger.info("Copy ${src}")
                FileUtils.copyFile(src, dest)
            }
        }
    }
}

Le code ci-dessus nécessite deux imports additionnels :

import com.android.build.api.transform.Status
import org.apache.commons.io.FileUtils

Comme nous ne gérons que des dépendances externes, nous n’avons qu’à nous occuper de fichiers JAR. Ainsi, l’itération a lieu uniquement sur jarInputs et non sur directoryInputs. Lors d’une construction incrémentale, il y a deux cas à gérer : soit le fichier a été retiré (❶), soit il a été modifié (❷). Dans les autres cas, nous considérons que le fichier est déjà à sa place.

Modification d’un JAR§

Lors du traitement du fichier JAR de Crosswalk, nous devons aussi le modifier. Voici la première partie du code (en replacement du code en ❷) :

if ("${src}" ==~ ".*/org.xwalk/xwalk_core.*/classes.jar") {
    def pool = new ClassPool()
    pool.insertClassPath("${src}")
    def ctc = pool.get('org.xwalk.core.internal.SslUtil') // ❸

    def ctm = ctc.getDeclaredMethod('shouldDenyRequest')
    ctc.removeMethod(ctm) // ❹

    ctc.addMethod(CtNewMethod.make("""
public static boolean shouldDenyRequest(int error) {
    return false;
}
""", ctc)) // ❺

    def sslUtilBytecode = ctc.toBytecode() // ❻

    // Écriture du nouveau fichier JAR
    // …
} else {
    logger.info("Copy ${src}")
    FileUtils.copyFile(src, dest)
}

Il est nécessaire d’ajouter les imports suivant pour utiliser Javassist :

import javassist.ClassPath
import javassist.ClassPool
import javassist.CtNewMethod

Lorsque le fichier en cours est celui que nous voulons modifier, nous l’ajoutons à notre classpath et récupérons la classe qui nous intéresse (❸). Cela nous permet d’effacer la méthode shouldDenyRequest() (❹). Ensuite, nous pouvons ajouter notre propre version (❺). La dernière étape consiste à récupérer le bytecode correspondant à la classe modifiée (❻).

Il reste enfin à reconstruire le fichier JAR :

def input = new JarFile(src)
def output = new JarOutputStream(new FileOutputStream(dest))

// ❼
input.entries().each {
    if (!it.getName().equals("org/xwalk/core/internal/SslUtil.class")) {
        def s = input.getInputStream(it)
        output.putNextEntry(new JarEntry(it.getName()))
        IOUtils.copy(s, output)
        s.close()
    }
}

// ❽
output.putNextEntry(new JarEntry("org/xwalk/core/internal/SslUtil.class"))
output.write(sslUtilBytecode)

output.close()

Il convient d’importer les classes suivantes :

import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
import org.apache.commons.io.IOUtils

Il y a deux étapes. En ❼, toutes les classes, à l’exception de SslUtil sont copiées dans le nouveau fichier JAR. En ❽, le bytecode précédemment modifié pour SslUtil est ajouté.

C’est tout ! L’exemple complet est disponible sur GitHub.

Fonctions avec dépendances§

Dans l’exemple précédent, la nouvelle méthode n’utilisait aucune dépendance externe. Supposons maintenant que nous voulons remplacer la méthode sslErrorFromNetErrorCode() de la même classe avec celle-ci :

import org.chromium.net.NetError;
import android.net.http.SslCertificate;
import android.net.http.SslError;

// Dans la classe SslUtil
public static SslError sslErrorFromNetErrorCode(int error,
                                                SslCertificate cert,
                                                String url) {
    switch(error) {
        case NetError.ERR_CERT_COMMON_NAME_INVALID:
            return new SslError(SslError.SSL_IDMISMATCH, cert, url);
        case NetError.ERR_CERT_DATE_INVALID:
            return new SslError(SslError.SSL_DATE_INVALID, cert, url);
        case NetError.ERR_CERT_AUTHORITY_INVALID:
            return new SslError(SslError.SSL_UNTRUSTED, cert, url);
        default:
            break;
    }
    return new SslError(SslError.SSL_INVALID, cert, url);
}

La principale différence est l’importation de classes supplémentaires.

Import du SDK Android§

Le SDK Android ne fait pas partie des dépendances externes. Il convient de l’importer manuellement. Le chemin complet vers le fichier JAR est :

androidJar = "${android.getSdkDirectory().getAbsolutePath()}/platforms/" +
             "${android.getCompileSdkVersion()}/android.jar"

Il faut l’ajouter au classpath avant d’ajouter la nouvelle méthode dans la classe SslUtil :

def pool = new ClassPool()
pool.insertClassPath(androidJar)
pool.insertClassPath("${src}")
def ctc = pool.get('org.xwalk.core.internal.SslUtil')
def ctm = ctc.getDeclaredMethod('sslErrorFromNetErrorCode')
ctc.removeMethod(ctm)
pool.importPackage('android.net.http.SslCertificate');
pool.importPackage('android.net.http.SslError');
// …

Import d’une autre dépendance externe§

Nous devons aussi importer org.chromium.net.NetError et donc mettre le fichier JAR approprié dans le classpath. La façon la plus simple de faire ceci est d’itérer de nouveau sur toutes les dépendances externes et de les ajouter au classpath :

def pool = new ClassPool()
pool.insertClassPath(androidJar)
inputs.each {
    it.jarInputs.each {
        def jarName = it.name
        def src = it.getFile()
        def status = it.getStatus()
        if (status != Status.REMOVED) {
            pool.insertClassPath("${src}")
        }
    }
}
def ctc = pool.get('org.xwalk.core.internal.SslUtil')
def ctm = ctc.getDeclaredMethod('sslErrorFromNetErrorCode')
ctc.removeMethod(ctm)
pool.importPackage('android.net.http.SslCertificate');
pool.importPackage('android.net.http.SslError');
pool.importPackage('org.chromium.net.NetError');
ctc.addMethod(CtNewMethod.make("…"))
// Puis reconstruction du fichier JAR...

Happy hacking !


  1. Avant Android 4.4, la webview était largement obsolète. Depuis Android 5, elle se trouve sous forme d’un composant séparé maintenu à jour comme une application. L’utilisation de Crosswalk reste pratique pour s’assurer de la version utilisée. 

  2. Cela peut sembler dangereux et c’est le cas. Toutefois, si l’on utilise une CA interne, il n’est pas possible de demander à la webview de l’utiliser. Le magasin de certificats système n’est pas utilisé non plus. Il est également possible d’utiliser TLS uniquement pour l’authentification avec des certificats clients, ce qui est une possibilité supportée par Dashkiosk

  3. Crosswalk étant un projet libre, une alternative aurait été d’en modifier le source et de le recompiler. Toutefois, le projet embarque Chromium et nécessite énormément de ressources pour venir au bout de la compilation. 

03 December, 2016 10:20PM by Vincent Bernat

November 29, 2016

Carl Chenet

Pourquoi je préfère la licence GPL aux licences permissives type BSD/MIT

En avant-propos, ce billet ne représente que ma démarche personnelle et mon humble point de vue sur l’utilisation des licences libres, correspondant forcément à ma façon d’agir, de faire, un point de vue duquel je suis volontiers prêt à discuter.

En matière de licence, pour tout ce qui ne concerne pas mes projets personnels, j’adopte complètement le point de vue de Zed Shaw, auteur du manuel de Python Learn Python The Hard Way et d’articles parfois polémiques (mais souvent intéressants), qui a écrit son point de vue sur le choix de la licence d’un logiciel par son auteur dans cet article (traduit par Framasoft, source originale en anglais) et que je vais essentiellement résumer par cette citation :

I really don’t care what license people use on their software, it’s their software and bitching at them for the license they choose is offensive. They wrote it, put their blood and sweat into it, and you should be glad that you get the privilege of even seeing it.

(traduction approximative : Je me fiche complètement de la licence que les gens utilisent pour leur logiciel, c’est leur logiciel et dire du mal d’eux pour la licence qu’ils ont choisi est offensant. Ils l’ont écrit, ont sué sang et eau pour lui et vous devriez être content d’avoir le privilège de juste le voir)

En tant que programmeur du Logiciel Libre, je ne peux qu’adhérer à ce point de vue. Par contre, je peux décrire pourquoi dans quasiment tous mes projets je n’utilise – personnellement encore une fois – que la GPLv3 (General Public License version 3).

GPL vs BSD

GPL vs BSD, une opposition classique au sein du Logiciel Libre

Éviter la fuite de code hors de la communauté

Rappelons quelques bases : tout le code écrit sous une licence permissive type BSD ou MIT restera dans la communauté du Libre. Par contre l’une des principales caractéristiques des licences permissives est la possibilité offerte de rendre privatrice une bifurcation (fork) d’une base de code au précédent sous une licence permissive. Très concrètement, il est autorisé de bifurquer un logiciel sous licence BSD ou MIT et d’en faire un logiciel privateur. Cet aspect est bien connu et parfois voulu des utilisateurs de ces licences, permettant toutes les utilisations possibles des bases de code sous ces licences. Le but recherché est d’attirer la plus large base possible d’utilisateurs et de contributeurs qui utiliseront et contribueront peut-être un jour à la base de code originale ou à ses dérivées.

FreeBSD, principal projet des BSD sous licence MIT

FreeBSD, principal projet sous licence BSD

J’ai toujours été pour ma part gêné par cette caractéristique des licences permissives. Je l’assimile à une potentielle fuite de code hors de la communauté. En effet, un cas d’usage de ces licences va consister à bifurquer une base de code existante et à implémenter de nouvelles fonctionnalités à partir de cette base de code. Ces nouvelles fonctionnalités, développées au sein d’une base de code privatrice, n’alimenteront donc pas en retour la base de code communautaire, accessible publiquement, librement utilisable et modifiable.

Prenons un cas assez courant, les routeurs construits sur une base de code sous licence BSD (souvent FreeBSD et OpenBSD). Pour le dire franchement, la liste de ces produits est à tomber par terre. Et ça n’est bien sûr que l’extrême sommet de l’iceberg.

Ma position est donc au final que ces licences permissives, bien que facilitant l’appropriation d’un Logiciel Libre et assurant à l’individu le maximum de droits sur une base de code qu’il n’a pas écrite, desservent la communauté dans son ensemble en laissant optionnelle la réintégration à la base de code communautaire les éventuels développements survenus sur la bifurcation devenue privatrice, développements pourtant eux-mêmes basés sur cette base de code produite à l’origine par la communauté.

iceberg

On peut se douter de la masse de produits privateurs réalisés à partir de logiciels sous licences permissives par l’important nombre de ceux qui sont connus

Une licence est fondée sur le droit, pas sur l’informatique

La GPLv3 et d’une manière générale perçue comme complexe par les informaticiens du Libre, ce qui représente un frein à son adoption. Inutile de le nier, elle l’est indubitablement pour quelqu’un de non-formé au droit (moi le premier). Le texte court et aisément compréhensible des licences BSD/MIT provoque souvent un phénomène d’adhésion, faisant que les licences BSD/MIT sont souvent préférées à la GPLv3. Mais cette brièveté cache des conséquences potentielles insoupçonnées, dont la plus importante a été décrite au chapitre précédent.

C’est à mon sens une grave erreur que de se référer à la brièveté d’une licence pour la percevoir comme « bonne ». Il est bon d’avoir le contrôle complet sur ce que l’on produit, mais la licence n’est pas une partie technique du programme, mais la définition juridique des droits que vous accordez à vos futurs utilisateurs et exploitants de votre code, le droit d’auteur vous donnant par défaut tous les droits sur la production de votre programme.

La licence évolue dans le monde du droit et le fait que vous soyez ou non capable de la lire ne devrait avoir dans les faits avoir que peu d’importance. Êtes-vous capable d’écrire vous-même le contrat de vente de votre maison ? Êtes-vous capable de percevoir et comprendre toutes les implications des conditions générales d’utilisation et de confidentialité des services en ligne que vous utilisez, comme celles de Facebook ou Gmail (désolé si vous n’êtes pas utilisateur de ces services, beaucoup le sont même chez les Libristes. J’utilise moi-même Twitter) ? La plupart du temps, vous n’êtes pas en capacité de le faire et vous devez vous appuyer sur un avocat pour étudier correctement un contrat. C’est absolument la même chose avec votre programme. Si vous souhaitez le défendre juridiquement de manière efficace, il vous faudra vous reposer sur le travail de professionnels du droit.

Eben Moglen

Eben Moglen, avocat conseil de la Free Software Foundation et président du Software Freedom Law Center.

Et c’est ici que la GPLv3 entre en jeu. Autant elle peut paraître effrayante par sa complexité, autant elle protégera juridiquement de manière efficace votre logiciel. Cette licence a su évoluer face aux attaques que le Logiciel Libre a subi, comme la Tivoisation. Cela est bien sûr valable si vous adhérez aux principes prônés par le créateur de cette licence, ce qui est mon cas dans le cadre de mes projets.

Une licence en accord avec sa démarche propre

Comme décrit en introduction, je pense qu’il faut accorder de l’importance à la licence qu’on choisit pour son logiciel afin de le protéger juridiquement, et par la même occasion protéger sa communauté d’utilisateurs et le travail produit par cette communauté.

Ce choix est également primordial pour s’assurer que le cadre d’utilisation dudit logiciel sera conforme à celui que désirait le créateur du projet. Dans mon cas, la GPLv3 accorde à chaque utilisateur du code les mêmes droits mais aussi les mêmes devoirs, à savoir reverser à la communauté le code modifié rendu public en conservant la même licence. Cela permet ainsi aux individus de se nourrir du travail de la communauté, et la communauté de bénéficier du travail des individus. Un cercle vertueux qui correspond à mon idéal personnel pour la communauté du Logiciel Libre.

Et vous ? Que pensez-vous du choix de la licence GPLv3 au lieu des licences plus permissives type BSD/MIT pour vos projets ? N’hésitez pas à réagir dans les commentaires.

29 November, 2016 11:00PM by Carl Chenet

November 23, 2016

hackergotchi for Tanguy Ortolo

Tanguy Ortolo

Interdit ou autorisé ?

Vu près de l'entrée d'un jardin public, celui de Brimborion, de mémoire :

Panneau rond avec une large bordure verte et un vélo noir au milieu

Alors, dans ce parc, le vélo est-il autorisé, interdit, recommandé, obligatoire ? (Rayez les mentions inutiles.)

C'est interdit, évidemment, mais modifier ainsi la couleur d'un panneau standard est une très mauvaise idée. Et la raison pour laquelle cette erreur a été commise, à savoir mieux s'assortir avec la couleur de l'environnement, est parfaitement stupide. Service des parcs de Sèvres, changez-moi ça tout de suite !

23 November, 2016 04:56PM by Tanguy

November 22, 2016

Carl Chenet

Dans le Libre : faire sien un logiciel

Utilisant uniquement du Logiciel Libre dans le cadre de mes différents projets, qu’il s’agisse du site d’actualité le Journal du hacker, le site d’emploi dédié au Logiciel Libre et à l’open source LinuxJobs.fr ou encore ce blog, j’ai pu constater l’innovation qui découle du travail sur du code libre et les interactions qui se créent avec les communautés du Libre.

Dans la suite de cet article je m’attacherai à décrire les différentes façons dont  on peut « s’approprier » un logiciel. Par s’approprier un logiciel libre, j’entends l’utiliser et le faire sien au point qu’il remplisse exactement nos besoins, en y contribuant ou en bifurquant (fork) sa base de code au besoin.

Un bel exemple des bifurcations du projet Debian

Un bel exemple des bifurcations du projet Debian

Je décrirai différentes formes possibles d’utilisation des bases de code présentes dans le Libre, les interactions qui se créent avec leurs utilisateurs et développeurs autour de ces bases de code. Ces utilisations et leurs conséquences seront basées sur des exemples réels et récents.

Utiliser et contribuer en retour

Lorsqu’on découvre un logiciel libre correspondant à nos besoins, il s’en suit souvent une période d’appropriation. Il faut comprendre par ce terme l’essayer et le faire fonctionner dans le but de remplir nos besoins et non plus seulement ceux du créateur du projet, qui peuvent être légèrement différents. Des adaptations sont parfois nécessaires et la documentation est parfois (souvent ?) incomplète ou tout simplement manquante.

Dans mon précédent article Gratter ses propres démangeaisons, j’ai décrit les étapes selon moi essentielles à vérifier avant de commencer à coder un nouveau projet. Dans cet état d’esprit, lorsque j’ai voulu créer le Journal du hacker, un agrégateur de liens communautaire pour le Logiciel Libre francophone, il me paraissait aberrant de devoir ré-écrire moi-même un moteur à la Hacker News, le site le plus connu de ce type.

Le Journal du hacker, basé sur le moteur du site lobste.rs sous licence BSD.

Le Journal du hacker, basé sur le moteur du site lobste.rs sous licence BSD.

Ayant trouvé un autre site sur le même principe, lobste.rs, propulsé lui par un logiciel libre sous licence BSD, j’ai commencé à étudier les sources de ce dernier. Et mes premiers tests d’appropriation  m’ont confronté à un important problème : le moteur ne supportait pas les caractères accentués français. Il fallait donc implémenter l’internationalisation du moteur et écrire la localisation française de l’application.

Ma future contribution à la base de code existante était donc toute trouvée 🙂

Bifurquer pour créer

J’ai abordé dans l’un de mes précédents articles le rôle critique de la bifurcation (fork) dans le Logiciel Libre. Elle est en fait essentielle dans la vie d’un logiciel, ce dernier pouvant socialement (et à terme techniquement) dépérir à cause d’un mainteneur absent ou abusivement fermé aux contributeurs extérieurs. La bifurcation assure de redynamiser la vie de la base de code et du projet autour de celle-ci. Cette action a bien sûr des avantages et des inconvénients, abordés dans l’article.

Pour continuer dans notre exemple du Journal du hacker, rares sont les projets aujourd’hui qui peuvent se permettre d’ignorer les réseaux sociaux. Un site d’information visant les Libristes avait de grandes chances de ne jamais se faire connaître sans être présent sur au moins l’un d’eux, afin de se créer un public. De très nombreux Libristes étant présents sur Twitter, j’investiguais les différentes solutions de relayer les informations du Journal du hacker vers le compte Twitter dédié à ce projet.

Le compte Twitter du Journal du hacker

Je me suis finalement arrêté sur un petit projet à l’abandon, rss2twitter, permettant de poster chaque entrée d’un flux RSS vers le réseau social Twitter. La base de code de rss2twitter était assez simple pour être rapidement relue et comprise.

Grâce à cette base de code existante, il était possible de passer immédiatement l’outil en production tout en y apportant régulièrement des améliorations selon mes besoins. Et cela tombait plutôt bien, dans le cadre de LinuxJobs.fr j’avais exactement le même besoin pour relayer les dernières offres d’emploi postées sur le site vers Twitter.  Le projet Feed2tweet était né.

J’allais au fil du temps apporter à la communauté un nouvel outil auto-hébergé, codé de façon modulaire dans un langage moderne, plus complet que ses prédécesseurs par des fonctionnalités ajoutées seulement en cas de besoin réel et surtout bien documenté pour qu’il puisse être facilement compris et utilisé par la base d’utilisateurs (et d’éventuels contributeurs) la plus large possible. Ce qui s’est avéré payant avec de nombreuses fonctionnalités entièrement codées par des nouveaux contributeurs. Encore une fois, donner et recevoir.

Documentation de Feed2tweet sur Readthedocs

Documentation de Feed2tweet sur Readthedocs

Le choix de basculer vers la licence GPL au lieu de la licence MIT a également permis de maintenir dans le Libre ces innovations et de les protéger là où l’utilisation d’une licence plus permissive aurait permis la réappropriation de ces fonctionnalités par un logiciel privateur, cas de figure proscrit par l’utilisation de la GPL.

Innover pour ruser

Quand vous êtes seul avec votre petit projet face au monde et à l’absence d’intérêt de votre communauté pour un projet balbutiant donc non-mature et pour laquelle le concept peut apparaître dans un premier temps flou, il faut ruser pour se faire connaître, pour attirer des utilisateurs qui seront peut-être de futurs contributeurs, bref pour exister.

Ayant constitué au fil du temps un compte Twitter avec un nombre correct d’abonnés, quasiment tous libristes, j’ai commencé à retweeter à la main les premiers articles relayés sur le Journal du hacker. La mayonnaise a semblé prendre et des abonnés à mon compte ont commencé à s’abonner également au compte Twitter du Journal du hacker.

Un retweet automatique depuis @journalduhacker vers @carl_chenet

Un retweet automatique depuis @journalduhacker vers @carl_chenet

Rapidement la tâche est devenue chronophage, il était temps de l’automatiser. Après avoir testé des services en ligne horribles par leur lenteur, l’amateurisme de l’interface, et leur envahissement de ma vie privée par le rajout de mentions obligatoires à mes propres tweets, j’ai senti le besoin et donc l’opportunité d’écrire un logiciel simple auto-hébergé répondant à mon besoin. De ce besoin est né le projet Retweet.

La démarche était sensiblement la même que pour Feed2tweet. Codé en Python 3, documenté, présentant des exemples  d’utilisation et ouvert aux contributions, Retweet a peu à peu trouvé son public. Il a été complété au fil des versions par des besoins apparaissant à l’épreuve d’une utilisation quotidienne en production, comme décrit dans mon précédent article Manger ce que l’on prépare.  La dernière version 0.10 a été contribuée à 99% par un nouveau contributeur au projet, je ne me suis chargé que de la relecture des changements, des tests et de la publication de cette version.

Un petit remerciement au fier contributeur dans le changelog, indispensable !

Un petit remerciement au fier contributeur dans le changelog, indispensable !

Sans être véritablement un cas d’appropriation d’un logiciel existant, innover pour ruser est une démarche de réaction face à la constatation d’un besoin existant et non résolu selon vos besoins spécifiques. Cette approche doit rester au cœur de l’approche d’un problème par le Libriste, d’où sa présence dans cet article.

Les grands axes de l’appropriation

Au cours de cet article nous avons présenté trois types d’appropriation d’un logiciel libre :

  • utiliser et contribuer en retour : l’utilisation d’un logiciel, la constatation d’un manque par rapport à nos besoins et l’écriture par soi-même des fonctionnalités manquantes, avec comme but de les reverser un jour au projet amont
  • bifurquer pour créer : l’utilisation d’un logiciel dont le projet autour est à l’arrêt, avec la réalisation rapide d’une bifurcation pour améliorer la base de code et relancer le projet pour attirer des utilisations/contributeurs, sans volonté de continuer à avoir des liens avec le projet dont on a bifurqué
  • innover pour ruser : l’identification d’une tâche récurrente et la création d’un logiciel pour automatiser la tâche, avec la volonté de répondre à notre besoin tout en fournissant des bases solides pour créer un logiciel ré-utilisable par la communauté qui pourra y contribuer en retour

On peut dégager de ces exemples quelques grands axes d’appropriation : il faut s’assurer de la compatibilité du logiciel avec lequel on souhaite travailler avec nos buts. Il faut également être capable de faire évoluer la base de code pour répondre à nos besoins non-satisfaits. En cas de bifurcation ou de création d’un nouveau logiciel, un grand soin doit être apporté à la documentation et à l’assistance des utilisateurs (qui peuvent devenir des contributeurs) pour assurer que le projet soit suffisamment ouvert à la communauté pour être véritablement attractif. Ainsi armés vos utilisateurs et contributeurs seront à même de vous faire des retours utiles pour débugger votre programme ou en améliorer les fonctionnalités.

Et vous ? comment avez-vous fait vôtre un logiciel libre pour répondre à vos besoins ? N’hésitez pas à laisser votre témoignages dans vos commentaires.

22 November, 2016 11:00PM by Carl Chenet

November 19, 2016

hackergotchi for J. Fernando Lagrange

J. Fernando Lagrange

Debian Stretch et Dell Latitude E6520: installation

J’ai un nouveau travail, pour lequel on m’a fourni un Dell Latitude E6520. Voici comment j’ai installé Debian 9 Stretch testing dessus.

Debian testing est la version actuellement en développement de la prochaine version stable de Debian. Elle est aussi disponible sous le nom de la future version, c’est-à-dire Stretch (depuis le 25 avril 2015).
(Extrait du wiki officiel)

Ma démarche pour installer Stretch

Pour installer la future Debian stable, j’ai suivi les étapes suivantes (indiquées comme la manière la plus fiable dans le wiki officiel (il est aussi possible d’utiliser l’installateur encore en version alpha pour Stretch):

  1. Installer Debian 8 Jessie stable à partir d’une clé USB
  2. Changer les sources de paquets
  3. Mettre à jour vers Debian 9 Stretch testing

Installer Debian 8 Jessie stable à partir d’une clé USB

Préparation de et démarrage sur la clé USB

En trois étapes:

  1. Télécharger la dernière version stable (la 8.6.0 en cemoment)
    À partir du lien en haut à droite de la page d’accueil du projet Debian
  2. Copier le contenu de ce téléchargement sur une clé USB
    Avec la commande # cp /chemin/dossier/téléchargement/debian-8.6.0-amd64-i386-netinst.iso /dev/sd<ma_cle_usb>
  3. Démarrer l’ordinateur sur la clé USB
    Pour cela, sur ce Dell (Latitude E6520), appuyer sur F12 pendant le démarrage de l’ordinateur et sélectionner la clé USB

« Options » choisies pendant l’installation

Mes « options » préférées pendant une installation de poste de travail:

  • Ne pas mettre de mot de passe au compte de l’administrateur (root): cela installe sudo et ajoute l’utilisateur créé pendant l’installation dans le groupe sudo
  • Utiliser le disque en entier avec LVM et une partition chiffrée, qui contient tous les dossiers
  • Choisir l’environnement de bureau XFCE

Changer les sources de paquets

Dans /etc/apt/sources.list, changer jessie par stretch, le fichier final que j’ai utilisé est le suivant:

# 

deb http://httpredir.debian.org/debian/ stretch main
deb-src http://httpredir.debian.org/debian/ stretch main

deb http://security.debian.org/ stretch/updates main
deb-src http://security.debian.org/ stretch/updates main

deb http://httpredir.debian.org/debian/ stretch-updates main
deb-src http://httpredir.debian.org/debian/ stretch-updates main

Puis mettre à jour la liste des paquets disponibles: # apt update

Mettre à jour vers Debian 9 Stretch testing

En trois étapes:

  1. Mettre à jour l’outil de gestion des paquets:
    # apt install apt
  2. Mettre à jour les paquets installés:
    # apt upgrade
  3. Redémarrer (je ne sais pas si c’est nécessaire, mais cela permet d’utiliser le noyau qui vient d’être installé):
    # reboot
  4. Finir la mise à jour:
    # apt full-upgrade

Note:

  • Pendant la mise à jour, j’ai rencontré un problème, temporaire et dont la cause première a déjà été corrigée), en indiquant que le paquet rdnssd est en conflit avec network-manager. Comme j’utilise network-manager, j’ai résolu ce problème en supprimant le paquet rdnssd, qui ne me semble pas nécessaire dans mon cas.

Et voilà !

Comme ce modèle n’était pas dans la partie « Installing Debian On » du wiki, je l’ai ajouté ! 🙂

19 November, 2016 11:44AM by Low Memory

November 14, 2016

hackergotchi for Raphaël Hertzog

Raphaël Hertzog

Mes activités libres en octobre 2016

Mon rapport mensuel couvre une grande partie de mes contributions au logiciel libre. Je l’écris pour mes donateurs (merci à eux !) mais aussi pour la communauté Debian au sens large parce que cela peut donner des idées aux nouveaux venus et que c’est également un des moyens les plus effectifs de trouver des volontaires pour travailler sur les projets qui me tiennent à cœur.

Debian LTS

J’ai commencé à travailler le mois dernier sur le paquet tiff3, mais je n’ai pas eu suffisamment de temps pour compléter la mise à jour. Il s’est avéré que les problèmes étaient suffisamment épineux pour que personne ne prenne le relai. En conséquence, j’ai recommencé à travailler sur tiff3 et tiff ce mois-ci, passant l’intégralité des 13 heures allouées sur ces deux paquets.

J’ai soumis des rapports de bogue pour des problèmes non encore remontés sur le suiveur de bogues (n°842361 pour la CVE-2016-5652, n°842046 pour les CVE-2016-5319/CVE-2016-3633/CVE-2015-8668). J’ai marqué plusieurs CVE comme n’affectant pas tiff3, dans la mesure où ce paquet n’embarque pas d’outils, a contrario du paquet source « tiff ».

Dans la mesure où l’amont a décidé d’abandonner plusieurs outils plutôt que de corriger leurs failles de sécurité, j’ai également opté pour leur retrait. Avant de faire cela, j’ai recherché les dépendances inverses de libtiff-tools, afin de m’assurer qu’aucun des outils supprimés n’était utilisé par d’autres paquets (ce que le mainteneur semble confirmer).

J’ai rétroporté les patchs amont pour les CVE-2016-6223 et CVE-2016-5652.

Mais le plus clair du temps a été passé sur les CVE-2014-8128, CVE-2015-7554 et CVE-2016-5318. Je pense qu’il s’agit là de plusieurs variantes d’un même problème, ce que l’amont semble penser également, puisqu’il a créé une sorte de meta-bogue pour les suivre. Je me suis inspiré d’un patch suggéré dans le ticket n°2499, que j’ai un peu généralisé en essayant d’ajouter les données du tag pour tous les tags manipulés par les divers outils. Ce fut un processus laborieux, car il y a de nombreux tags qui sont utilisés à de nombreux endroits. Ceci étant, cela a marché comme prévu. Je ne parviens plus à reproduire les erreurs de segmentation avec les fichiers qui posaient problème.

J’ai demandé de l’aide sur la liste de diffusion pour passer en revue/tester le résultat, mais n’ai pas eu beaucoup de retour. Je vais bientôt pousser les paquets mis à jour.

Distro Tracker

J’ai noté une augmentation soudaine du nombre d’adresses email automatiquement désinscrites du suiveur de paquets Debian, et j’ai reçu quelques requêtes de rejet (« bounces »). Il s’avère que le suiveur de bogues a relayé beaucoup de spams, auxquels étaient attachés des fichiers exécutables. Spams qui ont donc été rejetés par Google (et non pas simplement mis de côté). Ce qui est regrettable… il y a peu de chance que le flux de spams se tarisse, et il n’y a pas non plus de raison d’attendre de Google qu’il change de comportement. Je n’ai donc eu d’autre choix que d’essayer de rendre le gestionnaire de rejet plus intelligent, ce que j’ai fait : j’ai mis en place une liste d’expressions régulières qui vont annuler un rejet. En d’autres termes, une fois que le rejet correspond à l’une de ces expressions, celui-ci n’est plus pris en compte dans le déclenchement de la désinscription automatique.

Travaux Debian divers

Rapports de bogue créés Dans le ticket n°839403, j’ai suggéré la possibilité de définir directement l’indice de priorité d’une source dans le fichier sources.list. Dans le n°840436, j’ai demandé au mainteneur du paquet selenium-firefoxdriver de faire le nécessaire afin que son paquet non-libre soit compilé automatiquement.

Empaquetage J’ai parrainé la version 2.0.2-0.1 de puppet-lint, et passé en revue le paquet rozofs (que je viens juste de parrainer dans experimental, pour commencer).

Publicité Je maintiens le compte Debian sur Twitter et Facebook. J’ai utilisé twitterfeed.com jusqu’à présent, mais ce dernier est en train de fermer. J’ai suivi leurs recommandations et basculé vers dlvr.it, de sorte à ce que les entrées soient automatiquement reprises depuis le fil micronews.debian.org. Dans le rapport de bogue n°841165, j’ai remonté le fait qu’il manque aux chroots créés par sbuild-createchroot les entrées IPv6 habituelles créées par netbase. Dans le ticket n°841503, j’ai consigné un problème que j’ai constaté de nombreuses fois (dans Debian et Kali) lors de mises à jour d’une installation cryptsetup typique.

Merci

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in October 2016 contribuée par Weierstrass01.

Aucun commentaire pour le moment | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

14 November, 2016 02:22PM by Raphaël Hertzog

November 12, 2016

Florent Gallaire

Open Data juridique : l’utilisation de la base LEGI

Suite au rapport sur l’ouverture des données publiques que le magistrat à la Cour des comptes et développeur Debian Mohammed Adnène Trojette a remis au Premier ministre le 5 novembre 2013, la majorité des bases de données juridiques de l’administration française ont été rendues disponibles en Open Data.

Ainsi, depuis juin 2014, la base LEGI, composée de l’ensemble des codes, lois et règlements français, est mise à disposition par la DILA, la Direction de l’information légale et administrative. La base complète est fournie environ deux fois par an sous la forme d’un ficher archive compressé, auquel viennent s’ajouter des mises à jour quotidiennes.

La base LEGI est très imposante. La dernière archive complète (Freemium_legi_global_20160406-082840.tar.gz) pèse 745 Mo, et elle se décompresse dans un répertoire legi d’une taille variant entre 9 et 15 Go selon votre système de fichiers.

Une fois que les données sont en Open Data, toutes les initiatives deviennent possibles. Voici les six projets que j’ai pu référencer :

NomArchéo Lexlegi.pyLegi DisplayLegit.jllegifrance-goCodes Droit.org
AuteurSeb35ChangacoSedLexeraviart (Etalab)SteeveHabett
Origine des donnéesLEGILEGILEGILEGILégifrance puis LEGILégifrance puis LEGI
ProductionDépôts GitTest des donnéesPlugin WordPressDépôts GitDépôt GitPDF et ePub
LangagePythonPythonPHPJuliaGoPerl
SGBDSQLite (Peewee)SQLiteMySQL---
LicenceWTFPLCC0GPLMITGPLPropriétaire

Le projet le plus ancien est les Codes pour Droit.org, qui a précédé l’ouverture de la base LEGI. Ce projet avait donc commencé en récupérant directement les données du site web Légifrance.

Le seul projet a avoir bénéficié d’une importante couverture médiatique -d’un gros buzz-, avec articles sur Le Monde et Le Figaro, tweets de Maître Éolas et de la secrétaire d’État chargée du numérique Axelle Lemaire, et en conséquence plus de 2 500 étoiles sur GitHub, est le Code civil que Steeve fournit sous la forme d’un dépôt Git.

Paradoxalement c’est un projet techniquement très limité :

  • seulement deux codes fournis (d’abord le Code civil, puis le Code pénal)
  • récupération des données du site web Légifrance alors que la base LEGI était disponible depuis presque un an
  • logiciel de génération des codes jamais distribué, donc propriétaire

Cependant, il a eu le grand mérite de faire connaître au grand public ce qui est sûrement l’innovation la plus importante que l’informatique peut apporter à l’étude des textes juridiques : une bonne visualisation des changements entre les versions grâce aux diff générés par un logiciel de gestion de versions comme Git.

Diff Article 34 du Code civil

Archéo Lex, un projet complet qui fournit tous les codes de la base LEGI sous la forme de dépôts Git ainsi que le logiciel utilisé pour les générer, était pourtant apparu plusieurs mois avant le Code civil de Steeve…

Enfin, la mission Etalab s’est emparée de la démarche et a fourni tous les codes et toutes les lois non codifiées sous la forme de dépôts Git ainsi que Legit.jl, le logiciel utilisé pour les générer. C’est très bien, mais je trouve que le choix du langage de programmation Julia est contestable, non pas d’un point de vue technique, mais d’un point de vue communautaire. En choisissant un langage aussi confidentiel, on se prive de toute chance de voir des contributeurs extérieurs s’y intéresser…

Concernant la qualité des données de la base LEGI, Seb35 remercie la DILA pour la très bonne qualité des métadonnées tandis que Changaco indique avoir été un peu découragé par la structure médiocre des données.

Personnellement, je pense que le manque de dynamique autour de la base LEGI, qui est pourtant l’une des plus intéressantes de l’Open Data en France, s’explique par la complexité de l’organisation des données qui la rend difficilement exploitable. Ainsi, la dernière version de la base est composée de 1 624 783 fichiers XML, répartis dans une arborescence absconse de 1 537 949 sous-répertoires. Je suis convaincu qu’il reste encore plein de choses à faire pour rendre ces riches données plus accessibles et plus exploitables.

Mise à jour du 16 novembre 2016 : Tous les codes sont présents dans la branche everything du Code civil de Steeve, et ils ont été générés à partir de la base LEGI avec le logiciel libre legifrance-go.

12 November, 2016 05:46AM by fgallaire

October 29, 2016

hackergotchi for J. Fernando Lagrange

J. Fernando Lagrange

Certificats Let’s Encrypt ! avec certbot

Qu’est-ce que c’est donc ? (bis)

Le mois dernier, j’avais partagé comment je faisais pour renouveler des certificats Let’s Encrypt ! Je me suis alors rendu compte qu’il y a des outils dédiés dans le projet Debian, et qu’ils ont étés rétroportés pour Jessie: le paquet Debian certbot. Voici comment j’utilise ce paquet.

Pour rappel:
« Let’s Encrypt (abrégé LE) est une autorité de certification lancée le 3 décembre 2015 (Bêta Version Publique). Cette autorité fournit des certificats gratuits X.509 pour le protocole cryptographique TLS au moyen d’un processus automatisé destiné à se passer du processus complexe actuel impliquant la création manuelle, la validation, la signature, l’installation et le renouvellement des certificats pour la sécurisation des sites internet. »
Contenu soumis à la licence CC-BY-SA 3.0. Source : Article Let’s Encrypt de Wikipédia en français (auteurs ).

Voici donc comment j’utilise ce paquet Debian certbot pour:

  • Créer de nouveaux certificats (pour nginx)
  • Mettre à jour ces certificats

Préambule: installation

Pour installer le paquet certbot, il faut d’abord ajouter la source des paquets rétroportés. C’est indiqué dans les instructions (en anglais) et sur la page wiki (en français). Personnellement, voici comment j’ai fait:

J’ai créé un fichier /etc/apt/sources.list.d/backports.list contenant la ligne suivante:

deb http://ftp.debian.org/debian jessie-backports main

Puis lancé les commandes suivantes:

root@server ~# apt update
[…]
root@server ~# apt install certbot
[…]

Créer de nouveaux certificats (pour nginx)

J’utilise nginx comme serveur web. J’ai mis en place le certificat Let’s Encrypt ! en 3 étapes:

  1. Créer le certificat
  2. Configurer nginx pour utiliser le nouveau certificat
  3. Relancer nginx

Créer le certificat

Voici comment j’ai créé les certificats pour le site web www.fosforito.fr:

root@server ~# systemctl stop nginx.service
root@server ~# certbot certonly -d www.fosforito.fr
[…]

Puis, j’ai suivi les instructions (en anglais) pour utiliser l’authentification avec un serveur web autonome (standalone). Cela autorise certbot à lancer son propre serveur web, le temps de créer le certificat. nginx ne doit donc pas fonctionner le temps de créer le certificat (quelques secondes dans mon cas), c’est le but de la première commande. Pour le relancer, j’ai utilisé la commande suivante:

root@server ~# systemctl start nginx.service

Configuration de nginx

Pour utiliser la configuration ci-dessous, j’ai d’abord créé une clé Diffie-Hellman comme indiqué par SSL Labs:

root@server ~# openssl dhparam -out /etc/nginx/dhparams.pem 2048
[…]

Voici le fichier /etc/nginx/sites-available/www.fosforito.fr.conf que j’utilise avec la commande root@server ~# ln -s /etc/nginx/sites-available/www.fosforito.fr.conf /etc/nginx/sites-enabled/www.fosforito.fr.conf:

server {
    listen 443;
    server_name www.fosforito.fr;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/www.fosforito.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.fosforito.fr/privkey.pem;

    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

    ssl_prefer_server_ciphers on;

    ssl_dhparam /etc/nginx/dhparams.pem;

    root /srv/www.fosforito.fr/;
    index index.html;

    access_log      /var/log/nginx/www.ssl.access.log;
    error_log       /var/log/nginx/www.ssl.error.log;


}

Une fois tout cela mis en place, je teste avec SSL Labs et je vois que ce site obtient un A, ce qui me va bien. 🙂

Mise à jour du certificat

Le paquet certbot met en place une tâche planifiée pour mettre à jour automatiquement le(s) certificat(s) Let’s Encrypt ! présent(s) sur le serveur. Malheureusement, pour l’instant, cela ne fonctionne que pour le serveur web apache (paquet apache2 dans Debian).
Pour nginx, j’ai simplement modifié la tâche planifiée, dans le fichier /etc/cron.d/certbot, pour arrêter le serveur web avant le renouvellement de certificat et le relancer après. Voici le fichier au complet (notez les options pre-hook et post-hook):

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot && perl -e 'sleep int(rand(3600))' && certbot -q renew --pre-hook "service nginx stop" --post-hook "service ngnix start"

Récapitulatifs

Mise en place du certificat pour nginx

  1. Arrêter nginx
  2. Créer le certificat Let’s Encrypt !
  3. Créer le groupe Diffie-Hellman
  4. Mettre en place la configuration du site web
  5. Relancer nginx

Renouvellement du(des) certificat(s)

Ajouter les options pre-hook et post-hook à la tâche plannifiée.

29 October, 2016 06:36PM by Low Memory

October 17, 2016

hackergotchi for Raphaël Hertzog

Raphaël Hertzog

Mes activités libres en septembre 2016

Mon rapport mensuel couvre une grande partie de mes contributions au logiciel libre. Je l’écris pour mes donateurs (merci à eux !) mais aussi pour la communauté Debian au sens large parce que cela peut donner des idées aux nouveaux venus et que c’est également un des moyens les plus effectifs de trouver des volontaires pour travailler sur les projets qui me tiennent à cœur.

Debian LTS

Avec l’augmentation du nombre de contributeurs rémunérés, les corrections faciles à réaliser (comme les CVE disposant de patchs) sont généralement effectuées assez rapidement. Tous les paquets sur lesquels j’ai travaillé étaient touchés par des bogues ouverts depuis longtemps, du fait de la difficulté à les traiter.

J’ai préparé la DLA-613-1 corrigeant 3 CVE affectant roundcube. La correction nécessitait le rétroportage du code gérant le CRSF, qui n’était pas disponible dans la version de Wheezy. J’ai passé presque 8 heures à travailler sur roundcube.

J’ai ensuite commencé à travailler sur tiff3. J’ai passé en revue de nombreuses CVE : CVE-2016-3658, CVE-2015-7313, CVE-2015-7554, CVE-2015-8668, CVE-2016-5318, CVE-2016-3625, et CVE-2016-5319. J’ai mis à jour leurs statuts pour le paquet tiff3 de Wheezy, puis j’ai demandé des fichiers de rejeu aux personnes ayant remonté les CVE, alors que ces fichiers n’étaient pas encore publiquement disponibles. Enfin, j’ai fait en sorte que tout soit enregistré dans le suiveur de bogues amont. Les 4 heures 25 minutes passées à travailler sur ce paquet ne furent pas suffisantes pour se pencher sur les patchs, je l’ai donc remis dans la pile des paquets à traiter.

Transition vers GNOME 3.22

J’ai poussé une nouvelle version de gnome-shell-timer qui devait fonctionner avec la version 3.21 de GNOME qui avait été poussée vers sid.

Malheureusement, cette nouvelle version (ainsi que celle de GTK+) a provoqué de nombreuses régressions qui ont affecté les utilisateurs de Debian Testing (et donc ceux de Kali), particulièrement en ce qui concerne le gnome-control-center. J’ai poussé une nouvelle version corrigeant certains soucis, et j’en ai remonté un bon nombre vers l’amont également (n°771515, n°771517, et n°771696).

Kali

J’ai travaillé (cf. le n°836211) à la création d’un patch dpkg pour contourner la limitation de overlayfs (Nous l’utilisons dans Kali, car la persistence d’un système live se base justement sur overlayfs), et j’ai contacté le mainteneur amont d’overlayfs en espérant que le problème soit plutôt proprement patché côté overlayfs.

J’ai poussé radcli en version 1.2.6-2.1 afin de corriger un bogue critique pour la publication (n°825121), car le paquet avait été retiré de Testing alors qu’openvas en dépend toujours dans Kali.

En tant que membre de l’équipe pkg-security, j’ai parrainé/poussé acccheck et arp-scan pour Marcos Fouces, ainsi que la version 3.09b de p0f.

Travaux Debian divers

Distro Tracker J’ai testé, corrigé et fusionné le patch de Paul Wise intégrant les hints multiarch dans tracker.debian.org (cf. le n°833623).

Cahiers de l’Admin Debian J’ai activé la traduction vietnamienne sur debian-handbook.info et actualisé toutes les traductions d’après les mises à jour effectuées sur Weblate.

Units systemd pour apache2 J’ai préparé et soumis des units systemd pour apache2 (cf. le n°798430). Avec l’approbation de Stefan Fritsch, j’ai poussé mon code vers le dépôt Git, et intégré le résultat dans la version 2.4.23-5.

Empaquetage d’Hindsight J’ai commencé par empaqueter lua-sandbox (cf. le n°838969) – qui est une dépendance d’Hindsight – puis Hindsight lui-même (cf. le n°838968). Ce faisant, j’ai ouvert plusieurs tickets auprès de l’amont.

PIE par défaut J’ai poussé une nouvelle version de cpputest compilée avec les drapeaux -fPIC, de sorte que le exécutables liés à sa bibliothèque statique puisse être compilés avec les drapeaux -fPIE (cf. le n°837363, remonté à l’amont ici).

Rapports de bogues créés Un mauvais lien vers la page d’accueil dans haskell-dice-entropy-conduit. Des options incohérentes : --onlyscripts et --noscripts dans debhelper. L’entrée concernant pidgin dans security-support-limited est obsolète dans debian-security-support. Une nouvelle version amont (2.0.2) dans puppet-lint.

Merci

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in September 2016 contribuée par Weierstrass01.

Aucun commentaire pour le moment | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

17 October, 2016 10:02AM by Raphaël Hertzog

October 08, 2016

hackergotchi for Charles Plessy

Charles Plessy

Je viens de finir de lire la trilogie des chroniques du Radch.

J'ai beaucoup aimé. Il y a déjà de nombreux commentaires sur Internet (merci à Russ pour m'avoir fait découvrir ces romans), donc je ne m'attarderai pas dans les détails. Et il est difficile de résumer sans dévoiler l'intrigue... En bref :

Le premier tome, La justice de l'ancillaire nous fait visiter plusieurs mondes et cultures et nous donne un aperçu de ce que ça fait d'être un demi-dieu. La culture dominante ne fait aucune différence entre les deux sexes, et la grammaire de son langage n'a pas de genre. Ça donne une touche particulière à l'histoire, car par exemple quand il parle une langue étrangère, le héros a des difficultés pour s'adresser correctement à ses interlocuteurs sans les froisser. Malheureusement, la langue anglaise elle-même utilise peu les genres, donc l'effet littéraire s'en trouve un peu amoindri. Peut-être que sur ce point la traduction française, que je n'ai pas lue, pourrait être plus intéressante ?

le deuxième tome L'épée de l'ancillaire nous raconte comment on peut se dire des choses dans une société de surveillance sans intimité, en variant subtilement la manière de servir le thé. On en boit des litres dans ce tome, dont le principal intérêt est le jeu des relations entre les personnages, et leurs dialogues.

Le troisième tome La miséricorde de l'ancillaire pose la question de ce qui nous rend humains. Parmi les personnages les plus intéressants, il y a un ambassadeur extra-terrestre, qui est une sorte d'humain de synthèse. Au premier abords, il semble complètement étranger, mais à bien y réfléchir, il n'est pas très différent d'un nouveau-né qui comme par miracle saurait parler: au début, le monde n'a aucun sens, et petit à petit, par l'expérience, il déduit son fonctionnement. C'est comme ça que ce personnage finit par comprendre que ce que l'on appelle « la guerre », c'est un phénomène compliqué dont l'une des conséquences est une pénurie de sauce au poisson.

J'étais un peu surpris qu'aucun des livres ne nous emmène au coeur de l'empire du Radch, mais je vois à l'instant sur Wikipédia qu'un autre roman est en préparation... On pourrait spéculer que le Radch central ressemble à un Occident futur dystopique, dans lequel tout le monde est suivi en totalité et en permanence mais se croit heureux, et dont la paix intérieure est garantie par des opérations armées à l'extérieur, exécutées principalement par des robots-tueurs pilotés par des intelligences artificielles. Un futur peut-être pas si lointain ?

Il va sans dire que dans l'empire du Radch, il ne semble pas avoir le moindre logiciel libre. Ça me rappelle que je n'ai pas trop contribué à Debian pendant que je lisais...

08 October, 2016 03:29PM

October 02, 2016

Florent Gallaire

Arduino, la réunification

Banzi et Musto au Maker Faire de New York

Massimo Banzi (à gauche sur la photo) et Federico Musto (à droite) viennent d’annoncer sur l’estrade du Maker Faire de New York la « réunification » du projet Arduino. Arduino LLC et Arduino srl ont de plus publié conjointement un communiqué sur leur site web respectif Arduino.cc et Arduino.org.

Il y a un an et demi, en mars 2015, la scission du projet Arduino avait été rendue publique. Une bataille juridique s’était engagée concernant la propriété et l’exploitation de la marque Arduino dans le monde, amenant à la création de la marque Genuino. La disponibilité des produits Arduino était devenue très problématique et la vision du futur plus qu’incertaine.

La situation était très préjudiciable au plus important des projets de hardware libre et je suis vraiment très heureux de relayer l’annonce d’une transaction entre les parties plutôt que de faire un cas pratique de droit des marques sur le sujet !

02 October, 2016 04:12AM by fgallaire

September 19, 2016

hackergotchi for Raphaël Hertzog

Raphaël Hertzog

Mes activités libres en août 2016

Mon rapport mensuel couvre une grande partie de mes contributions au logiciel libre. Je l’écris pour mes donateurs (merci à eux !) mais aussi pour la communauté Debian au sens large parce que cela peut donner des idées aux nouveaux venus et que c’est également un des moyens les plus effectifs de trouver des volontaires pour travailler sur les projets qui me tiennent à cœur.

Ayant pris deux semaines de vacances en août, l’activité de ce mois fut moins importante qu’à l’accoutumée.

Travaux relatifs à Kali

La nouvelle équipe pkg-security fonctionne à plein régime, et j’ai passé en revue/parrainé de nombreux paquets ce mois-ci : polenum, accheck, braa, t50, ncrack, websploit.

J’ai créé le rapport de bogue n°834515 concernant sbuild, car sbuild-createchroot n’était plus utilisable dans kali-rolling du fait du tiret dans son nom. Le comportement antérieur a été restauré, et cette fonctionnalité proposée explicitement au travers d’une option.

J’ai attiré l’attention des ftpmasters sur le bogue n°832163, au sujet de la présence de paquets non désirés dans la section standard (ils ont été découverts dans l’ISO live de Kali, alors que nous ne les voulions pas).

J’ai envoyé (en tant que non-mainteneur) deux versions de fontconfig, de sorte à ce que nous puissions enfin pousser dans Debian une correction à peu près propre pour les diverses légendes affichées comme des carrés, après une mise à jour des polices (cf. le n°828037 et le n°835142).

J’ai testé (par deux fois) un patch live-build d’Adrian Gibanel Lopez implémentant le boot EFI avec grub, que j’ai intégré dans le dépôt Git officiel (cf. le n°731709).

J’ai ouvert un rapport de bogue (n°835983) concernant python-pypdf2, qui présente une dépendance invalide interdisant son installation parallèlement à python-pypdf.

J’ai déclaré orphelin le paquet splint, son mainteneur étant aux abonnés absents – missing in action (MIA). Déclaration immédiatement suivie d’un upload corrigeant un bogue critique pour la publication, bogue pour lequel il avait été exclu de testing (ce paquet est une dépendance de compilation d’un paquet Kali).

django-jsonfield

J’ai écrit un patch rendant python-django-jsonfield compatible avec Django 1.10 (cf. le n°828668). Patch que j’ai poussé par la suite dans le dépôt amont.

Distro Tracker

J’ai réalisé quelques modifications afin de rendre la base de code compatible avec Django 1.10 (et ajouté Django 1.10 à la matrice de test tox). J’ai également ajouté un lien « Tableau de bord du mainteneur Debian » à côté des noms des personnes, à la demande de Lucas Nussbaum (cf. le n°830548).

J’ai réalisé une analyse préliminaire du patch de Paul Wise visant à ajouter des indications multiarch (cf. le n°833623), et j’ai amélioré le support par le mailbot des en-têtes MIME faisant référence à des jeux de caractères inconnus (comme par exemple « cp-850 », Python ne reconnaissant que « cp850 »).

Enfin, j’ai aidé Peter Palfrader à mettre en place une adresse .onion pour tracker.debian.org, cf. onion.debian.org pour la liste complète des services accessibles à travers Tor.

Travaux divers

J’ai mis à jour ma formule salt pour letsencrypt.sh, afin qu’elle soit fonctionnelle avec la toute dernière version de letsencrypt.sh (0.2.0).

J’ai fusionné les traductions mises à jour pour le Cahier de l’Administrateur Debian sur weblate.org, et poussé une nouvelle version vers Debian.

Merci

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in August 2016 contribuée par Weierstrass01.

Aucun commentaire pour le moment | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

19 September, 2016 07:07PM by Raphaël Hertzog

August 26, 2016

Mes activités libres en juillet 2016

Mon rapport mensuel couvre une grande partie de mes contributions au logiciel libre. Je l’écris pour mes donateurs (merci à eux !) mais aussi pour la communauté Debian au sens large parce que cela peut donner des idées aux nouveaux venus et que c’est également un des moyens les plus effectifs de trouver des volontaires pour travailler sur les projets qui me tiennent à cœur.

DebConf 16

A l’occasion de la DebConf 16, j’ai été présent en Afrique du Sud du 2 au 9 juillet, et j’ai animé trois présentations/tables rondes. Vous pouvez trouver les diapositives et vidéos de ces événements dans les liens de leurs pages respectives :

J’étais un peu nerveux en ce qui concerne la troisième table ronde (au sujet de l’utilisation des fonds de Debian pour financer les projets Debian) mais, après en avoir discuté avec de nombreuses personnes pendant cette semaine, il semble que les mentalités au sein du projet aient évolué ces dix dernières années. Bien que cela reste un sujet sensible (et ce à raison compte tenu des impacts potentiels), la volonté d’en discuter et d’expérimenter est présente. Vous pouvez jeter un coup d’œil aux gobby notes prises lors de la discussion.

J’ai passé la plupart du temps à discuter, et n’ai pas beaucoup contribué d’un point de vue technique, mis à part avoir essayé de – et échoué à – corriger les problèmes d’accessibilité rencontrés sur tracker.debian.org (toute aide experte sur le sujet est la bienvenue, cf. le ticket n°830213).

Empaquetage Debian

J’ai poussé la nouvelle version de zim afin de corriger le problème de reproductibilité (et j’ai transmis le patch à l’amont).

J’ai poussé Django en version 1.8.14 vers le dépôt jessie-backports, et j’ai du corriger l’échec d’un test (pull request).

J’ai également poussé la nouvelle version amont 1.0.1 de python-django-jsonfield, qui intègre les patchs que j’ai préparés en juin.

J’ai géré la transition de la (petite) bibliothèque ftplib : en préparant la nouvelle version dans experimental, en m’assurant que les dépendances de compilation inverses compilaient toujours, et en coordonnant la phase de transition avec l’équipe en charge de la publication. Tout cela a été déclenché par ce bogue de compilation reproductible que j’ai rencontré et qui m’a fait jeter un coup d’œil au paquet… la dernière fois l’amont avait disparu (et même son URL), mais il semble que l’activité ait repris et qu’une nouvelle version ait été poussée.

J’ai fait la demande n°832053 d’une nouvelle commande deblog dans devscripts. Cela devrait rendre plus facile l’affichage des logs des compilations courante et précédentes.

Travaux relatifs à Kali

J’ai travaillé à de nombreux problèmes affectant les utilisateurs de Kali (ainsi que ceux de Debian Testing) :

  • J’ai corrigé un bogue dans open-vm-tools, afin de retrouver le paquet dans Testing;
  • J’ai créé le rapport de bogues n°830795 concernant nautilus et n°831737 concernant pbnj, afin de remonter ces problèmes à Debian;
  • J’ai créé un patch pour fontconfig, de sorte à ce que les fichiers .dpkg-tmp soient ignorés. J’ai également transmis ce patch à l’amont et créé un rapport de bogues relatif à gnome-settings-daemon qui, en lançant fc-cache aux mauvais moments, est à la source du problème;
  • J’ai lancé une discussion pour voir comment corriger le problème du pavé tactile synaptics dans GNOME 3.20. Finalement nous nous sommes retrouvés avec une nouvelle version de xserver-xorg-input-all, qui ne dépend que de xserver-xorg-input-libinput, et non pas de xserver-xorg-input-synaptics (qui n’est plus supporté par GNOME). Auparavant l’auteur amont avait refusé de réintroduire le support synaptics;
  • J’ai créé le rapport de bogues n°831730 relatif à desktop-base, car le plasma-desktop de KDE n’utilise plus l’arrière-plan de Debian par défaut. J’ai du rechercher l’aide de l’amont pour trouver une possible solution (déployée dans Kali uniquement pour l’instant);
  • J’ai créé le rapport de bogues n°832503 pour remonter le fait que la manière dont dpkg traite les dépendances de foo:any lorsque foo n’est pas marquée « Multi-Arch: allowed » est contre-productive… J’ai découvert cela en essayant d’utiliser une dépendance firefox-esr:any. Et j’ai créé le rapport de bogues n°832501 pour obtenir le marqueur « Multi-Arch: allowed » désiré sur firefox-esr.

Merci

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in July 2016 contribuée par Weierstrass01.

Aucun commentaire pour le moment | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

26 August, 2016 08:54AM by Raphaël Hertzog

August 20, 2016

Florent Gallaire

Les micro-frameworks Python : Flask, Bottle, Itty, Newf, djng et importd

Suite au succès phénoménal de Flask, qui a plus d’étoiles sur GitHub que Django, et à celui remarquable de Bottle, j’ai poursuivi ma réflexion personnelle sur les microframeworks. C’est un sujet auquel je m’étais fortement intéressé en 2009, il y a 7 ans donc, lors de la soudaine prolifération de microframeworks Python.

Sinatra, l’inspiration vint encore du Ruby

Tout comme Ruby on Rails a été dès 2004 le grand précurseur des frameworks web MVC de nouvelle génération, Sinatra a été dès 2007 le précurseur des microframeworks web. Sinatra a rendu l’écriture d’application web radicalement plus aisée grâce à sa syntaxe claire et concise :

require 'sinatra'

get '/' do
'Hello world!'
end

WSGI, la condition technique

Le standard Python WSGI (Web Server Gateway Interface) décrit dans la PEP 333 de 2003, mise à jour en 2010 par la PEP 3333, a proposé une interface simple permettant de découpler les frameworks web des serveurs web.

Et l’ajout du module wsgiref dans la bibliothèque standard de Python 2.5 en 2006 a permis a tout framework d’être utilisable sans aucune dépendance grâce au petit serveur WSGI qu’il fournit :

from wsgiref.simple_server import make_server

Qu’est-ce qu’un micro-framework ?

En admettant que l’on sache ce qu’est un framework, on doit s’interroger sur le sens de micro. Le Larousse précise :

Préfixe, du grec mikros, petit, indiquant que quelque chose est très petit.

Un micro-framework est donc un très petit framework. L’intérêt de cette démarche est réel pour le développeur car il est plus facile d’apprendre à utiliser un petit framework, qui de plus consomme moins de ressources et impose souvent moins de contraintes.

Il est communément admis que ces microframeworks sont surtout intéressants pour construire de petites applications, la quantité de fonctionnalités des frameworks full-stack justifiant de plus en plus leur usage avec l’augmentation de la taille et des besoins de l’application.

Le moins de lignes de code possible

Un microframework est donc un framework ayant une petite base de code, c’est-à-dire un petit nombre de lignes de code. Encore faut-il qu’il en ait suffisamment pour qu’un développeur ait un intérêt à l’utiliser.

Le minimum nécessaire n’est pas forcément facile à évaluer, mais on peut penser qu’un framework comme Newf, avec ses 114 lignes de code, était très nettement en dessous. Itty, quant à lui, est très proche de Bottle en termes de design et de fonctionnalités, mais d’une manière globalement plus – et donc finalement trop – minimaliste.

Dans les deux cas, cela s’est révélé insuffisant pour susciter un réel intérêt chez les développeurs d’applications web et donc pour créer une dynamique et fédérer une communauté autour de ces projets.

Tout le framework dans un seul fichier

La théorie de l’ingénierie logicielle a combattu cette pratique au nom d’une meilleure structuration, permettant une bonne séparation des fonctionnalités et donc un débogage et une réutilisation plus facile du code. Pourtant, mettre tout le code dans un seul fichier présente certains avantages, en particulier quand il s’agit de le distribuer. C’est une pratique qui a connu une nouvelle légitimation avec le succès des bibliothèques JavaScript côté client, facilement chargées dans le navigateur web d’une simple ligne :

<script src="https://cdn.net/lib.js"></script>

Bottle est distributed as a single file module alors que Flask est plus classiquement composé de plusieurs fichiers. Flask, le plus populaire des microframeworks Python en est-il donc vraiment un ?

Essayons d’y voir plus clair à l’aide de wc récursifs appliqués sur les répertoire contenant le code source des frameworks, et desquels j’ai retiré le code des tests :

Micro-frameworksFrameworks
NomNewfdjngimportdIttyBottleFlaskTornadoPyramidDjango
wc -l1503287919584 1796 46922 32722 641122 675
sloccount1142305336322 7212 72511 53511 31277 514
Fichiers Python1142112181193853
Étoiles GitHub501234543743 87822 00711 9032 05920 717
PyPI (millions)0,10,0521411223

J’ai ajouté au tableau Django, Pyramid et Tornado, les trois frameworks web Python les plus populaires, et il apparaît clairement qu’en comparaison Flask est bien un microframework, puisque s’il est 1,5 fois plus gros que Bottle, il est 3,5 fois moins gros que Tornado et Pyramid et 19 fois moins gros que Django.

Toute l’application dans un seul fichier

Lorsque l’on utilise les outils d’aide des frameworks classiques pour débuter un projet, on se retrouve devant une arborescence complexe. Par exemple avec Django, si vous évitez les bizarreries et faites les choses normalement :

$ django-admin startproject django_project
$ cd django_project
$ django-admin startapp django_app


django_project
├── django_project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── django_app
│ ├── admin.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py

De même avec Pyramid :

$ pcreate -s starter pyramid_project

pyramid_project
├── CHANGES.txt
├── development.ini
├── MANIFEST.in
├── production.ini
├── pyramid_project
│ ├── __init__.py
│ ├── static
│ │ ├── pyramid-16x16.png
│ │ ├── pyramid.png
│ │ ├── theme.css
│ │ └── theme.min.css
│ ├── templates
│ │ └── mytemplate.pt
│ ├── tests.py
│ └── views.py
├── README.txt
└── setup.py

Ceci est une bonne base pour un gros projet, qui sera bien structuré dès le départ, avec un bon découplage du code, et même les fichiers nécessaires à son packaging ; mais pour beaucoup de projets assez simples, c’est surtout lourd et redondant.

Tous les microframeworks ont donc comme point commun qu’ils sont conçus pour qu’une application toute entière contenue dans un seul fichier soit parfaitement fonctionnelle, et un certain nombre de frameworks qui ne prétendent pas être des microframeworks, comme Tornado, partagent la même approche.

Pas de dépendances… ou beaucoup de dépendances ?

Deux visions opposées peuvent en effet légitimement se défendre lors de la construction d’un microframework :

– pour avoir un framework léger il ne faut aucune dépendances, et se reposer exclusivement sur la bibliothèque standard de Python (Python Standard Library)
– pour avoir un framework léger il faut au contraire se reposer un maximum sur des bibliothèques existantes, fiables et populaires si possible, et se contenter d’offrir une fine couche logicielle permettant de les interfacer correctement

Newf et Itty font bien sûr partie de la première catégorie.

Bottle qui has no dependencies other than the Python Standard Library, et fournit son propre langage de template, fait donc aussi partie de la première catégorie. Mais on peut en plus lui interfacer facilement Mako, Jinja2 et Cheetah, des langages de template Python populaires, ce qui le fait alors déborder sur la deuxième catégorie.

Flask quant à lui est de la seconde catégorie, d’autant que son auteur est Armin Ronacher (mitsuhiko) qui est aussi l’auteur de ses dépendances Werkzeug et Jinja2. Mais si avoir comme dépendances une bibliothèque WSGI et un langage de template est on ne peut plus légitime pour un microframework, l’ajout de la bibliothèque d’interface de ligne de commande Click semble beaucoup plus contestable et relever plutôt du syndrome NIH (Not invented here).

Enfin, à l’initiative de djng, la seconde vision a amené à de multiples essais de microframeworks basés sur… Django, le maxi-framework du monde Python ! Et si seul importd a rencontré un certain succès parmi ces projets, je pense que cet oxymore logiciel est un concept vraiment intéressant et que son potentiel n’a probablement pas encore été totalement exploité.

Mise à jour du 10 septembre 2016 : Suite au commentaire de Stéfane Fermigier, ajout dans le tableau du comptage des lignes de code avec SLOCcount. Ajout de djng.
Mise à jour du 10 octobre 2016 : Ajout dans le tableau du nombre de téléchargements sur PyPI.

20 August, 2016 11:31PM by fgallaire

August 17, 2016

hackergotchi for Tanguy Ortolo

Tanguy Ortolo

Aux concepteurs de voies cyclables

À voir le tracé de certaines voies cyclables, ceux qui les conçoivent ne sont pas toujours conscients qu'un cycliste se déplace avec une vitesse de l'ordre de 20 km/h. Ce genre d'aménagement, qui serait impensable pour une route normale :

Route avec une chicane à angle droit !

Au top, braquez et serrez le frein à main. Attention… TOP ! ;-)

… ce genre d'aménagement donc, est tout aussi invraisemblable pour une voie cyclable :

Piste cyclable avec une chicane à angle droit !

Au top, tournez votre guidon à 90°. Attention… TOP ! ;-)

Un cycliste ne peut pas tourner sur place à angle droit. Au mieux, on peut essayer de s'en approcher, mais ces virages à rayon de courbure nul sont pénibles et toujours dangereux, parce que cela implique :

  • de freiner brutalement — et paf, le cycliste qui arrive derrière et qui n'a pas remarqué cette anomalie du tracé ;
  • de tourner avec un angle déraisonnable — et zip, le cycliste sur route mouillée ou jonchée de gravier ou de feuilles mortes.

Mesdames, Messieurs les responsables des aménagements de voirie, pour éviter ce genre d'erreur de conception, ce n'est pas compliqué : lorsque vous tracez une voie cyclable, essayez d'imaginer qu'il s'agit d'une route normale, en plus petit. Vous n'iriez tout de même pas mettre une chicane à angle droit sur une route normale ? Eh bien, sur une piste cyclable, c'est pareil, si vous devez mettre une chicane, prévoyez un rayon de courbure raisonnable. Sans cela, dans le meilleur cas, les cyclistes ne respecteront pas votre aménagement inapproprié, et dans le pire des cas vous ramasserez des cyclistes et des piétons accidentés, direction l'hôpital le plus proche.

17 August, 2016 10:16AM by Tanguy

hackergotchi for Charles Plessy

Charles Plessy

Qui a fini DEP 5 ?

Beaucoup de monde a travaillé à finir DEP 5. Je trouve que le blog de Lars ne montre pas assez l'aspect collectif du processus.

Si l'on regarde dans le texte de la spécification, on y trouve:

The following alphabetical list is incomplete; please suggest missing people:
Russ Allbery, Ben Finney, Sam Hocevar, Steve Langasek, Charles Plessy, Noah
Slater, Jonas Smedegaard, Lars Wirzenius.

Le journal des changements de la charte Debian mentionne:

  * Include the new (optional) copyright format that was drafted as DEP-5.
    This is not yet a final version; that's expected to come in the
    3.9.3.0 release.  Thanks to all the DEP-5 contributors and to Lars
    Wirzenius and Charles Plessy for the integration into the Policy
    package.  (Closes: #609160)

 -- Russ Allbery <rra@debian.org>  Wed, 06 Apr 2011 22:48:55 -0700

et

debian-policy (3.9.3.0) unstable; urgency=low

  [ Russ Allbery ]
  * Update the copyright format document to the version of DEP-5 from the
    DEP web site and apply additional changes from subsequent discussion
    in debian-devel and debian-project.  Revise for clarity, to add more
    examples, and to update the GFDL license versions.  Thanks, Steve
    Langasek, Charles Plessy, Justin B Rye, and Jonathan Nieder.
    (Closes: #658209, #648387)

Pour ma part, je suis très reconnaissant à Bill Alombert d'avoir enregistré le document dans le dépôt Git, ce qui a mis fin aux débats.

17 August, 2016 04:08AM

August 10, 2016

hackergotchi for J. Fernando Lagrange

J. Fernando Lagrange

Renouvellement de certificats LetsEncrypt avec systemd

Qu’est-ce que c’est donc ?

« Let’s Encrypt (abrégé LE) est une autorité de certification lancée le 3 décembre 2015 (Bêta Version Publique). Cette autorité fournit des certificats gratuits X.509 pour le protocole cryptographique TLS au moyen d’un processus automatisé destiné à se passer du processus complexe actuel impliquant la création manuelle, la validation, la signature, l’installation et le renouvellement des certificats pour la sécurisation des sites internet1. » (Contenu soumis à la licence CC-BY-SA 3.0. Source : Article Let’s Encrypt de Wikipédia en français (auteurs) )

Bref, c’est bien pratique pour faire du HTTPS (entre autres) et on peut automatiser le renouvellement des certificats. Il y a plusieurs années, j’aurais fait un cron, mais comme j’ai appris que systemd pouvait gérer des tâches répétitives, je me suis dit que c’était l’occasion de m’y mettre ! 😉

Comment on fait ?

Voici les étapes suivies, détaillées ci-dessous puis quelques documents qui m’ont permis de le faire, sans compter le conseil d’un ami: « T’as qu’à faire un timer ! » :

  • Copier certbot sur le serveur, logiciel (libre, non-copyleft) de gestion des certificats de Let’s Encrypt
  • Créer un script pour renouveler les certificats avec certbot
  • Créer un service systemd pour lancer le script
  • Créer une minuterie (timer) systemd pour lancer le service à intervalles réguliers

Enfin, activer et lancer la minuterie puis vérifier que ça fonctionne.

1. Copier certbot sur le serveur

Je le copie dans le dossier /opt du serveur:

root@serveur:~# cd /opt/ && git clone https://github.com/certbot/certbot
[…]

2. Créer le script pour utiliser certbot

Le script se nomme certbot-renew, il est créé dans /opt/certbot/, au même endroit que certbot. Créez aussi le dossier pour les journaux avec la commande mkdir /var/log/letsencrypt/.

Si vous utilisez le serveur web apache, changez le service que systemd doit arrêter et redémarrer, en gras dans le code ci-dessous:

root@serveur:~# cat > /opt/certbot/certbot-renew << EOF
#!/bin/sh
# Inspired by <https://letsencrypt.org/getting-started/>
systemctl stop nginx.service
/opt/certbot/certbot-auto renew -nvv --standalone > /var/log/letsencrypt/renew.log 2>&1
LE_STATUS=$?
systemctl start nginx.service
if [ "$LE_STATUS" != 0 ]; then
echo Automated renewal failed:
tail -n 200 /var/log/letsencrypt/renew.log
exit 1
fi
EOF

3. Créer le service systemd

C’est ce service qui va lancer le script /opt/certbot/certbot-renew créé à l’étape précédente:

root@serveur:~# cat > /etc/systemd/system/certbot-renew.service << EOF
# Voir <https://mjanja.ch/2015/06/replacing-cron-jobs-with-systemd-timers/>
[Unit]
Description=Renouvellement des certificats letsencrypt

[Service]
Type=simple
nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
ExecStart=/opt/certbot/certbot-renew
EOF

4. Créer la minuterie systemd

C’est cette minuterie qui va lancer le service créé à l’étape précédente. Notez que la valeur daily pour OnCalendar lance le service à minuit. Comme le serveur était programmé pour faire d’autres choses à minuit, j’ai utilisé un autre moment. ^^

root@serveur:~# cat > /etc/systemd/system/certbot-renew.timer << EOF
# Voir <https://mjanja.ch/2015/06/replacing-cron-jobs-with-systemd-timers/>
[Unit]
Description=Renouvellement des certificats letsencrypt

[Timer]
#OnCalendar=daily
OnCalendar=*-*-* 04:20:42

[Install]
WantedBy=timers.target
EOF

 

Il ne reste plus qu’à activer cette minuterie pour qu’elle soit lancée à chaque démarrage du serveur:  systemctl enable certbot-renew.timer

Pour éviter un redémarrage, la minuterie peut être lancée manuellement: systemctl start certbot-renew.timer

Pour vérifier que tout fonctionne bien le service peut aussi être lancé manuellement: systemctl start certbot-renew.service. Vérifiez alors les journaux pour voir si tout s’est bien déroulé.

 

Voici donc comment j’ai procédé, il doit exister bien d’autres façons de faire, n’hésitez-pas à m’en faire part et/ou à améliorer ce que je présente ici.

Documentation, ressources:

Manuels de systemd: systemd.exec, systemd.service et systemd.timer.
Manuel de ioprio_set.
Remplacer les cron jobs par des minuteries systemd (en anglais).
Pour débuter avec Let’s Encrypt (en anglais).

Un brin de persévérance, un tonneau de tests et quelques couplets de corrections. 😉

 

10 August, 2016 09:02PM by Low Memory

August 01, 2016

hackergotchi for Charles Plessy

Charles Plessy

Nuage Amazon : remise à niveau.

Cela faisait quelques années que je n'avais pas fait de travail sérieux utilisant le nuage Amazon. Il m'a fallu un petit moment pour retrouver mes marques et m'adapter aux changements. En particulier, les instances à plus petit prix, t2.nano ne sont plus accessible que depuis les nuages virtuels privés (« Virtual Private Cloud », VPC), et j'ai eu un peu de mal à trouver comment en créer un simple. Je pense qu'une des raisons est que les utilisateurs arrivés après le 18 mars 2013 on automatiquement un VPC par défaut et que les autres ont déjà créé leur VPC depuis longtemps. Au final, ce n'était pas compliqué du tout. C'est certainement pour ça que je n'avais pas trouvé de tutoriel à ce sujet.

En résumé il faut d'abords créer un VPC. Pour lancer une instance de temps en temps, la plage IP privée importe peu. Les VPCs par défaut utilisent 172.31.0.0/16; alors faisons de même.

CIDR_BLOCK=172.31.0.0/16
aws ec2 create-vpc --cidr-block $CIDR_BLOCK

La commande renvoie un identifiant de VPC, que je stocke à la main dans la variable VPC par copié-collé. Le même principe sera répété pour chaque commande créant quelque chose. On peut retrouver l'identifiant avec la commande aws ec2 describe-vpcs.

VPC=vpc-XXXXXXXX  # Et ainsi de suite

Après, créer un sous-réseau. Là encore, pas la peine de faire compliqué, on peut lui donner la plage IP entière. Je récupère l'identifiant renvoyé et le stocke dans la variable SUBNET. Pour que les instances reçoivent une IP publique comme dans les VPCs par défaut et l'ancien comportement du nuage sans VPC, il faut activer l'attribut MapPublicIpOnLaunch.

aws ec2 create-subnet --vpc-id $VPC --cidr-block $CIDR_BLOCK
SUBNET=subnet-XXXXXXXX
aws ec2 modify-subnet-attribute --subnet-id $SUBNET --map-public-ip-on-launch 

Ensuite, créer une passerelle (je récupère l'identifiant dans GATEWAY) et l'attacher au VPC.

aws ec2 create-internet-gateway
GATEWAY=igw-XXXXXXXX
aws ec2 attach-internet-gateway --internet-gateway-id $GATEWAY --vpc-id $VPC

Une table de routage a été créée automatiquement, et on peut trouver son identifiant via la commande describe-route-tables, pour créer ensuite une route par défaut vers la passerelle.

aws ec2 describe-route-tables
ROUTETABLE=rtb-XXXXXXXX
aws ec2 create-route --route-table-id $ROUTETABLE --destination-cidr-block 0.0.0.0/0 --gateway-id $GATEWAY

Bien sûr, si on n'ouvre pas le trafic, on ne pourra pas contacter la machine... Ici, j'ouvre le port 22 pour un accès SSH.

aws ec2 describe-security-groups
SECURITY_GROUP=sg-XXXXXXXX
aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP --protocol tcp --port 22 --cidr 0.0.0.0/0

Autre changement, Amazon distribue maintenant des outils libres pour la ligne de commande, qui sont plus complets qu'euca2ools.

Prochaine étape, je vais recommencer les tests utilisant l'installeur Debian dans le Nuage.

01 August, 2016 09:38PM

July 11, 2016

hackergotchi for Raphaël Hertzog

Raphaël Hertzog

Mes activités libres en juin 2016

Mon rapport mensuel couvre une grande partie de mes contributions au logiciel libre. Je l’écris pour mes donateurs (merci à eux !) mais aussi pour la communauté Debian au sens large parce que cela peut donner des idées aux nouveaux venus et que c’est également un des moyens les plus effectifs de trouver des volontaires pour travailler sur les projets qui me tiennent à cœur.

Empaquetage Debian

Django et Python J’ai poussé la version 1.9.7 de Django, et créé auprès de l’amont le ticket n°26755, concernant l’échec aux tests DEP-8.

J’ai empaqueté/parrainé python-django-modeltranslation et python-paypal. J’ai ouvert une demande de pull pour model-translation, afin de corriger les échecs des tests de compilation de paquet Debian.

J’ai empaqueté une nouvelle version de python-django-jsonfield (la 1.0.0), créé un rapport de bug et découvert une régression dans le support PostgreSQL. J’ai apporté mon aide sur le ticket amont, et me suis vu accorder les droits de commit. J’ai profité de cette opportunité pour faire un peu de tri dans les bogues, et pousser quelques corrections. J’ai également discuté du futur du module et fini par lancer la discussion sur la liste de diffusion des développeurs Django, concernant la possibilité d’ajouter un champ JSONField au noyau.

CppUTest J’ai poussé une nouvelle version amont (3.8), contenant plus d’un an de travail. J’ai découvert que « make install » n’installait pas un des header requis, et j’ai donc créé le ticket correspondant, accompagné d’un patch. Le paquet ayant échoué à la compilation pour plusieurs architectures, j’ai créé un autre rapport de bogue et préparé un correctif pour certaines de ces erreurs, avec l’aide des développeurs amont. J’ai également ajouté un test DEP-8 après avoir envoyé un paquet cassé (et non testé)…

Support de systemd pour net-snmp et postfix J’ai travaillé à l’ajout de service units systemd natifs pour net-snmp (n°782243) et postfix (n°715188). Dans les deux cas, les mainteneurs n’ont pas été très réactifs jusqu’à présent, en conséquence de quoi j’ai poussé mes modifications en tant que non-mainteneur.

Équipe pkg-security Lancée doucement il y a quelques mois, l’équipe que j’ai créée est maintenant en croissance, que ce soit du point de vue du nombre de membres ou de celui du nombre de paquets. J’ai créé la page wiki Teams/pkg-security obligatoire, et parrainé les paquets xprobe et hydra. Enfin, j’ai poussé une mise à jour de medusa, pour incorporer les changements en provenance de Kali dans Debian (et soumettre le patch à l’amont dans le même temps).

fontconfig Après avoir lu l’analyse de Jonathan McDowell au sujet du bogue que de nombreux utilisateurs de Kali et moi-même ont rencontré à de multiples reprises, j’ai créé le ticket n°828037, afin que celui-ci soit corrigé une bonne fois pour toutes. Malheureusement, rien n’a changé à ce jour.

DebConf 16

Ce mois-ci, une partie de mon temps a été consacré à la préparation des deux conférences et de la table ronde que je vais présenter/animer à Cape Town entre le 2 et le 9 juillet :

Distro Tracker

J’ai continué le parrainage de Vladimir Likic, qui a réussi à terminer son premier patch. Il travaille maintenant sur la documentation à destination des nouveaux contributeurs, sur la base de son expérience récente.

J’ai amélioré la configuration tox pour pouvoir lancer des tests sur Django 1.8 LTS avec les avertissements bloquants (python -Werror) activés. De la sorte, je serai sûr de ne pas me baser sur une fonctionnalité abandonnée, et donc que la base de code sera fonctionnelle avec la prochaine version LTS Django (1.11). Cela m’a permis de découvrir les quelques endroits où j’utilisais effectivement des API obsolètes, et où j’ai mis à jour le code pour ne plus en dépendre (la mise à jour de JSONField vers la 1.0.0 dont j’ai parlé plus haut en est un parfait exemple).

J’ai également corrigé quelques problèmes supplémentaires avec les en-têtes d’emails « repliés », qui ne peuvent pas être réutilisés dans un nouvel objet Message, à qui il manque le champ Objet. Tous ces soucis ont été détectés via des exceptions déclenchées par une activité de spam, exceptions qui m’ont ensuite été transmises par email.

Travaux relatifs à Kali

j’ai poussé un nouveau live-boot (5.20160608) vers Debian, pour corriger un problème où le processus de boot était bloqué à cause d’un timeout.

J’ai transféré un bogue Kali affectant libatk-wrapper-java (n°827741), qui s’est trouvé être finalement un bogue OpenJDK.

J’ai créé le rapport de bogue n°827749 concernant reprepro, et demandant une méthode de suppression des références à des fichiers internes sélectionnés. C’est nécessaire si l’on souhaite pouvoir faire disparaître un fichier, et si ce dernier fait partie d’une sauvegarde que l’on veut garder malgré cela. En vérité, je souhaite avant tout pouvoir remplacer le fichier .orig.tar.gz utilisé par Kali par le orig.tar.gz utilisé par Debian… ces conflits cassent les scripts de réplication/import.

Salt

J’ai utilisé salt pour déployer un nouveau service, et j’ai développé plusieurs patchs pour quelques problèmes rencontrés dans les formules salt. J’ai également créé une nouvelle formule letsencrypt-sh pour la gestion des certificats TLS avec le client letsencrypt.sh ACME.

Merci

Rendez-vous au mois prochain pour un nouveau résumé de mes activités !

Ceci est une traduction de mon article My Free Software Activities in June 2016 contribuée par Weierstrass01.

Aucun commentaire pour le moment | Vous avez aimé ? Cliquez ici. | Ce blog utilise Flattr.

11 July, 2016 12:02PM by Raphaël Hertzog

July 09, 2016

hackergotchi for Charles Plessy

Charles Plessy

Félicitations, Marga !

Pour la première fois dans notre histoire, une femme rejoint le Comité Technique. Félicitations, Marga, et merci d'avoid donné ta candidature.

09 July, 2016 12:43PM

June 28, 2016

hackergotchi for Tanguy Ortolo

Tanguy Ortolo

J'ai testé pour vous UltraViolet (c'est de la merde)

Après avoir acheté un beau coffret de la trilogie cinématographique Le Hobbit, j'ai eu la surprise d'un trouver des instructions pour « récupérer une copie numérique » pour regarder ces films « sur tous mes écrans » grâce à un machin appelé UltraViolet. Les instructions indiquées sont les suivantes :

  1. allez sur warnerbros.fr/uv ;
  2. entrez un code d'activation.

S'agissant d'un machin développé par la MAFIAA, je pouvais déjà prédire le résultat, mais par acquit de conscience, j'ai tout de même essayé, avec un navigateur Web Firefox sous Debian GNU/Linux, plugin Flash installé et à jour, JavaScript et cookies activés sans restriction. Après tout, il est bien indiqué sur le papier que c'est censé marcher « sur tous mes écrans », avec de beaux petits schémas représentant un téléphone, une tablette, un ordinateur portable et un téléviseur.

Logo UltraViolet

Étape 1, Warner Bros

Deux étapes, on pourrait difficilement faire plus simple ! Sauf qu'évidemment, ça se complique. Sur la page UltraViolet de Warner Bros, il n'y a pas d'endroit où saisir un code ; au lieu de cela, il est proposé deux sites partenaires où on doit pouvoir l'entrer : Nolim films et Flixter.

Étape 1, deuxième partie, premier essai, Nolim films

Lorsque j'ai essayé, hier, la page de Nolim films affichait seulement « chargement en cours ». Après quelques minutes, j'ai donc renoncé et été voir chez Flixter.

Étape 1, deuxième partie, deuxième essai, Flixter

Côté Flixter, ça commence bien, on arrive sur un site en anglais. Une fois passé en français, il y a un bouton pour « Utiliser un code ». On tape le code et… ça dit qu'il n'y a aucun résultat. En fait, il faut saisir le titre du film, et ensuite seulement, saisir le code d'activation.

Étape 2, (essayer de) regarder ou télécharger le film

Il faut alors créer un compte, qui demande de fournir des renseignements personnels, c'est à dire des informations qui ne devraient certainement pas les concerner : pour regarder un film qu'on a acheté, il est anormal de devoir donner son nom, prénom et date de naissance. Personnellement, j'ai renseigné mon nom, mais une date de naissance bidon.

Enfin, on peut regarder son film. Enfin, essayer, parce que ça ne marche pas : ça lance une page avec Flash, qui affiche… du noir, puis un indicateur de chargement, et qui finit par planter le lecteur Flash.

On peut aussi télécharger son film avec un logiciel propriétaire proposé pour cela. Il est prévu pour Windows, et ne s'installe pas sous Wine.

Étape 3, ripper son DVD

Comme prédit, ça ne fonctionne pas. Il est donc temps de faire un peu chauffer mon processeur pour ripper mes DVD : ça au moins, ça fonctionne, et sans la moindre restriction. Autrement, ces flims doivent également être disponibles sur les réseaux de contrefaçon : contrairement à l'UltraTropLaid, ça aussi, ça fonctionne.

28 June, 2016 11:34AM by Tanguy

June 17, 2016

hackergotchi for J. Fernando Lagrange

J. Fernando Lagrange

La brique en voyage

La situation

Il se trouve que j’ai déménagé récemment. J’en ai profité pour demander un abonnement Internet à l’association de la Fédération FDN de mon coin: Rézine. J’ai donc mis ma brique Internet chez quelqu’un, le temps que l’accès Internet soit en place.

Le problème

Quand j’ai connecté la brique depuis un autre accès Internet, plus rien n’a fonctionné : pas de nouvelles de la brique sur Internet, ni sur le réseau local ! 🙁

La solution

Note pour les avocats: cette solution a fonctionné chez moi, mais il y a un risque de perdre des données. Rien ne garanti qu’elle fonctionnera chez vous ! Je ne peux pas être tenu pour responsable des actions que vous faites. En cas de doute, demandez de l’aide au membre FFDN le plus proche de chez vous !

 

« Malheureusement », j’ai un modèle de brique datant de juillet 2015 (avec la migration du blog sur la brique fin 2015). Et une fois fonctionnelle, je ne me suis pas occupé de son entretien: ne pas toucher à quelque chose qui fonctionne me semble un bon conseil à suivre en informatique.

Mais là, je n’avais pas vu qu’il y avait des erreurs sur le disque. Ces erreurs n’ont été gênantes qu’une fois la brique éteinte et rallumée. J’ai donc pris le disque dur de la brique (la carte microSD) et je l’ai mis dans mon PC.

Puis, avec la commande lsblk j’ai vu que la partition de ce disque était /dev/sdc1; j’ai alors pu lancer une vérification du disque avec la commande suivante:

# fsck /dev/sdc1
[…là, ça défile et des fois ça pose des questions…]

Quand la question était posée de corriger les erreurs, j’ai répondu oui. Une fois toutes les erreurs corrigées, j’ai relancé la commande pour vérifier qu’il n’y avait plus d’erreur:

# fsck /dev/sdc1
fsck de util-linux 2.25.2
e2fsck 1.42.12 (29-Aug-2014)
/dev/sdc1 : propre, 93335/917568 fichiers, 848399/3859968 blocs

C’est alors, plein d’espoir que j’ai remis le disque dur dans la brique pour la brancher et l’allumer: ça marchait à nouveau ! 🙂

Deuxième problème

Tout content que la brique refonctionne, j’ai payé un coup à boire à la personne qui l’héberge et je suis rentré chez moi. C’est avec un peu de déception que j’ai réalisé le lendemain que la brique ne fonctionnait plus ! :’-(

Ce deuxième problème est aussi lié au fait que j’ai mis en place ma brique en juillet 2015: à partir du moment où l’application vpnclient mettait en place le tunnel chiffré, la brique n’avait plus accès aux DNS (dont on parle dans cette superbe conférence) !

Après demande d’information à mon fournisseur de tunnels, c’est normal pour pleins de raisons diffèrentes, bref je dois utiliser leur DNS.

Deuxième solution

Une fois le problème identifié, la solution n’est pas loin ! Ici, j’ai mis à jour l’application vpnclient et le tour était joué: la dernière version de cette application prends en compte les DNS ! \o/

Je peux donc maintenant bloguer à nouveau, par exemple pour indiquer comment j’ai déplacé ma brique ! 🙂

Prochaines étapes: mise en place de sauvegardes… Stay tuned for more info

 

17 June, 2016 09:13AM by Low Memory

May 02, 2016

hackergotchi for Vincent Bernat

Vincent Bernat

Petit traité empirique de l'empaquetage Debian

Bien que la création de paquets Debian soit abondamment documentée, la plupart des tutoriaux ciblent les paquets respectueux de la charte Debian. De plus, leur création a longtemps eu la réputation d’être particulièrement difficile1 et beaucoup se sont tournés vers des outils moins contraignants2 tels que fpm ou CheckInstall.

Toutefois, je vais montrer que la construction de paquets Debian en utilisant les outils officiels est plutôt simple en appliquant ces quelques concessions :

  1. Aucun paquet source ne sera généré. Les paquets seront construits directement depuis une copie propre issue du système de versions.

  2. Des dépendances supplémentaires peuvent être téléchargées pendant la construction. Empaqueter individuellement chaque dépendance est un travail ingrat, notamment avec certains environnements tels que Java, Javascript et Go.

  3. Les paquets produits peuvent combiner et inclure des dépendances tierces. Cela peut lever certaines objections liées à la sécurité et à la maintenance à long terme, mais c’est une concession courante dans certains écosystèmes tels que Java, Javascript et Go.

Ceinture blanche§

Deux types de paquets coexistent dans l’archive Debian : les paquets sources et les paquets binaires. Un paquet source produit un ou plusieurs paquets binaires. Chaque paquet doit porter un nom.

Comme indiqué lors de l’introduction, aucun paquet source ne sera construit. Nous allons travailler directement sur sa représentation décompressée : une arborescence de fichiers incluant le répertoire debian/. Les exemples qui suivent utilisent une arborescence composée uniquement du répertoire debian/, mais ce dernier peut être inclus dans n’importe quel project existant.

Comme point de départ, nous allons empaqueter memcached, un cache mémoire distribué. Il nous faut créer quatre fichiers :

  • debian/compat,
  • debian/changelog,
  • debian/control et
  • debian/rules.

Le premier contient uniquement 9 :

echo 9 > debian/compat

Le second contient ceci :

memcached (0-0) UNRELEASED; urgency=medium

  * Fake entry

 -- Happy Packager <happy@example.com>  Tue, 19 Apr 2016 22:27:05 +0200

La seule information d’importance est le nom du paquet source, memcached, sur la première ligne. Toutes les autres informations sont sans influence sur les paquets créés.

Le fichier de contrôle§

debian/control décrit les méta-données à propos du paquet source et des paquets binaires. Un bloc est dédié à chacun d’eux.

Source: memcached
Maintainer: Vincent Bernat <bernat@debian.org>

Package: memcached
Architecture: any
Description: high-performance memory object caching system

Le paquet source est memcached. Il faut utiliser le même nom que dans le fichier debian/changelog.

Un seul paquet binaire est créé : memcached. Par la suite, si vous voyez memcached, il s’agit du nom du paquet binaire. The champ Architecture doit être soit any, soit all. Ce dernier est utilisé exclusivement si tous les fichiers sont indépendants de l’architecture matérielle. Dans le doute, il suffit de mettre any.

Le champ Description contient une courte description du paquet binaire.

La recette§

Le dernier fichier à rédiger est debian/rules. Il s’agit de la recette du paquet. Nous avons besoin de télécharger memcached, le construire et installer son arborescence dans debian/memcached/ :

#!/usr/bin/make -f

DISTRIBUTION = $(shell lsb_release -sr)
VERSION = 1.4.25
PACKAGEVERSION = $(VERSION)-0~$(DISTRIBUTION)0
TARBALL = memcached-$(VERSION).tar.gz
URL = http://www.memcached.org/files/$(TARBALL)

%:
    dh $@

override_dh_auto_clean:
override_dh_auto_test:
override_dh_auto_build:
override_dh_auto_install:
    wget -N --progress=dot:mega $(URL)
    tar --strip-components=1 -xf $(TARBALL)
    ./configure --prefix=/usr
    make
    make install DESTDIR=debian/memcached

override_dh_gencontrol:
    dh_gencontrol -- -v$(PACKAGEVERSION)

Les cibles vides override_dh_auto_clean, override_dh_auto_test et override_dh_auto_build permettent de s’assurer que debhelper ne fera rien de « magique ». La cible override_dh_gencontrol permet de spécifier la version3 sans avoir à tenir à jour debian/changelog. Cette recette est très similaire à ce qui aurait été écrit pour fpm :

DISTRIBUTION=$(lsb_release -sr)
VERSION=1.4.25
PACKAGEVERSION=${VERSION}-0~${DISTRIBUTION}0
TARBALL=memcached-${VERSION}.tar.gz
URL=http://www.memcached.org/files/${TARBALL}

wget -N --progress=dot:mega ${URL}
tar --strip-components=1 -xf ${TARBALL}
./configure --prefix=/usr
make
make install DESTDIR=/tmp/installdir

# Build the final package
fpm -s dir -t deb \
    -n memcached \
    -v ${PACKAGEVERSION} \
    -C /tmp/installdir \
    --description "high-performance memory object caching system"

Vous pouvez lire le résultat final sur GitHub et le construire avec la commande dpkg-buildpackage -us -uc -b.

Ceinture jaune§

À partir de là, il est possible d’inclure quelques améliorations. Aucune n’est essentielle mais le gain est suffisamment intéressant pour justifier l’effort.

Les dépendances sources§

Notre recette initiale ne fonctionne que si nous disposons déjà de wget et de libevent-dev. Ces paquets ne sont pas présents sur tous les systèmes. Il est assez aisé de spécifier ces dépendances en ajoutant un champ Build-Depends dans debian/control :

Source: memcached
Build-Depends: debhelper (>= 9),
               wget, ca-certificates, lsb-release,
               libevent-dev

Il faut toujours spécifier debhelper (>= 9) car son utilisation est centrale dans debian/rules. Il n’y a pas besoin de dépendre de make ou d’un compilateur C car le paquet build-essential est considéré comme toujours présent et il les fournit indirectement. dpkg-buildpackage se plaindra si une des dépendances est manquante. Pour installer sans peine ces paquets, vous pouvez utiliser la commande suivante4 :

mk-build-deps \
    -t 'apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends -qqy' \
    -i -r debian/control

Il est aussi intéressant de se pencher sur des outils tels que pbuilder et sbuild qui permettent de construire des paquets dans un environnment minimal et isolé.

Les dépendances binaires§

Si le paquet ainsi construit est installé sur une machine vierge, memcached refusera de démarrer en raison de l’absence de libevent. Il est possible d’exprimer cette dépendance en ajoutant un champ Depends dans le fichier debian/control. De plus, dans le cas des bibliothèques dynamiques, ces dépendances peuvent être générées automatiquement en utilisant des variables de substitution :

Package: memcached
Depends: ${misc:Depends}, ${shlibs:Depends}

Le paquet construit contiendra les informations suivantes :

$ dpkg -I ../memcached_1.4.25-0\~unstable0_amd64.deb | grep Depends
 Depends: libc6 (>= 2.17), libevent-2.0-5 (>= 2.0.10-stable)

Intérgration avec un système de démarrage§

La plupart des paquets fournissant un démon incluent une intégration avec le système de démarrage afin de démarrer le démon au boot ou de le redémarrer après une mise à jour. Pour les distributions basées sur Debian, il existe plusieurs systèmes de démarrage. Voici les trois plus courants.

  • System-V est le système historique. Ces scripts de démarrage peuvent être réutilisés par les autres systèmes. Il s’agit donc du plus petit dénominateur commun.
  • Upstart est le système popularisé par Ubuntu. Il est utilisé jusqu’à la version 14.10, incluse.
  • systemd est le système par défaut pour Debian depuis Jessie et pour Ubuntu depuis la version 15.04.

Écrire un script de démarrage pour System-V est une tâche ardue. Habituellement, je préfère donc simplement fournir un script pour le système de démarrage par défaut de la distribution visée (Upstart et systemd).

System-V§

Si vous voulez écrire un script de démarrage pour System-V, adaptez5 le script /etc/init.d/skeleton de la distribution la plus ancienne que vous souhaitez supporter. Mettez le résultat dans le fichier debian/memcached.init. Il sera installé au bon endroit et invoqué lors de l’installation, mise à jour ou retrait du paquet. Habituellement, l’utilisateur peut personnaliser les options du démon en modifiant le fichier /etc/default/memcached. Pour en fournir un, placez son contenu dans le fichier debian/memcached.default.

Upstart§

Fournir un script pour Upstart est similaire : son contenu doit être placé dans debian/memcached.upstart. Par exemple :

description "memcached daemon"

start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 5 60
expect daemon

script
  . /etc/default/memcached
  exec memcached -d -u $USER -p $PORT -m $CACHESIZE -c $MAXCONN $OPTIONS
end script

La directive la plus importante à surveiller est expect. Ici, nous utilisons expect daemon et memcached est démarré avec l’option -d.

systemd§

Fournir un script pour systemd est un tout petit peu plus compliqué. Le contenu doit se placer dans debian/memcached.service. Par exemple :

[Unit]
Description=memcached daemon
After=network.target

[Service]
Type=forking
EnvironmentFile=/etc/default/memcached
ExecStart=/usr/bin/memcached -d -u $USER -p $PORT -m $CACHESIZE -c $MAXCONN $OPTIONS
Restart=on-failure

[Install]
WantedBy=multi-user.target

Bien que cela ne soit pas considéré comme une bonne pratique6, nous réutilisons /etc/default/memcached. Comme pour Upstart, la directive Type est particulièrement importante. Nous utilisons forking car memcached est démarré avec l’option -d.

Il est également nécessaire d’ajouter une dépendance source sur dh-systemd dans debian/control :

Source: memcached
Build-Depends: debhelper (>= 9),
               wget, ca-certificates, lsb-release,
               libevent-dev,
               dh-systemd

Il faut également modifier la règle par défaut dans debian/rules :

%:
    dh $@ --with systemd

Cette complexité supplémetaire est regrettable et est dû au fait que l’intégration de systemd ne fait pas partie de debhelper7. Sans ces modifications, le script sera installé mais l’intégration n’aura pas lieu et il ne sera pas lancé au démarrage de la machine.

Utilisateur dédié§

De nombreux démons n’ont pas besoin de s’exécuter en tant que root et c’est souvent une bonne idée de fournir un utilisateur dédié. Dans le cas de memcached, nous allons fournir l’utilisateur _memcached8.

Ajoutez un fichier debian/memcached.postinst avec le contenu suivant :

#!/bin/sh

set -e

case "$1" in
    configure)
        adduser --system --disabled-password --disabled-login --home /var/empty \
                --no-create-home --quiet --force-badname --group _memcached
        ;;
esac

#DEBHELPER#

exit 0

Lorsque le paquet est désinstallé, aucun ménage n’est effectué :

  • moins de code à écrire, moins de bugs,
  • l’utilisateur peut toujours posséder quelques fichiers sur le système.

L’utilitaire adduser effectuera toujours la bonne action que l’utilisateur demandé existe déjà ou non. Il faut penser à l’ajouter comme dépendance binaire dans debian/control :

Package: memcached
Depends: ${misc:Depends}, ${shlibs:Depends}, adduser

Le marqueur #DEBHELPER# indique le point d’insertion pour des scripts d’intégration supplémentaires.

Le résultat final est disponible sur GitHub et peut être testé avec la commande dpkg-buildpackage -us -uc -b.

Ceinture verte§

Il est possible d’exploiter certaines capacités de debhelper pour réduire la taille du fichier debian/rules et pour le rendre plus déclaratif. Cette section est totalement optionnelle : vous pouvez la sauter si besoin.

Banalités§

Il y a quatre étapes dans la construction d’un paquet Debian :

  1. debian/rules clean va nettoyer l’arborescence pour revenir dans son état initial.

  2. debian/rules build doit construire le logiciel. Pour quelque chose de basé sur autoconf, comme memcached, il s’agit essentiellement d’exécuter ./configure && make.

  3. debian/rules install doit installer l’arborescence de chaque paquet binaire dans le répertoire approprié. Pour des logiciels basés sur autoconf, il s’agit d’exécuter make install DESTDIR=debian/memcached.

  4. debian/rules binary doit empaqueter les différentes arborescences en paquets binaires.

Il ne faut pas écrire directement chacune de ces cibles. L’utilitaire dh, un composant de debhelper, va faire la majeure partie du boulot. Le fichier debian/rules minimaliste suivant suffit pour accomplir cette tâche pour de nombreux paquets sources :

#!/usr/bin/make -f
%:
    dh $@

Pour chacune des quatre cibles décrites ci-dessus, vous pouvez exécuter dh --no-act pour voir les utilitaires invoqués. Par exemple :

$ dh build --no-act
   dh_testdir
   dh_update_autotools_config
   dh_auto_configure
   dh_auto_build
   dh_auto_test

Chacun de ces utilitaires dispose d’une page de manuel. Ceux commençant par dh_auto sont un peu « magiques ». Par exemple, dh_auto_configure va tenter de configurer automatiquement le logiciel avant l’étape de construction. Selon les cas, il peut invoquer ./configure, cmake ou Makefile.PL.

Si un des utilitaires dh_ ne fait pas ce qu’il faut, il est possible de le remplacer en déclarant une cible nommée de manière adéquate :

override_dh_auto_configure:
    ./configure --with-some-grog

Chaque utilitaire est également configurable via des options. Ainsi, il est possible de modifier leurs comportements en définissant la cible correspondante et en invoquant l’utilitaire manuellement :

override_dh_auto_configure:
    dh_auto_configure -- --with-some-grog

Ainsi, ./configure sera appelé avec l’option --with-some-grog mais aussi avec des options par défaut telles que --prefix=/usr.

Dans l’exemple initial de memcached, ces cibles « magiques » sont surchargées. dh_auto_clean, dh_auto_configure et dh_auto_build ont été neutralisées pour éviter tout comportement inattendu. dh_auto_install a été détournée pour exécuter l’intégralité de la construction de l’arborescence cible. De plus, le comportement de dh_gencontrol a été modifié en lui fournissant le numéro de version désiré plutôt que de le laisser regarder dans debian/changelog.

Construction automatique§

memcached utilisant autoconf, dh sait comment le construire : ./configure && make && make install. Il est donc possible de laisser dh faire la majeure partie du boulot avec le fichier debian/rules suivant :

#!/usr/bin/make -f

DISTRIBUTION = $(shell lsb_release -sr)
VERSION = 1.4.25
PACKAGEVERSION = $(VERSION)-0~$(DISTRIBUTION)0
TARBALL = memcached-$(VERSION).tar.gz
URL = http://www.memcached.org/files/$(TARBALL)

%:
    dh $@ --with systemd

override_dh_auto_clean:
    wget -N --progress=dot:mega $(URL)
    tar --strip-components=1 -xf $(TARBALL)

override_dh_auto_test:
    # Don't run the whitespace test
    rm t/whitespace.t
    dh_auto_test

override_dh_gencontrol:
    dh_gencontrol -- -v$(PACKAGEVERSION)

La cible dh_auto_clean est détournée pour effectuer le téléchargement et la mise en place de l’arborescence9. Ni dh_auto_configure, ni dh_auto_build ne sont modifiés. dh appellera ./configure avec les options appropriées puis make. dh_auto_test doit exécuter la suite de tests de memcached. Toutefois, un des tests échoue en raison d’un fichier dans le répertoire debian/. Nous supprimons ce test récalcitrant et invoquons manuellement dh_auto_test. dh_auto_install n’est pas surchargé et dh exécutera alors une variante de make install.

Afin de mieux apprécier la différence, la voici sous forme de patch :

--- memcached-intermediate/debian/rules 2016-04-30 14:02:37.425593362 +0200
+++ memcached/debian/rules  2016-05-01 14:55:15.815063835 +0200
@@ -12,10 +12,9 @@
 override_dh_auto_clean:
-override_dh_auto_test:
-override_dh_auto_build:
-override_dh_auto_install:
    wget -N --progress=dot:mega $(URL)
    tar --strip-components=1 -xf $(TARBALL)
-   ./configure --prefix=/usr
-   make
-   make install DESTDIR=debian/memcached
+
+override_dh_auto_test:
+   # Don't run the whitespace test
+   rm t/whitespace.t
+   dh_auto_test

Vous avez le choix de laisser dh faire une partie du travail ou non. Il est généralement possible de partir d’un debian/rules minimal et de surcharger uniquement quelques cibles.

Fichiers supplémentaires§

Bien que make install ait installé les fichiers essentiels pour memcached, il est parfois nécessaire de copier quelques fichiers supplémentaires dans le paquet binaire. Pour se faire, il est possible d’utiliser cp ou encore de déclarer les fichiers à copier :

  • les fichiers listés dans debian/memcached.docs seront copiés dans /usr/share/doc/memcached par dh_installdocs,
  • les fichiers listés dans debian/memcached.examples seront copiés dans /usr/share/doc/memcached/examples par dh_installexamples,
  • les fichiers listés dans debian/memcached.manpages seront copiés dans le sous-répertoire approprié de /usr/share/man par dh_installman,

Voici un exemple pour debian/memcached.docs :

doc/*.txt

Si vous avez besoin de copier des fichiers à un endroit arbitraire, il est possible de lister ceux-ci ainsi que leur répertoire cible dans le fichier debian/memcached.install. dh_install se chargera de la copie. Par exemple :

scripts/memcached-tool usr/bin

L’utilisation de ces fichiers permet une description plus déclarative de la recette. Il s’agit d’une histoire de goût et vous pouvez tout à fait utiliser cp à la place. Le résultat final est visible sur GitHub.

Autres exemples§

Le dépôt GitHub comprend d’autres exemples. Ils suivent tous le même schéma et mettent en œuvre les techniques décrites dans les sections précédentes.

Il y a notamment des exemples de démons en Java, Go, Python et Node.js. Le but de ces exemples est de démontrer que l’utilisation des outils Debian est relativement simple. Mission accomplie ?


  1. La mémoire collective est toujours marquée par la glorieuse époque précédant l’introduction de debhelper 7.0.50 (circa 2009). La création du fichier debian/rules était alors particulièrement laborieuse. Toutefois, de nos jours, le squelette est devenu minimal. 

  2. La complexité n’est pas la seule raison de ce choix : les outils alternatifs proposent également la création de paquets RPM, ce que les outils Debian ne permettent pas. 

  3. Il y a différentes façons de numéroter les versions d’un paquet. La façon proposée ici n’est pas plus mauvaise qu’une autre pour Ubuntu. Pour Debian, elle ne couvre pas les mises à jour entre deux versions de la distribution. De nos jours, il est cependant plutôt courant de réinstaller un système plutôt que de le mettre à jour. 

  4. Les paquets devscripts et equivs sont alors nécessaires. 

  5. Il est également possible d’utiliser le script fourni en amont. Toutefois, il n’existe pas de script universel fonctionnant sur toutes les distributions. Il est donc important de vérifier que ce script est adapté à Debian en le comparant au squelette et en vérifiant qu’il utilise bien start-stop-daemon et le fichier /lib/lsb/init-functions. Si c’est le cas, vous pouvez le copier vous-même dans debian/memcached/etc/init.d. debhelper ajoutera les scripts nécessaires à son intégration. 

  6. Un utilisateur désireux de modifier certaines options doit plutôt utiliser systemctl edit

  7. Voir #822670 Pour les paquets destinés à Debian Stretch ou Ubuntu Yaketty (ou plus récents), placer 10 dans le fichier debian/compat sera suffisant pour retirer dh-systemd des dépendances et --with systemd du fichier debian/rules

  8. La charte Debian ne se prononce pas sur la convention à utiliser. Il est courant de préfixer le nom du démon avec un tiret bas (comme dans les BSD). Un autre usage courant est d’utiliser Debian- comme préfixe. Cette dernière méthode a l’inconvénient de produire un nom d’utilisateur trop long pour être visible dans les utilitaires comme top et ps

  9. Il aurait été possible d’appeler dh_auto_clean à la fin de la cible. Toutefois, nous nous plaçons dans l’hypothèse que chaque construction est faite sur une nouvelle copie issue du système de version. 

02 May, 2016 07:25PM by Vincent Bernat

April 28, 2016

hackergotchi for Tanguy Ortolo

Tanguy Ortolo

Pour des cartes restaurant anonymes

Contexte

Dans les années 2000, la RATP et la SNCF on progressivement imposé le remplacement des tickets de papier anonymes par des cartes à puce nommées Navigo, pour les utilisateurs d'abonnements. Le problème, c'est que ces cartes à puces étaient nominatives, et que dans un pays libre, « aller et venir librement, anonymement, est l’une des libertés fondamentales. » La CNIL a donc imposé la création d'une carte Navigo anonyme.

L'histoire bégaie un peu. Dans les années qui viennent, sous la pression de l'État, les opérateurs de titres restaurant vont progressivement imposer le remplacement des titres de papier anonymes par des cartes à puce, qui permettent un plus grand contrôle des usages, afin d'en limiter les utilisations détournées. Le problème, c'est que ces cartes à puce sont nominatives, et que dans un pays libre, se nourrir, et plus généralement consommer librement, anonymement, est l'une des libertés fondamentales. La CNIL devrait donc imposer la création de cartes restaurant anonymes.

C'est possible

Les opérateurs de titres restaurant objecteront peut-être que c'est techniquement impossible. Pour les aider ainsi que la CNIL, voici une description d'un système qui rendrait possible l'utilisation de cartes restaurant anonymes. Comme pour les cartes de transport, choisir l'anonymat peut impliquer de renoncer à certains avantages.

L'entreprise distribuant des titres restaurant à ses salariés dispose d'un stock de quelques cartes anonymes, seulement identifiées par leur numéro. Comme toute carte restaurant, chacune est associée à un compte initialement vide.

Lorsqu'un salarié demandé à disposer d'une carte anonyme, l'entreprise lui fournit une de ces cartes. Elle peut noter et transmettre à l'opérateur le fait que cette carte est maintenant attribuée, mais a interdiction de relever le nom du salarié qui l'utilise. Si le salarié disposait déjà d'une carte nominative, son numéro doit être relevé afin de cesser d'alimenter le compte correspondant, ce qui peut être traité de la même façon qu'un retrait de l'offre de titres restaurant. Évidemment, l'entreprise a interdiction de tenter de dissuader les salariés de choisir l'anonymat, et de pénaliser ceux qui feraient ce choix.

Chaque mois, lors de la distribution des titres restaurant, le salarié utilisateur d'une carte anonyme se présente en personne, comme cela se fait pour des titres en papier. Le responsable approvisionne le compte correspondant au numéro indiqué sur la carte, et note sur un registre séparé que ce salarié a bien bénéficié de la distribution. L'entreprise a interdiction de noter sur ce registre le numéro de la carte créditée, et, d'une façon générale, de noter ou de transmettre tout ce qui pourrait permettre d'associer les noms des salariés avec les numéros des cartes anonymes. Encore une fois, l'entreprise a interdiction de pénaliser les salariés qui se présentent pour une distribution anonyme.

Le salarié utilise sa carte restaurant de façon normale pour régler ses consommations et achats éligibles dans les conditions prévues. Les restaurateurs de enseignes acceptant les paiements par carte restaurant ont interdiction de pénaliser les utilisateurs de cartes anonymes. Seules les fonctionnalités annexes de gestion peuvent être affectées par le caractère anonyme de la carte : ainsi, en cas de perte, l'opposition sur cette carte ne pourra pas être effectuée avec le seul nom du bénéficiaire, mais nécessitera la connaissance de son numéro, faute de quoi elle ne pourra être réalisé, et le crédit restant devra être considéré comme non récupérable. De telles restrictions doivent être justifiées par une raison technique : ainsi, il ne serait pas admissible de restreindre une opération de promotion chez un restaurateur partenaire aux seuls titulaires de cartes nominatives.

28 April, 2016 05:47PM by Tanguy

April 25, 2016

Parking Méditerranée - Gare de Lyon : attention, hostile aux vélos

Parking Méditerranée

La Gare de Lyon est une grande gare parisienne, qui est desservie à la fois par le réseau régional et par plusieurs grandes lignes nationales. On y trouve donc :

  • des riverains, qui habitent ou travaillent près de la gare ;
  • des usagers quotidiens ;
  • des voyageurs occasionnels, qui partent ou reviennent par exemple de week-end ou de vacances en province.

Le parking Méditerranée, opéré par la SAEMES, est situé sous la gare de Lyon, et accueille le même type de clients :

  • des usagers quotidiens, qui y parquent leur véhicule tous les jours ou toutes les nuits ;
  • des voyageurs occasionnels, qui parquent ponctuellement leur véhicule pour quelques jours, voire quelques semaines.

Cet usage est indépendant du type de véhicule, qu'il s'agisse d'une voiture, d'une moto ou d'une bicyclette.

Théoriquement, un accès vélo

Sur sa page Web, le parking Méditerranée - Gare de Lyon affiche un joli logo vélo, qui suggère la possibilité d'y garer sa bicyclette (qu'est-ce que ça pourrait bien vouloir dire d'autre ?).

De surprise en surprise

La réalité est toute autre. Le voyageur qui arrive à vélo au parking Méditerranée va de surprise en surprise (et de pire en pire) :

  1. L'espace vélo n'est pas indiqué, les panneaux donnant seulement le choix entre l'espace voiture et l'espace moto. Faute de mieux, autant choisir l'espace moto, c'est ce qui se fait de plus approchant.
  2. On est censé prendre un ticket, mais la machine n'en distribue pas aux vélos : on a beau appuyer sur le bouton prévu pour cela, rien ne sort et la barrière reste fermée. Qu'à cela ne tienne, un vélo est suffisamment maniable pour contourner la barrière, mais ça commence mal (et ça va mal finir, mais pour le moment, on a un train à prendre)…
  3. Une fois arrivé dans l'espace moto, comme on peut s'y attendre, rien n'est prévu pour fixer des vélos. Peu importe, un cycliste urbain est de toute façon habitué à stationner comme il le peut, une barrière fera donc l'affaire, en vérifiant bien qu'on ne gêne pas le passage ou le stationnement des autres usagers.
  4. Une fois rentré de voyage, et de retour à la gare de Lyon, on constate que l'exploitant du parking a enchaîné la bicyclette, sans un mot d'explication, sans doute parce qu'elle était mal garée, mais comment pourrait-elle être bien garée puisque l'espace vélos n'est pas indiqué ?
  5. À l'accueil, l'exploitant exige un paiement pour libérer le vélo. Pourquoi pas, mais 15 €, c'est un peu cher pour trois jours de stationnement en occupant zéro emplacement.

Un parking hostile aux vélos

Le parking Méditerranée - Gare de Lyon, qui s'affiche sur le Web avec un espace vélo, est en réalité hostile à ce type de véhicule. Le fait d'afficher un espace vélo, qui s'avère en réalité indisponible, pourrait d'ailleurs relèver de la publicité mensongère.

Suite à cette désagréable expérience, j'ai commencé une enquête sur le stationnement vélo dans les parkings publics des grandes gares parisiennes, dont certains indiquent ainsi disposer d'un espace vélo, qui peut s'avérer inexistant. Affaire à suivre.

25 April, 2016 05:01PM by Tanguy

April 10, 2016

hackergotchi for Vincent Bernat

Vincent Bernat

Test d'un applicatif réseau avec pytest et les espaces de noms Linux

Initié en 2008, lldpd est une implémentation en C du standard IEEE 802.1AB-2005 (aussi connu comme LLDP). Bien qu’il soit accompagné de quelques tests unitaires, comme beaucoup d’autres applicatifs réseaux, la couverture de ceux-ci est assez restreinte : il sont plutôt difficile à écrire en raison de l’aspect impératif du code et du couplage fort avec le système. Une réécriture (itérative ou complète) aiderait à rendre le code plus simple à tester, mais cela nécessiterait un effort important et introduirait de nouveaux bugs opérationnels.

Afin d’obtenir une meilleure couverture des tests, les fonctionnalités les plus importantes de lldpd sont désormais vérifiées à travers des tests d’intégration. Ceux-ci se reposent sur l’utilisation des espaces de noms Linux pour mettre en place des environnements isolés légers pour chaque test. pytest est utilisé comme outil de test.

pytest en bref§

pytest est un outil de tests pour Python dont la versatilité permet son usage dans de nombreuses situations. Il dispose de trois fonctionnalités remarquables :

  • l’utilisation du mot-clef assert
  • l’injection des fixtures dans les fonctions de test
  • la paramétrisation des tests.

Les assertions§

Avec unittest, l’outil de tests unitaires fourni avec Python, les tests sont encapsulés dans une classe et doivent faire appel à des méthodes dédiées pour les assertions. Par exemple :

class testArithmetics(unittest.TestCase):
    def test_addition(self):
        self.assertEqual(1 + 3, 4)

Avec pytest, il est possible d’exprimer ceci plus naturellement :

def test_addition():
    assert 1 + 3 == 4

pytest va analyser l’AST et afficher des messages d’erreur appropriés en cas d’échec. Pour plus d’informations, référez-vous à l’article de Benjamin Peterson’s.

Les fixtures§

Une fixture est un ensemble d’actions à effectuer afin de préparer le système à exécuter une série de tests. Avec les outils classiques, il n’est souvent possible de définir qu’une seule fixture pour une ensemble de tests :

class testInVM(unittest.TestCase):

    def setUp(self):
        self.vm = VM('Test-VM')
        self.vm.start()
        self.ssh = SSHClient()
        self.ssh.connect(self.vm.public_ip)

    def tearDown(self):
        self.ssh.close()
        self.vm.destroy()

    def test_hello(self):
        stdin, stdout, stderr = self.ssh.exec_command("echo hello")
        stdin.close()
        self.assertEqual(stderr.read(), b"")
        self.assertEqual(stdout.read(), b"hello\n")

Dans l’exemple ci-dessus, nous voulons tester quelques commandes sur une machine virtuelle. La fixture démarre la VM et initie la connexion SSH. Toutefois, en cas d’échec de cette dernière, la méthode tearDown() ne sera pas appelée et la VM continuera de tourner.

Avec pytest, il est possible de faire les choses différemment :

@pytest.yield_fixture
def vm():
    r = VM('Test-VM')
    r.start()
    yield r
    r.destroy()

@pytest.yield_fixture
def ssh(vm):
    ssh = SSHClient()
    ssh.connect(vm.public_ip)
    yield ssh
    ssh.close()

def test_hello(ssh):
    stdin, stdout, stderr = ssh.exec_command("echo hello")
    stdin.close()
    stderr.read() == b""
    stdout.read() == b"hello\n"

La première fixture démarre une VM. La seconde va fournir une connexion SSH vers la VM fournie en argument. Les fixtures sont utilisées à travers un système d’injection des dépendences : la seule présence de leur nom dans la signature d’une fonction de test ou d’une autre fixture suffit à l’utiliser. Chaque fixture ne gère le cycle de vie que d’une seule entité. Peu importe si une autre fixture ou une fonction de tests dépendant de celle-ci réussit ou non, la VM sera démantelée en fin de test.

La paramétrisation§

Si un test doit être exécuté plusieurs fois avec des paramètres différents, la solution classique est d’utiliser une boucle ou de définir dynamiquement les fonctions de test. Avec pytest, vous pouvez paramétriser une fonction de test ou une fixture :

@pytest.mark.parametrize("n1, n2, expected", [
    (1, 3, 4),
    (8, 20, 28),
    (-4, 0, -4)])
def test_addition(n1, n2, expected):
    assert n1 + n2 == expected

Tester lldpd§

Tester une fonctionnalité de lldpd se fait en cinq étapes :

  1. Mettre en place deux espaces de noms.
  2. Créer un lien virtuel entre ceux-ci.
  3. Démarrer un processus lldpd dans chaque espace.
  4. Tester la fonctionnalité dans un des espaces.
  5. Vérifier avec lldpcli le résultat attendu dans l’autre espace.

Voici un test typique utilisant les fonctionnalités les plus intéressantes de pytest :

@pytest.mark.skipif('LLDP-MED' not in pytest.config.lldpd.features,
                    reason="LLDP-MED not supported")
@pytest.mark.parametrize("classe, expected", [
    (1, "Generic Endpoint (Class I)"),
    (2, "Media Endpoint (Class II)"),
    (3, "Communication Device Endpoint (Class III)"),
    (4, "Network Connectivity Device")])
def test_med_devicetype(lldpd, lldpcli, namespaces, links,
                        classe, expected):
    links(namespaces(1), namespaces(2))
    with namespaces(1):
        lldpd("-r")
    with namespaces(2):
        lldpd("-M", str(classe))
    with namespaces(1):
        out = lldpcli("-f", "keyvalue", "show", "neighbors", "details")
        assert out['lldp.eth0.lldp-med.device-type'] == expected

Tout d’abord, ce test ne sera exécuté que si le support de LLDP-MED a été inclu dans lldpd. De plus, le test est paramétré : quatre tests distincts seront effectués, un pour chaque rôle que lldpd doit être capable d’assumer en tant que terminaison LLDP-MED.

La signature du test comporte quatre paramètres non couverts par le décorateur parametrize() : lldpd, lldpcli, namespaces et links. Il s’agit des fixtures.

  • lldpd est une fabrique qui permet de lancer des instances de lldpd. Elle assure la configuration de l’espace de noms (mise en place de la séparation de privilèges, unformisation de certains fichiers, …) puis appelle lldpd avec les paramètres additionnels fournis. Les messages émis par le démon sont enregisrés dans le rapport en cas d’erreur. Le module se charge aussi de fournir un objet pytest.config.lldpd qui contient les fonctionnalités supportées par lldpd afin de sauter les tests qui nécessitent une fonctionnalité non disponible. Le fichier fixtures/programs.py contient davantage de détails.

  • lldpcli est également une fabrique, mais pour lancer des instances de lldpcli, le client pour interroger lldpd. De plus, la sortie produite est traitée pour obtenir un dictionnaire et faciliter l’écriture des tests.

  • namespaces est la fixture la plus intéressante. Il s’agit d’une fabrique pour les espaces de noms Linux. Elle va créer un nouvel espace de nom ou référencer un espace existant. Il est possible d’entrer dans un espace donné avec le mot-clef with. La fabrique maintient pour chaque espace une liste de descripteurs de fichiers sur lesquels exécuter setns(). Une fois le test fini, les espaces de noms sont détruits naturellement du fait de la fermeture de tous les descripteurs de fichiers. Le fichier fixtures/namespaces.py contient davantage de détails. Cette fixture est réutilisable par d’autres projets1.

  • links contient des fonctions pour gérer les interfaces réseau : création d’une paire d’interfaces Ethernet entre deux espaces de noms, création de ponts, d’aggrégats et de VLAN, etc. Il se repose sur le module pyroute2. Le fichier fixtures/network.py contient davantage de détails.

Vous pouvez découvrir un exemple d’exécution de ces tests en regardant le résultat obtenu avec Travis pour la version 0.9.2. Chaque test étant isolé, il est possible de les lancer en parallèle avec pytest -n 10 --boxed. Afin de dépister encore plus de bugs, à la compilation, l’address sanitizer (ASAN) et le undefined behavior sanitizer (UBSAN) sont activés. En cas de problème détecté, comme par exemple une fuite mémoire, le programme s’arrêtera avec un code de sortie non nul et le test associé échouera.


  1. Il y a trois principales limitations concernant l’usage des espaces de noms avec cette fixture. Tout d’abord, lors de la création d’un user namespace, seul root est lié avec l’utilisateur actuel. lldpd nécessite deux utilisateurs (root et _lldpd). Aussi, il n’est pas possible de se reposer sur cette fonctionnalité pour faire tourner les tests sans être root. La seconde limitation concerne les PID namespace. Il n’est pas possible pour un process de changer de PID namespace. L’appel de setns() ne sera effectif que pour les descendants du process. Il est donc important de ne monter /proc que dans les descendants. La dernière limitation concerne les fils d’exécution : ils doivent tous être dans le même user namespace et PID namespace. Le module threading doit donc être remplacé par l’utilisation du module multiprocessing

10 April, 2016 04:22PM by Vincent Bernat

April 07, 2016

hackergotchi for Charles Plessy

Charles Plessy

Les entrées FreeDesktop entrent dans la charte Debian.

Après une longue pérégrination qui a duré près de trois ans, l'utilisation des entrées de menu FreeDesktop est enfin décrite dans notre Charte.

En bonus, cette nouvelle version 3.9.8 de la Charte rappelle aussi qu'il faut enregistrer les nouveaux types de média chez l'IANA.

Merci à tous ceux qui ont rendu ceci possible.

07 April, 2016 01:03PM

March 17, 2016

hackergotchi for Aurélien Jarno

Aurélien Jarno

(Pseudo-)virtualizing Intel USB controllers

I own a motherboard an Intel 8-Series Lynx Point chipset, with an Intel Haswell CPU supporting VT-d. This allow me to use Linux’s VFIO features and assign PCIe devices to a KVM-based virtual machine. High-end network controllers goes even further with the Single Root I/O Virtualization (SR-IOV) capabilities, allowing them to be shared between to multiple virtual machines.

The Lynx Point chipset provides a total of 14 USB ports arranged in 6 USB 3.0 ports and 8 USB 2.0 ports. It would be nice to be able to assign USB ports to virtual machines. QEMU already allows to assign a USB device to a virtual machine, but it works emulating a USB controller, and the traffic goes through userland. In addition it only works for a specific known device, a random device plugged to a given port is not automatically assigned to the guest (though I guess it can be scripted using the libvirt API). The xHCI specification, the one behind USB 3.0, has been designed to also support SR-IOV, to the best of my knowledege none of them actually support it. We’ll see that with some hacks it is possible to actually assign a set of USB ports to a virtual machine, with the restrictions that running ports in SuperSpeed mode is allowed only on one side, host or virtual machine.

First let’s look at how the USB controllers appears on a Lynx Point chipset using lscpi:
00:14.0 USB controller [0c03]: Intel Corporation 8 Series/C220 Series Chipset Family USB xHCI [8086:8c31] (rev 04)
00:1a.0 USB controller [0c03]: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 [8086:8c2d] (rev 04)
00:1d.0 USB controller [0c03]: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #1 [8086:8c26] (rev 04)

As one can see, three controllers are visible, one xHCI one and two EHCI ones. Let’s now look at how the USB ports are arranged using lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/15p, 480M

explain EHCI/OHCI/XHCI

http://www.intel.com/content/www/us/en/chipsets/8-series-chipset-pch-datasheet.html

the kernel in the VM might move back the devices to the xHCI controller. This is always the case for old kernels (like the 3.2 in Debian Wheezy), but for recent kernel it only happens if there is an intel EHCI controller available (either passed through VFIO or emulated by QEMU).

add table

Add warning

17 March, 2016 04:34PM by aurel32

February 25, 2016

Stéphane Blondon

Des graphiques à la Xkcd

Ou comment faire des graphiques dans le légendaire style de XKCD (une finesse du trait plus tranchante que Michel-Ange, des couleurs plus contrastées que Léonard de Vinci).

graphique à la xkcd

Les développeurs de Matplotlib l’ont fait et intégré à la bibliothèque. Globalement, il suffit d’initialiser le script python avec la fonction xkcd(). Cette fonction initialise des paramètres pour le rendu des graphiques.

with plt.xkcd():
    #le code pour produire le graphique

Installation

Dans Debian, le paquet de base de Matplotlib est python-matplotlib pour python2 et python3-matplotlib pour python3.

Pour que le graphique ait une police similaire à ceux de xkcd, la police Humor Sans doit être installée. Dans Debian, elle se trouve dans le paquet fonts-humor-sans.

Il est possible d’avoir encore une erreur signalant que la police n’est pas trouvée :

/usr/lib/python2.7/dist-packages/matplotlib/font_manager.py:1288: UserWarning: findfont: Font family [u'Humor-Sans'] not found. Falling back to Bitstream Vera Sans

En réalité, elle est bien accessible par matplotlib mais la bibliothèque a construit un cache des polices disponibles lors de la création d’un autre graphique par le passé. Ce cache n’est pas vidé après l’installation de la police. L’erreur survient car matplotlib regarde dans son cache et non les polices actuellement installées sur le système. Il suffit donc de supprimer ce cache (fontList.cache pour python2 ou fontList.py3k.cache pour python3) et d’exécuter à nouveau le script.


stephane@foehn:~$ ls .cache/matplotlib/
fontList.cache fontList.py3k.cache tex.cache
stephane@foehn:~$ rm .cache/matplotlib/fontList.cache #si script lancé avec python2

Et là, ça marche !🙂

Évitez tout de même de mettre des accents, la police ne dispose pas de ces caractères et un « ? » est affiché à la place.

Versions des logiciels utilisés, code source

paquet python-matplotlib : 1.5.1-1
paquet fonts-humor-sans : 1.0-1

Le code source qui a permis de produire le magnifique graphique inséré au début de l’article :

from matplotlib import pyplot as plt
import numpy as np

with plt.xkcd():
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    plt.xticks([])
    plt.yticks([])
    ax.set_ylim([-1, 2])

    x = np.linspace(0, 10)
    plt.plot(x, np.sin(x) + 0.3, '--')

    plt.xlabel('abscisses')
    plt.ylabel('ordonnees')
    plt.title("c'est le plus beau graphique du monde !")

    plt.savefig("/tmp/graph_xkcd.png")

25 February, 2016 10:26PM by ascendances

February 23, 2016

hackergotchi for Aurélien Jarno

Aurélien Jarno

10 years ago…

… I joined the Debian GNU libc team and did my first glibc upload. At that time source-only upload were far from exiting, and I was using a HP 9000 model 715/80 HPPA workstation for my Debian builds.

Still it seems to me like yesterday.

23 February, 2016 09:43PM by aurel32

August 15, 2015

Stéphane Blondon

DebConf15 à Heidelberg

Je suis à la DebConf15 et j’ai des preuves :

club_mate

La photo a été prise dans l’auberge de jeunesse. Le Club-Mate, c’est un peu la baguette des Allemands, avec la bière et la porte de Brandebourg. (La porte est un peu plus difficile à boire.)

Le logo compatible Club-Mate :
Dc15going1


15 August, 2015 05:30PM by ascendances

May 27, 2015

hackergotchi for Vincent Bernat

Vincent Bernat

Correction sans redémarrage de la faille VENOM de QEMU

La faille CVE-2015-3456, aussi connue sous le nom VENOM, exploite une faiblesse dans l’implémentation du contrôleur de disquettes de QEMU:

Le contrôleur de disquettes (FDC) de QEMU, tel qu’utilisé dans Xen […] et dans KVM permet aux systèmes invités de provoquer un déni de service (écriture hors limite suivie du crash du processus invité) ou éventuellement d’exécuter du code arbitraire à travers les commandes FD_CMD_READ_ID, FD_​CMD_​DRIVE_​SPECIFICATION_​COMMAND ou d’autres commandes non spécifiées.

Même lorsque QEMU a été configuré pour ne pas exposer de lecteur de disquettes, le contrôleur est toujours actif. La vulnérabilité est facile à tester1 :

#define FDC_IOPORT 0x3f5
#define FD_CMD_READ_ID 0x0a

int main() {
    ioperm(FDC_IOPORT, 1, 1);
    outb(FD_CMD_READ_ID, FDC_IOPORT);
    for (size_t i = 0;; i++)
        outb(0x42, FDC_IOPORT);
    return 0;
}

Une fois le correctif installé, tous les processus doivent être redémarrés pour que la mise à jour prenne effet. Il est possible de minimiser le temps de coupure en utilisant virsh save.

Une alternative serait de modifier le processus en cours d’exécution. Le noyau Linux a suscité beaucoup d’intérêt dans ce domaine avec des solutions telles que Ksplice, kGraft et kpatch, ainsi que par l’inclusion d’une structure commune dans le noyau. L’espace utilisateur ne dispose cependant pas de solutions aussi élaborées2.

Je présente ici une solution simple et sans dépendance pour corriger une instance de QEMU en cours d’exécution. Voici une courte démonstration :

Prototype§

Essayons d’abord de trouver une modification simple à implémenter : bien qu’il soit possible de modifier du code en cours d’exécution, il est bien plus simple de modifier une variable.

Concept§

En examinant le code du contrôleur de disquettes et le correctif, une façon d’éviter la vulnérabilité est de n’accepter aucune commande sur le port FIFO. Chaque requête aura comme réponse « Invalid command » (0x80). L’utilisateur ne pourra plus pousser aucun octet avant de lire la réponse, ce qui provoquera une remise à zéro de la queue FIFO. Bien sûr, le contrôleur de disquette deviendra alors inopérant.

La liste des commandes acceptées par le contrôleur sur le port FIFO se trouve dans le tableau handlers[] :

static const struct {
    uint8_t value;
    uint8_t mask;
    const char* name;
    int parameters;
    void (*handler)(FDCtrl *fdctrl, int direction);
    int direction;
} handlers[] = {
    { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ },
    { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE },
    /* [...] */
    { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */
};

Pour éviter de parcourir ce tableau pour chaque commande reçue, un autre tableau associe une commande à la fonction adéquate :

/* Associate command to an index in the 'handlers' array */
static uint8_t command_to_handler[256];

static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
{
    int i, j;
    static int command_tables_inited = 0;

    /* Fill 'command_to_handler' lookup table */
    if (!command_tables_inited) {
        command_tables_inited = 1;
        for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
            for (j = 0; j < sizeof(command_to_handler); j++) {
                if ((j & handlers[i].mask) == handlers[i].value) {
                    command_to_handler[j] = i;
                }
            }
        }
    }
    /* [...] */
}

Notre modification consiste à changer le tableau command_to_handler[] pour associer toutes les commandes à la fonction fdctrl_unimplemented() (celle en dernière position dans le tableau handlers[]).

Test avec gdb§

Pour vérifier que cette modification fonctionne correctement, nous la testons avec gdb. À moins d’avoir compilé QEMU manuellement, il est nécessaire d’installer le paquet contenant les symboles de débogage. Malheureusement, chez Debian, ils ne sont pas encore3 disponibles. Chez Ubuntu, il suffit d’installer le paquet qemu-system-x86-dbgsym après avoir activé les dépôts appropriés.

La fonction suivante pour gdb implémente le correctif :

define patch
  set $handler = sizeof(handlers)/sizeof(*handlers)-1
  set $i = 0
  while ($i < 256)
   set variable command_to_handler[$i++] = $handler
  end
  printf "Done!\n"
end

Il suffit alors de s’attacher au processus vulnérable (avec attach), d’appeler cette fonction (avec patch) et de se détacher (avec detach). Cette procédure est simple à automatiser.

Limitations§

L’usage de gdb comporte principalement deux limitations :

  1. gdb doit être installé sur toutes les machines à corriger.
  2. Les paquets de débogage doivent également être présents. Il est de plus difficile de récupérer d’anciennes versions de ceux-ci.

Industrialisation§

Pour contourner ces limitations, nous allons écrire un programme utilisant l’appel système ptrace() et qui ne nécessite pas les symboles de débogage pour fonctionner.

Trouver l’emplacement mémoire§

La première étape est de localiser le tableau command_to_handler[] en mémoire. Le premier indice se trouve dans la table des symboles que l’on peut interroger avec readelf -s :

$ readelf -s /usr/lib/debug/.build-id/09/95121eb46e2a4c13747ac2bad982829365c694.debug | \
>   sed -n -e 1,3p -e /command_to_handler/p

Symbol table '.symtab' contains 27066 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
  8485: 00000000009f9d00   256 OBJECT  LOCAL  DEFAULT   26 command_to_handler

Habituellement, cette table a été retirée pour économiser de l’espace disque, comme on peut le voir ci-dessous :

$ file -b /usr/bin/qemu-system-x86_64 | tr , \\n
ELF 64-bit LSB shared object
 x86-64
 version 1 (SYSV)
 dynamically linked
 interpreter /lib64/ld-linux-x86-64.so.2
 for GNU/Linux 2.6.32
 BuildID[sha1]=0995121eb46e2a4c13747ac2bad982829365c694
 stripped

Si votre distribution fournit un paquet de débogage, les symboles sont alors installés dans le répertoire /usr/lib/debug. La plupart des distributions modernes utilisent désormais le build ID4 pour lier un exécutable à ses symboles de débogage, comme c’est le cas dans l’exemple ci-dessus. Sans paquet de débogage, il est nécessaire de recompiler le paquet dans un environnement minimal5 sans supprimer les symboles. Sur Debian, cela peut se faire en affectant nostrip à la variable d’environnement DEB_BUILD_OPTIONS.

Il y a ensuite deux cas possibles :

  • le cas facile,
  • le cas difficile.

Le cas facile§

Sur x86, la mémoire d’un processus Linux normal est organisée comme ceci6 :

Organisation mémoire d'un processus normal sur x86

L’espace aléatoire introduit entre les différentes zones (ASLR) permettent de rendre la tâche d’un attaquant plus difficile quand il veut référencer une fonction particulière. Sur x86-64, l’organisation est similaire. Le point important est que l’adresse de base de l’exécutable est fixe.

L’organisation mémoire d’un processus peut être consultée à travers le fichier /proc/PID/maps. Voici une version raccourcie et annotée sur x86-64 :

$ cat /proc/3609/maps
00400000-00401000         r-xp 00000000 fd:04 483  not-qemu [text segment]
00601000-00602000         r--p 00001000 fd:04 483  not-qemu [data segment]
00602000-00603000         rw-p 00002000 fd:04 483  not-qemu [BSS segment]
[random gap]
02419000-0293d000         rw-p 00000000 00:00 0    [heap]
[random gap]
7f0835543000-7f08356e2000 r-xp 00000000 fd:01 9319 /lib/x86_64-linux-gnu/libc-2.19.so
7f08356e2000-7f08358e2000 ---p 0019f000 fd:01 9319 /lib/x86_64-linux-gnu/libc-2.19.so
7f08358e2000-7f08358e6000 r--p 0019f000 fd:01 9319 /lib/x86_64-linux-gnu/libc-2.19.so
7f08358e6000-7f08358e8000 rw-p 001a3000 fd:01 9319 /lib/x86_64-linux-gnu/libc-2.19.so
7f08358e8000-7f08358ec000 rw-p 00000000 00:00 0
7f08358ec000-7f083590c000 r-xp 00000000 fd:01 5138 /lib/x86_64-linux-gnu/ld-2.19.so
7f0835aca000-7f0835acd000 rw-p 00000000 00:00 0
7f0835b08000-7f0835b0c000 rw-p 00000000 00:00 0
7f0835b0c000-7f0835b0d000 r--p 00020000 fd:01 5138 /lib/x86_64-linux-gnu/ld-2.19.so
7f0835b0d000-7f0835b0e000 rw-p 00021000 fd:01 5138 /lib/x86_64-linux-gnu/ld-2.19.so
7f0835b0e000-7f0835b0f000 rw-p 00000000 00:00 0
[random gap]
7ffdb0f85000-7ffdb0fa6000 rw-p 00000000 00:00 0    [stack]

Dans le cas d’un exécutable normal, le nombre fourni dans la table des symboles est une adresse absolue :

$ readelf -s not-qemu | \
>   sed -n -e 1,3p -e /command_to_handler/p

Symbol table '.dynsym' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
    47: 0000000000602080   256 OBJECT  LOCAL  DEFAULT   25 command_to_handler

Ainsi, dans l’exemple ci-dessus, l’adresse du tableau command_to_​handler[], est simplement 0x602080.

Le cas difficile§

Pour améliorer la sécurité, il est possible de placer certains exécutables à un emplacement aléatoire en mémoire, comme c’est le cas pour une bibliothèque. Un tel exécutable est appelé un Position Independent Executable (PIE). Un attaquant ne pourra pas se baser sur une adresse fixe pour rebondir sur une fonction particulière. Voici à quoi ressemble l’organisation mémoire d’un processus dans ce cas :

Organisation mémoire d'un processus PIE sur x86

Dans le cas d’un processus PIE, le nombre indiqué dans la table des symboles est relatif à l’adresse de base du processus.

$ readelf -s not-qemu-pie | sed -n -e 1,3p -e /command_to_handler/p

Symbol table '.dynsym' contains 17 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
    47: 0000000000202080   256 OBJECT  LOCAL  DEFAULT   25 command_to_handler

En regardant le contenu de /proc/PID/maps, il est possible de calculer l’emplacement mémoire du tableau :

$ cat /proc/12593/maps
7f6c13565000-7f6c13704000 r-xp 00000000 fd:01 9319  /lib/x86_64-linux-gnu/libc-2.19.so
7f6c13704000-7f6c13904000 ---p 0019f000 fd:01 9319  /lib/x86_64-linux-gnu/libc-2.19.so
7f6c13904000-7f6c13908000 r--p 0019f000 fd:01 9319  /lib/x86_64-linux-gnu/libc-2.19.so
7f6c13908000-7f6c1390a000 rw-p 001a3000 fd:01 9319  /lib/x86_64-linux-gnu/libc-2.19.so
7f6c1390a000-7f6c1390e000 rw-p 00000000 00:00 0
7f6c1390e000-7f6c1392e000 r-xp 00000000 fd:01 5138  /lib/x86_64-linux-gnu/ld-2.19.so
7f6c13b2e000-7f6c13b2f000 r--p 00020000 fd:01 5138  /lib/x86_64-linux-gnu/ld-2.19.so
7f6c13b2f000-7f6c13b30000 rw-p 00021000 fd:01 5138  /lib/x86_64-linux-gnu/ld-2.19.so
7f6c13b30000-7f6c13b31000 rw-p 00000000 00:00 0
7f6c13b31000-7f6c13b33000 r-xp 00000000 fd:04 4594  not-qemu-pie [text segment]
7f6c13cf0000-7f6c13cf3000 rw-p 00000000 00:00 0
7f6c13d2e000-7f6c13d32000 rw-p 00000000 00:00 0
7f6c13d32000-7f6c13d33000 r--p 00001000 fd:04 4594  not-qemu-pie [data segment]
7f6c13d33000-7f6c13d34000 rw-p 00002000 fd:04 4594  not-qemu-pie [BSS segment]
[random gap]
7f6c15c46000-7f6c15c67000 rw-p 00000000 00:00 0     [heap]
[random gap]
7ffe823b0000-7ffe823d1000 rw-p 00000000 00:00 0     [stack]

L’adresse de base est 0x7f6c13b31000, le décalage relatif est 0x202080 et donc le tableau se trouve à l’adresse mémoire 0x7f6c13d33080. Il est possible de vérifier cette valeur avec gdb : with gdb:

$ print &command_to_handler
$1 = (uint8_t (*)[256]) 0x7f6c13d33080 <command_to_handler>

Modifier un emplacement mémoire§

Une fois l’emplacement du tableau command_to_handler[] connu, le modifier est relativement simple. Il convient d’abord de s’attacher au processus cible :

/* Attach to the running process */
static int
patch_attach(pid_t pid)
{
    int status;

    printf("[.] Attaching to PID %d...\n", pid);
    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
        fprintf(stderr, "[!] Unable to attach to PID %d: %m\n", pid);
        return -1;
    }

    if (waitpid(pid, &status, 0) == -1) {
        fprintf(stderr, "[!] Error while attaching to PID %d: %m\n", pid);
        return -1;
    }
    assert(WIFSTOPPED(status)); /* Tracee may have died */

    if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si) == -1) {
        fprintf(stderr, "[!] Unable to read siginfo for PID %d: %m\n", pid);
        return -1;
    }
    assert(si.si_signo == SIGSTOP); /* Other signals may have been received */

    printf("[*] Successfully attached to PID %d\n", pid);
    return 0;
}

Ensuite, récupérons le tableau command_to_handler[], modifions le et réécrivons le en mémoire7.

static int
patch_doit(pid_t pid, unsigned char *target)
{
    int ret = -1;
    unsigned char *command_to_handler = NULL;
    size_t i;

    /* Get the table */
    printf("[.] Retrieving command_to_handler table...\n");
    command_to_handler = ptrace_read(pid,
                                     target,
                                     QEMU_COMMAND_TO_HANDLER_SIZE);
    if (command_to_handler == NULL) {
        fprintf(stderr, "[!] Unable to read command_to_handler table: %m\n");
        goto out;
    }

    /* Check if the table has already been patched. */
    /* [...] */

    /* Patch it */
    printf("[.] Patching QEMU...\n");
    for (i = 0; i < QEMU_COMMAND_TO_HANDLER_SIZE; i++) {
        command_to_handler[i] = QEMU_NOT_IMPLEMENTED_HANDLER;
    }
    if (ptrace_write(pid, target, command_to_handler,
           QEMU_COMMAND_TO_HANDLER_SIZE) == -1) {
        fprintf(stderr, "[!] Unable to patch command_to_handler table: %m\n");
        goto out;
    }
    printf("[*] QEMU successfully patched!\n");
    ret = 0;

out:
    free(command_to_handler);
    return ret;
}

Comme ptrace() ne permet de lire et d’écrire qu’un mot à la fois, ptrace_read() et ptrace_write() sont des enrobages pour lire et écrire une quantité arbitraire de mémoire. Voici par exemple le code de ptrace_read() :

/* Read memory of the given process */
static void *
ptrace_read(pid_t pid, void *address, size_t size)
{
    /* Allocate the buffer */
    uword_t *buffer = malloc((size/sizeof(uword_t) + 1)*sizeof(uword_t));
    if (!buffer) return NULL;

    /* Read word by word */
    size_t readsz = 0;
    do {
        errno = 0;
        if ((buffer[readsz/sizeof(uword_t)] =
                ptrace(PTRACE_PEEKTEXT, pid,
                       (unsigned char*)address + readsz,
                       0)) && errno) {
            fprintf(stderr, "[!] Unable to peek one word at address %p: %m\n",
                    (unsigned char *)address + readsz);
            free(buffer);
            return NULL;
        }
        readsz += sizeof(uword_t);
    } while (readsz < size);
    return (unsigned char *)buffer;
}

Assembler les morceaux§

Le programme prend en paramètre :

  • le PID du processus à modifier,
  • le décalage issu de la table des symboles pour le tableau command_to_handler[],
  • le build ID de l’exécutable utilisé pour obtenir ce décalage (à des fins de sécurité).

Les principales étapes sont alors les suivantes :

  1. S’Attacher au processus avec ptrace().
  2. Obtenir le nom de l’exécutable depuis /proc/PID/exe.
  3. Lire le fichier /proc/PID/maps afin de trouver l’adresse de base.
  4. Effectuer certaines vérifications supplémentaires:
    • vérifier qu’il y a bien un entête ELF à l’adresse de base (via quatre octets magiques),
    • vérifier le type de l’exécutable (ET_EXEC pour les exécutables normaux, ET_DYN pour les PIE),
    • récupérer et comparer le build ID avec celui attendu.
  5. À partir de l’adresse de base et du décalage fourni, calculer l’emplacement du tableau command_to_handler[].
  6. Modifier le tableau.

Les sources du programme sont disponibles sur GitHub.

$ ./patch --build-id 0995121eb46e2a4c13747ac2bad982829365c694 \
>         --offset 9f9d00 \
>         --pid 16833
[.] Attaching to PID 16833...
[*] Successfully attached to PID 16833
[*] Executable name is /usr/bin/qemu-system-x86_64
[*] Base address is 0x7f7eea912000
[*] Both build IDs match
[.] Retrieving command_to_handler table...
[.] Patching QEMU...
[*] QEMU successfully patched!

  1. Le code complet pour ce test est disponible sur GitHub

  2. Un projet qui semble intéressant est Katana. Mais il existe aussi un quelques papiers perspicaces sur le sujet. 

  3. Certains paquets fournissent également un paquet -dbg contenant les symboles de débogage. D’autres non. Une initiative pour produire automatiquement des paquets de débogage est actuellement en cours. 

  4. Le wiki de Fedora explique les raisons derrière cette décision

  5. Si la construction ne se fait pas à l’identique du paquet original, les build ID seront différents. L’information fournie par les symboles de débogage peut alors être ou non correcte. Une initiative pour s’assurer de la reproductabilité de la construction de tous les paquets est en cours. 

  6. « Anatomy of a program in memory » explique plus en détail cette organisation. 

  7. En étant une variable statique non initialisée, la variable se situe dans la section BSS qui se retrouve accessible en écriture en mémoire. Si ce n’était pas le cas, sous Linux, l’appel système ptrace() permet tout de même d’écrire dessus. Linux va copier la page correspondante et la marquer comme privée. 

27 May, 2015 03:52PM by Vincent Bernat

May 19, 2015

Olivier Berger (pro)

Présentation du projet Debian par Nicolas Dandrimont lors de la Debian release party de Jessie

Nicolas (olasd) Dandrimont est venu présenter le projet Debian à Télécom SudParis lundi 18 mai 2015, pour la petite fête de sortie de la version majeure “Jessie” que nous avions organisé avec MiNET.

Les transparents de Nicolas sont disponibles sur son site.

Updated : Voici l’enregistrement de la conférence sur YouTube :

Merci aux membres de MiNET qui ont joyeusement participé à cette petite fête.

Voici quelques photos :




Vous pouvez aussi revisionner l’enregistrement de la conférence de Stefano il y a 4 ans.

19 May, 2015 02:52PM by Olivier Berger

May 13, 2015

Avec MiNET, première Debian release party française de Jessie le 18 mai à Télécom SudParis

Vous étiez frustrés de ne pas pouvoir fêter Jessie en France dignement ?

On a pensé à vous, avec MiNET.

Le 18 mai entre 17h et 18h30, nous fêterons ça à Évry (Essonne) à Télécom SudParis, avec la participation de Nicolas Dandrimont en guest star, pour présenter le projet.

Attention, inscription gratuite par avance en contactant les organisateurs, compte-tenu des contraintes de sécurité pour l’accès au site (vigipirate).

Plus de détails sur : https://wiki.debian.org/ReleasePartyJessie/France/Évry

13 May, 2015 01:23PM by Olivier Berger

May 03, 2015

Stéphane Blondon

Colorer une sortie dans un terminal : highlight, pygmentize et ccze

highlight et pygmentize servent à colorer du code source, ccze à colorer des logs.

Affichage de la sortie de cat, highlight et pygmentize

Pour utiliser ces outils, voici les paquets à installer sur une distribution Debian ou dérivée :

commande paquet
highlight highlight
pygmentize python-pygments ou python3-pygments
ccze ccze

highlight et pygmentize

De nombreux langages disponibles

La liste des langages disponibles pour les deux outils est longue comme un jour sans compilation :
highlight colore 159 langages selon sa documentation.
pygmentize en colore 235 d’après un grep Lexer$ sur le texte de la page listant les lexeurs disponibles.

Plutôt que de tous les lister, voici un comparatif sur les 20 langages ayant le plus de lignes de code dans Jessie (la nouvelle version stable de Debian).

  1. C : les deux
  2. C++ : les deux
  3. Java : les deux
  4. XML : les deux
  5. sh : les deux
  6. Python : les deux. pygmentize a plusieurs lexeurs (python 2, python3, sortie console et la pile d’erreurs).
  7. Perl : les deux
  8. Lisp : les deux
  9. Asm : les deux. highlight colore aussi l’assembleur PowerPC.
  10. Fortran : highlight traite spécifiquement fortran77, pas pygmentize (qui gère la version 90).
  11. C# : les deux
  12. PHP : les deux
  13. Fortran90 : les deux
  14. Pascal : les deux. pygmentize nécessite d’utiliser Delphi lexer, avec option spécifique.
  15. Makefile : highlight (make, QMake), pygmentize (Makefile, CMake)
  16. Ruby : les deux. pygmentize colore le langage mais aussi la sortie console.
  17. SQL : highlight (MSSQL, SPIN SQL, PL/SQL, Sybase), pygmentize (MySQL, PgSQL, PL/PgSQL, console Postgres, SQL, console Sqlite)
  18. ML : les deux (Standard ML ainsi qu’Ocaml)
  19. Tcl : les deux

À cette liste, voici le comparatif sur les 20 premiers langages selon l’indice TIOBE en mars 2015 (sans juger de l’intérêt profond du classement en lui-même, ou son absence) :

  1. C : cf. liste précédente
  2. Java : cf. liste précédente
  3. Objective-C : les deux
  4. C++ : cf. liste précédente
  5. C# : cf. liste précédente
  6. PHP : cf. liste précédente
  7. JavaScript : les deux
  8. Python : cf. liste précédente
  9. Visual Basic .NET : ? (je ne connais pas les environnements Microsoft donc j’ai tout mis à la ligne suivante)
  10. Visual Basic : highlight colore les fichiers avec les extensions de fichiers .bas, .basic, .bi et .vbs. pygmentize colore ceux en .vb et .bas.
  11. F# : les deux
  12. Perl : cf. liste précédente
  13. Delphi/Object Pascal : pyg
  14. Transact-SQL : aucun des deux
  15. Pascal : cf. liste précédente
  16. ABAP : les deux
  17. PL/SQL : highlight uniquement
  18. Ruby : cf. liste précédente
  19. MATLAB : les deux. pygmentize colore le langage et la sortie console.
  20. R : les deux. pygmentize colore le langage (avec SLexer, ce n’est pas intuitif), la sortie console et la documentation.

pygmentize et highlight permettent la coloration syntaxique de nombreux autres langages comme Applescript, Awk, Bbcode, Clojure, Haxe, Lua et bien d’autres.

Les fichiers de configuration d’Apache sont colorés par les deux outils. pygmentize colore aussi la configuration de Lighttpd et Nginx mais aussi d’autres fichiers de configuration comme Docker ou CFEngine.

Contrairement à highlight, pygmentize permet aussi de colorer des logs IRC, les fichiers CMake ou du code spécifique aux moteurs de template (django, smarty, mako, genshi, erb).

hightlight colore COBOL ou graphviz, pas pygmentize.

Facile à utiliser

Les deux outils sont triviaux à installer. L’usage est facile aussi car ils déterminent le lexeur à utiliser en fonction de l’extension du fichier. Il est possible de forcer l’utilisation d’un lexeur (utile si les données viennent d’un pipe par exemple).

Par contre (et par défaut), highlight sort la coloration en html et non pour la console. Ce qui oblige à préciser la sortie terminal souhaitée. Il y en a deux possibles : ansi (16 couleurs) et term256 (256 couleurs). Ansi serait-il à réserver aux plus nostalgiques ? Ce choix cornélien s’impose aussi avec pygmentize (sortie par défaut contre console256).
Dans les faits, les différences ont peu d’intérêt.

highlight et pygmentize, période ansi et période 256 couleurs

Colorer de nouveaux langages

Les deux outils permettent d’ajouter de nouveaux lexeurs :
– en Lua pour highlight
– en Python pour pygmentize (qui est lui-même écrit en Python)

Autres usages

highlight et pygmentize permettent d’avoir d’autres sorties :

sorties highlight pygmentize
HTML oui oui
XHTML oui non
SVG oui oui
RTF oui oui
ODT oui non
Images bitmap non oui (bmp, gif, jpeg et png)

highlight est compatible avec source-highlight du projet GNU (outil que je n’ai jamais testé).

Que choisir ?

Si vous avez besoin d’un langage qui est disponible que sur l’un des deux outils, choisissez celui-là.
Si vous comptez écrire des greffons pour ajouter des langages, choisissez si vous préférez écrire en Lua ou en Python.
Si les deux règles précédentes ne permettent pas d’emporter la décision, je conseillerai plutôt pygmentize qui a plus de langages et qui gère des trucs plus récents (les moteurs de template par exemple). Évidemment, si c’est pour maintenir du code COBOL sur une base logicielle de 15 ans d’âge, ça ne sera pas très déterminant non plus…

ccze

ccze n’est pas concurrent des deux outils précédents car il colore des journaux, pas du code.

Affichage de la sortie de cat et ccze

Les remarques et usages de http://www.quennec.fr/gnulinux/utilisation/afficher-les-logs-en-couleur sur ccze sont valides. Cependant j’ai dû activer le mode ansi (avec -A ou --raw-ansi ou bien -m ansi ou encore --mode ansi) lors de mes tests, sinon il n’y avait aucune sortie dans le terminal.

Les journaux d’Apache, Exim, Postfix, syslog sont colorés par ccze. Pour la liste complète, man ccze.

Il est aussi possible d’ajouter de nouveaux type de journaux. Par contre, il faudra les écrire en C (cf. man ccze-plugin).

Fin : références, versions des logiciels

Les statistiques Debian concernant les langages sont issues de http://sources.debian.net/stats/. Pour en savoir plus, voir aussi http://sources.debian.net/doc/ (en particulier « Debsources: Live and Historical Views on Macro-Level »).

La page des lexers de pygmentize est /usr/share/doc/python-pygments-doc/html/docs/lexers.html sur Jessie (en supposant que python-pygments-doc est installé). L’emplacement était /usr/share/doc/python-pygments/lexers.html sur Wheezy (la version stable précédente) et était directement incluse dans le paquet python-pygments.

Les versions utilisées pour l’article :

stephane@foehn:~$ pygmentize -V
Pygments version 2.0.1, (c) 2006-2014 by Georg Brandl.
stephane@foehn:~$ highlight --version

 highlight version 3.18
 Copyright (C) 2002-2013 Andre Simon <andre.simon1 at gmx.de>

 Argparser class
 Copyright (C) 2006-2008 Antonio Diaz Diaz <ant_diaz at teleline.es>

 Artistic Style Classes (2.04)
 Copyright (C) 2006-2013 by Jim Pattee <jimp03 at email.com>
 Copyright (C) 1998-2002 by Tal Davidson

 Diluculum Lua wrapper (1.0)
 Copyright (C) 2005-2013 by Leandro Motta Barros

 xterm 256 color matching functions
 Copyright (C) 2006 Wolfgang Frisch <wf at frexx.de>

 This software is released under the terms of the GNU General Public License.
 For more information about these matters, see the file named COPYING.

stephane@foehn:~$ ccze --version
ccze 0.2.1

03 May, 2015 11:25AM by ascendances

April 15, 2015

Olivier Berger (pro)

Appel pour une “Linked Research” (recherche reliée), traduit en français

J’ai traduit en français les transparents de l’appel pour une “Linked Research” (que j’ai traduit par “recherche reliée”) de Sarven Capadisli originellement en anglais

L’objectif est d’inciter (entre autre actions) à la publication d’articles académiques sous une forme exploitable aussi bien par les humains que par les machines, et permettant ainsi d’embarquer dans le document des méta-données additionnelles.

Plus de détails dans les transparents ici : http://www-public.tem-tsp.eu/~berger_o/presentations-call-for-linked-research-fr/

15 April, 2015 11:51AM by Olivier Berger

April 11, 2015

hackergotchi for Roland Mas

Roland Mas

Le marronnier du printemps

Eh ben eh ben eh ben. C'est bien calme ici, alors que j'aurais des tas de choses à dire… Je pourrais vous parler de Chacun sa part, qui continue de vivre sa vie et de croître doucement. Je pourrais vous parler de rock et de batterie. Je pourrais vous parler d'un truc rigolo que j'ai fait et qui mélange Gnucash, Boobank, Python, crm114 et Libre Office Calc. Ou de FusionForge. Ou de moto, de Montpellier, de soleil. Je pourrais vous parler de plein de choses, mais il se trouve que je passe mon temps à faire ces choses plutôt qu'à en parler sur mon blog, tout magnifique soit-il. Donc je me contenterai du marronnier habituel, qui porte cette année le numéro 38.

Et qui le porte bien, merci.

11 April, 2015 05:30PM

April 01, 2015

hackergotchi for Debian France

Debian France

Debian France a un nouveau Président

Suite à l'Assemblée Générale Ordinaire tenue le mois dernier, le Conseil d'Administration de Debian France a élu un nouveau Président: bienvenue à Nicolas Dandrimont (alias olasd) !

Le président précédent, Raphaël Hertzog, reste dans le Conseil d'Administration pour assurer la transition. Sylvestre Ledru reste trésorier et Julien Cristau est reconduit pour un nouveau mandat au Conseil d'Administration. Julien Danjou quitte l'équipe après plusieurs années de bons et loyaux services.

Un grand merci à tous les candidats au Conseil d'Administration, nous comptons sur eux pour aussi dynamiser l'association dans les années à venir: - François-Régis Vuillemin - Michel Barret - Sébatien Poher

01 April, 2015 04:14PM

January 23, 2015

Présentation du projet Debian aux Expériences Numériques

Expériences Numériques

Les EPN de la Maison pour Tous Salle des Rancy en collaboration avec l'Aadn, Aldil, Ubunteros de Lyon, Illyse organisent le 31 janvier 2015 : les Expériences Numeriques.

Ce rendez-vous est une journée de découverte, d’initiation et de rencontres autour des pratiques du numérique.

À cette occasion une conférence aura lieu à 16h pour présenter le projet Debian. Pendant cette journée une install party sera organisée où les personnes qui le désirent pourront installer notre distribution favorite.

Télécharger le programme.

Carte Openstreet Map. Voir aussi le plan d'accès officiel pour plus de détails.

logo Maison pour Tous Salle des Rancy

23 January, 2015 03:12PM

December 23, 2014

hackergotchi for Vincent Bernat

Vincent Bernat

Eudyptula Challenge : démarrage rapide d'un noyau Linux

Le challenge Eudyptula est une série d’exercices de programmation pour le noyau Linux. Il commence avec le très basique module « Hello world » puis progresse en complexité jusqu’à faire pousser des modifications dans l’arbre du noyau Linux.

Une des premières tâches de ce challenge est de compiler puis démarrer son propre noyau. eudyptula-boot est un script autonome permettant de démarrer une image noyau jusqu’à obtenir un shell. Il est livré avec les fonctionnalités suivantes :

  • Il permet de booter quasiment n’importe quel noyau Linux, du noyau fourni par votre distribution favorite jusqu’au noyau personnalisé1 pour travailler sur une fonctionnalité quelconque.

  • Il utilise le système de fichiers de l’hôte comme racine pour le système invité. Aucune image disque n’est donc nécessaire. Ces dernières prennent beaucoup de place, doivent être maintenues à jour, se retrouvent encombrées au fil du temps et les outils dont vous avez besoin ne sont jamais installés. Pour éviter toute modification accidentelle, le système de fichiers est par défaut monté en lecture seule. S’ils sont disponibles, OverlayFS ou aufs sont utilisés pour ajouter une couche accessible en écriture. Il est de plus possible d’utiliser n’importe quel répertoire comme racine.

  • Le répertoire utilisateur est également accessible. Il est ainsi simple de partager des scripts et des programmes avec le système hôte.

  • Il démarre un système minimal avec le strict nécessaire2 pour démarrer un shell dans de bonnes conditions. Le système est opérationnel en moins de cinq secondes.

Dans la vidéo ci-dessous, eudyptula-boot est utilisé pour démarrer le noyau de l’hôte et exécuter quelques commandes :

Dans la vidéo suivante, nous démarrons un noyau personnalisé contenant un appel système supplémentaire. Il s’agit de la tâche n°15 du challenge Eudyptula. Un programme de test permet de vérifier le bon fonctionnement de l’appel système. Vers la fin, la vidéo contient également une rapide démonstration de gdb.

Bien que ce hack permette également de lancer des conteneurs3 avec une isolation accrue, les performances de 9p sont malheureusement peu convaincantes pour un tel usage.

vido est un projet similaire.


  1. Il est toutefois nécessaire d’activer le support de 9p virtio. Il suffit pour cela d’utiliser make kvmconfig

  2. Seul udev est démarré. 

  3. Un point de départ pour une telle utilisation est de combiner les options --root, --force et --exec. Ajoutez également --readwrite pour conserver les modifications. 

23 December, 2014 12:46PM by Vincent Bernat

December 22, 2014

hackergotchi for Debian France

Debian France

Dons Debian France

Dons Debian France

En cette fin d'année, nous tenons à rappeler que l'association Debian France est reconnue d'intérêt général. Ainsi, les donations à destination de l'association peuvent être déduites des impôts.

Une fois la donation réalisée, pour obtenir un reçu, il suffit d'envoyer un mail au trésorier - <tresorier@france.debian.net> en indiquant votre adresse.

Formulaire de donation

22 December, 2014 04:47PM

December 10, 2014

Olivier Berger (perso)

Réparé les hauts-parleurs d'un portable HP dv6000 en échangeant deux nappes internes

Les hauts-parleurs internes du portable HP de mes parents, un dv6000, ne marchaient plus : plus de son sans devoir mettre des enceintes ou un casque :-(

En fait, il semble que ce soit un problème classique, qui semble causé par des nappes de connexion internes deffectueuses.

La réparation n'est pas trop compliquée, si on achète une nappe de remplacement, mais on peut aussi trouver un contournement.

J'ai réussi à échanger les deux nappes qui connectent la carte mère à la partie qui contient les boutons et les hauts-parleurs, au dessus du clavier, et même si maintenant, les boutons de cette rangée supérieure ne marchent plus, ce n'est pas trop grave, car le son est revenu.

Pour voir une vidéo (en anglais) qui explique comment faire, voir : Hp Pavilion Dv6000 power button and speaker fix!

Content d'avoir récupéré le son :-)

10 December, 2014 10:10PM by obergix

December 09, 2014

hackergotchi for Debian France

Debian France

Debian France au Capitole du Libre

Debian France au Capitole du Libre

Le samedi 15 novembre, l'association Debian France a tenu un stand au Capitole du Libre, l'événement du Libre à Toulouse. Ceci a permis de créer un certain nombre de contacts prometteurs, et de confirmer que Debian est une référence reconnue pour ses valeurs. Nous remercions l'association Toulibre pour son accueil et son très bel événement!

09 December, 2014 04:06PM

September 24, 2014

Debian France reconnu comme Debian Trusted Organization

Debian France reconnu comme Debian Trusted Organization

Grâce à la refonte des statuts de l'association, Debian France est maintenant reconnue officiellement comme étant une Trusted Organization. Ainsi, l'association Debian France est habilitée à recevoir des fonds au nom de Debian et procéder à des dépenses pour le projet.

L'annonce a été réalisée par Lucas Nussbaum, Debian Project Leader.

24 September, 2014 07:14AM

September 12, 2014

Stéphane Blondon

Key Signing Assistant (concept)

Dans les allées de la DebConf14, j’ai discuté avec Franklin de l’intérêt pour un développeur d’utiliser son téléphone portable lors d’une key signing party.

Les schémas sont un brouillon d’une utilisation possible du téléphone. L’objectif n’est pas de remplacer la rencontre réelle ou la validation mais juste d’aider à l’échange et validation des clefs.

Actuellement, ce n’est qu’un concept ; rien n’est implémenté.

Le principe général est d’utiliser le téléphone comme un terminal pour l’échange et la validation. Les données partent et reviennent sur la station de travail du développeur par l’intermédiaire d’un serveur web.

  • Le téléphone portable considéré doit être un smartphone ;
  • La seule autorisation à donner pour le téléphone est l’accès à internet ;
  • On considère que les échanges réseau sont fait en https. Je ne pense pas que ce soit indispensable mais il n’y a aucune raison de s’en priver.

Avant la key signing party

Le développeur dispose d’un téléphone sur lequel l’application est installée.
Le processus pour installer ses propres informations est le suivant :

Avant la key signing party

Pendant la key signing party

Le processus est à reproduire pour chaque participant.

Pendant la key signing party

Après la key signing party

Une fois rentré chez lui, le développeur récupère l’ensemble de ses validations sur sa machine de travail :

Après la key signing party

Qu’en pensez-vous ?

Source des schémas

Schémas réalisés avec Inkscape, à partir d’icônes Tango et Gnome-Tango.
Les fichiers svg et png sont disponibles dans le répertoire http://stephane.yaal.fr/ksa/.


12 September, 2014 07:18AM by ascendances

September 10, 2014

Olivier Berger (pro)

Le MOOC Bases de données relationnelles est lancé

Nous venons de lancer la première édition du MOOC sur les bases de données relationnelles de Télécom SudParis. Au programme, de la théorie (algèbre relationnelle), de la pratique (dans SQLite dans les navigateurs basés sur WebKit, et plus tard dans PostgreSQL dans une box Vagrant basée sur Debian (voir post précédent)), des contenus et logiciels libres (autant que possible) et pas mal de rush pour finaliser tout ça dans le Moodle.

On débute avec plus de 800 inscrits à la fin du premier jour (y compris les 180 étudiants ingénieurs de 2ème année de Télécom SudParis, qui suivront le cours présentiel en parallèle du MOOC, et collaboreront avec les apprenants externes pour les travaux personnels).

Il est toujours possible de s’inscrire : le gros du travail commence en semaine 2 (qui commence lundi 15/09 à 00h00 heure de Paris).

10 September, 2014 07:53PM by Olivier Berger

August 20, 2014

hackergotchi for Aurélien Jarno

Aurélien Jarno

MIPS Creator CI20

I have received two MIPS Creator CI20 boards, thanks to Imagination Technologies. It’s a small MIPS32 development board:

mips-ci20

As you can see it comes in a nice packaging with a world-compatible power adapter. It uses a Ingenic JZ4780 SoC with a dual core MIPS32 CPU running at 1.2GHz with a PowerVR SGX540 GPU. The board is fitted with 1GB of RAM, 8GB of NOR flash, HDMI output, USB 2.0 ports, Ethernet + Wi-Fi + BlueTooth, SD card slot, IR receiver, expansion headers and more. The schematics are available. The Linux kernel and the U-Boot bootloader sources are also available.

Powering this board with a USB keyboard, a USB mouse and a HDMI display, it boots off the internal flash on a Debian Wheezy up to the XFCE environment. Besides the kernel, the Wi-Fi + Bluetooth firmware, and very few configuration changes, it runs a vanilla Debian. Unfortunately I haven’t found time to play more with it yet, but it looks already quite promising.

The board has not been formally announced yet, so I do not know when it will become available, nor the price, but if you are interested I’ll bring it to DebConf14. Don’t hesitate to ask me if you want to look at it or play with it.

20 August, 2014 08:52PM by aurel32

Olivier Berger (pro)

Building a lab VM based on Debian for a MOOC, using Vagrant + VirtualBox

We’ve been busy setting up a Virtual Machine (VM) image to be used by participants of a MOOC that’s opening in early september on Relational Databases at Telecom SudParis.

We’ve chosen to use Vagrant and VirtualBox which are used to build, distribute and run the box, providing scriptability (reproducibility) and making it portable on most operating systems.

The VM itself contains a Debian (jessie) minimal system which runs (in the background) PostgreSQL, Apache + mod_php, phpPgAdmin, and a few applications of our own to play with example databases already populated in PostgreSQL.

As the MOOC’s language will be french, we expect the box to be used mostly on machines with azerty keyboards. This and other context elements led us to add some customizations (locale, APT mirror) in provisioning scripts run during the box creation.

At the moment, we generate 2 variants of the box, one for 32 bits kernel (i686) and one for 64 bits kernel (amd64) which (once compressed) represent betw. 300 and 350 Mb.

The resulting boxes are uploaded to a self-hosting site, and distributed through vagrantcloud. Once the VM are created in VirtualBox, the typical VMDK drives file is around 1.3Gb.

We use our own Debian base boxes containing a minimal Debian jessie/testing, instead of relying on someone else’s, and recreate them using (the development branch version of) bootsrap-vz. This ensure we can put more trust in the content as it’s a native Debian package installation without MITM intervention.

The VM are meant to be run headless for the moment, keeping their size to the minimum, even though we also provide a script to install and configure a desktop environment based on XFCE4.

The applications are either used through vagrant ssh, for instance for SQL command-line in psql, or in the Web browser, for our own Web based SQL exerciser, or phpPgAdmin (see a demo screencast (in french, w/ english subtitles)), which can then be used even off-line by the participants, which also means this requires no servers availability for our IT staff.

The MOOC includes a section on PHP + SQL programming, whose exercises can be performed using a shared sub-folder of /vagrant/ which allows editing on the host with the favourite native editor/IDE, while running PHP inside the VM’s Apache + mod_php.

The sources of our environment are available as free software, if you’re interested to replicate a similar environment for another project.

As we’re still polishing the environment before the MOOC opening (on september 10th), I’m not mentioning the box URLs but they shouldn’t be too hard to find if you’re investigating (refering to the fusionforge project’s web site).

We don’t know yet how suitable this environment will be for learning SQL and database design and programming, and if Vagrant will bring more difficulties than benefits. Still we hope that the participants will find this practical, allowing them to work on the lab / exercises whenever and wherever they chose, removing the pain of installing and configuring a RDBMS on their machines, or the need to be connected to a cloud or to our overloaded servers. Of course, one limitation will be the requirements on the host machines, that will need to be reasonably modern, in order to run a virtualized Linux system. Another is access to high bandwidth for downloading the boxes, but this is kind of a requirement already for downloading/watching the videos of the MOOC classes 😉

Big thanks go to our intern Stéphane Germain, who joined us this summer to work on this virtualized environment.

20 August, 2014 01:59PM by Olivier Berger

August 15, 2014

hackergotchi for Aurélien Jarno

Aurélien Jarno

Intel about to disable TSX instructions?

Last time I changed my desktop computer I bought a CPU from the Intel Haswell family, the one available on the market at that time. I carefully selected the CPU to make sure it supports as many instructions extensions as possible in this family (Intel likes segmentation, even high-end CPUs like the Core i7-4770k do not support all possible instructions). I ended-up choosing the Core i7-4771 as it supports the “Transactional Synchronization Extensions” (Intel TSX) instructions, which provide transactional memory support. Support for it has been recently added in the GNU libc, and has been activated in Debian. By choosing this CPU, I wanted to be sure that I can debug this support in case of bug report, like for example in bug#751147.

Recently some computing websites started to mention that the TSX instructions have bugs on Xeon E3 v3 family (and likely on Core i7-4771 as they share the same silicon and stepping), quoting this Intel document. Indeed one can read on page 49:

HSW136. Software Using Intel TSX May Result in Unpredictable System Behavior

Problem: Under a complex set of internal timing conditions and system events, software using the Intel TSX (Transactional Synchronization Extensions) instructions may result in unpredictable system behavior.
Implication: This erratum may result in unpredictable system behavior.
Workaround: It is possible for the BIOS to contain a workaround for this erratum.

And later on page 51:

Due to Erratum HSw136, TSX instructions are disabled and are only supported for software development. See your Intel representative for details.

The same websites tell that Intel is going to disable the TSX instructions via a microcode update. I hope it won’t be the case and that they are going to be able to find a microcode fix. Otherwise it would mean I will have to upgrade my desktop computer earlier than expected. It’s a bit expensive to upgrade it every year and that’s a the reason why I skipped the Ivy Bridge generation which didn’t bring a lot from the instructions point of view. Alternatively I can also skip microcode and BIOS updates, in the hope I won’t need another fix from them at some point.

15 August, 2014 04:02PM by aurel32

July 15, 2014

Stéphane Blondon

DebConf sur la planète

Cette année, la conférence Debian annuelle aura lieu à Portland, aux États-Unis. Comme l’année dernière, j’y participerai.🙂

Participation à la conférence Debian

Cette conférence sera la quinzième du nom. Voici une carte des différentes DebConf (passées en rouge, la prochaine en blanc et celle de l’année prochaine en jaune).

debconf14_planet

Jusqu’ici les conférences ont eu lieu alternativement en Europe et en Amérique (du Nord, centrale ou du Sud). Ce sera aussi le cas en 2015 puisque la conférence aura lieu en Allemagne à Heidelberg.

Réalisation de la carte

La carte diffère légèrement de celle réalisée l’année dernière (pour DebConf13) grâce quelques changements de configuration d’xplanet.

Commande utilisée

xplanet -transpng debconf14_planet.png -geometry 1024x512 -projection peters -config debconf14_planet.conf -num_times 1

Deux paramètres ont été modifiés :

  • La carte utilise une projection de Peters plutôt qu’une projection de Mercator. Pour cela, il suffit de remplacer -projection mercator par -projection peters.
  • Avec cette projection, la taille de la Terre n’est pas la même et la zone vide est rempli par défaut par un ciel étoilé. Il est aussi possible de choisir une couleur unie ou sa propre image de fond. Remplacer le paramètre -output par -transpng pour définir le fichier de sortie permet d’avoir un fond transparent.

Fichier debconf14_planet.conf

[earth]
shade=100
marker_file=coords.txt
marker_fontsize=15
map=night.jpg

L’ajout de map permet de définir l’image à utiliser à la place de l’image par défaut. Ici, on obtient une image de la Terre de nuit (qui provient de /usr/share/xplanet/images/night.jpg).

Fichier coords.txt

+44.80 +0.58 "0&1" #Bordeaux, France
+43.65 -79.38 "2" #Toronto, Canada
+59.92 +10.75 "3" #Oslo, Norway
-29.99 -51.22 "4" #Porto Alegre, Brazil
+60.22 +24.66 "5" #Espoo, Finland
+18.91 -98.97 "6" #Oaxtepec, Mexico
+55.96 -3.19 "7" #Edinburgh, Scotland
-37.96 -57.59 "8" #Mar del Plata, Argentina
+39.60 -6.08 "9" #Extremadura, Spain
+40.74 -74.00 "10" #New York City, USA
+44.78 +17.21 "11" #Banja Luka, Republika Srpska, Bosnia and Herzegovina
+12.14 -86.25 "12" #Managua, Nicaragua
+46.87 +6.75 "13" #Le Camp, Vaumarcus, Switzerland
+45.53 -122.67 "14" color=white #Portland, Oregon, USA
+49.24 +8.42 "15" color=yellow #Heidelberg, Germany

Le fichier a simplement été mis à jour (ajout d’Heidelberg, décalage des couleurs).

À bientôt !


15 July, 2014 08:56PM by ascendances

June 18, 2014

hackergotchi for Aurélien Jarno

Aurélien Jarno

Debian is switching (back) to GLIBC

Five years ago Debian and most derivatives switched from the standard GNU C Library (GLIBC) to the Embedded GLIBC (EGLIBC). Debian is now about to take the reverse way switching back to GLIBC, as EGLIBC is now a dead project, the last release being the 2.19 one. At the time of writing the glibc package has been uploaded to experimental and sits in the NEW queue.

EGLIBC is dead for a good reason: the GLIBC development has changed a lot in the recent years, due to two major events: Ulrich Drepper leaving Red Hat and the GLIBC development, and the GLIBC steering committe self-dissolving. This has resulted in a much more friendly development based on team work with good cooperation. The development is now based on peer review, which results in less buggy code (humans do make mistakes). It has also resulted in things that were clearly impossible before, like using the same repository for all architectures, and even getting rid of the ports/ directory. Before we used to have two sets of architectures, the main ones in the glibc repository with architectures like x86, SuperH or SPARC, and the secondary ones in the glibc-ports repository with architectures like ARM or MIPS. As you can see the separation was quite arbitrary, and often leaded to missing changes on the secondary architectures. We also got real stable branches, with regular fixes.

The most important EGLIBC features have been merged to GLIBC, including for example the use of non-bash but POSIX shell, or the renaming of reserved keywords. The notable exception is the support for configurable components, which we originally planned to use for Debian-Installer, by building a smaller flavor using -Os and without NIS and RPC support. At the end we never worked on that, and it seems that the hardware targeted by Debian has grown faster than the GLIBC size, so that is not really a big loss. At the end, we ended up with only 5 missing patches from the EGLIBC tree:

The package names are unchanged (except the source package and the binary package containing the sources) so the transition is fully transparent for the users.

I would like to thank all the CodeSourcery employees who worked on EGLIBC, with a special thank to Joseph Myers who spent countless hours to merge the most important EGLIBC changes back to GLIBC, and sent regular emails about the merge status. I would also like to thanks all the people on the GLIBC side that made the change to happen, and all persons participating in the GLIBC development.

18 June, 2014 08:04PM by aurel32

April 11, 2014

hackergotchi for Roland Mas

Roland Mas

Une page de publicité

Allez, c'est vendredi, c'est permis, je vais m'autoriser deux petites annonces.

Premièrement : rappelez-vous Minami Taiko, ce groupe de tambours japonais du sud de la France. Bon, nous on est des amateurs, mais il se trouve qu'on fait venir, pour le festival Escale à Sète, un vrai groupe de taikos du Japon et tout. Ils s'appellent SEN, et ils vont faire quelques animations musicales dans Sète du 18 au 21 avril. Et avant de repartir dans leur lointain Cipango, ils feront un vrai concert à Montpellier, le mardi 22 avril au soir, sur le campus de l'INRA/Supagro. Et devinez qui fait la première partie ? Minami Taiko, voilà qui ! Donc si vous voulez découvrir le taiko ou voir quelques amateurs suivis d'un vrai groupe, faites donc un tour sur le site de Minami Taiko. À noter qu'il y a aussi un atelier d'initiation le même jour si ça vous intéresse.

Deuxièmement : je suis fier de vous présenter un petit site web que c'est moi qui l'ai fait avec mes petits doigts délicats. Ça s'appelle Chacun sa part, et ça sert à faire des comptes entre amis, genre quand on part en vacances ensemble, ou qu'on fait régulièrement des dépenses partagées dans un groupe de gens. Pour éviter des comptes d'apothicaire à chaque restau, chaque tournée au bar, chaque passage en caisse, on saisit la dépense sur le site, on dit qui a payé et qui a participé, et le site calcule automatiquement les soldes de chacun et propose des suggestions de remboursements pour rééquilibrer les comptes. Y'a un système d'invitations pour que chacun puisse consulter l'état du groupe et saisir des dépenses, des QR-codes pour faciliter la vie aux utilisateurs de smartphone, et même si ça n'a pas encore été testé à grande échelle ça a été validé par une poignée de testeurs dans différentes configurations. Allez-y, c'est cadeau. Chacun sa part. Point com.

11 April, 2014 08:06AM

37

C'est l'heure d'un marronnier de ce blog : la petite chronique numérologique du 11 avril. Celle-ci sera consacrée au nombre 37.

Nombre premier, premier irrégulier, premier cubain, cousin avec 41, hexagonal centré et étoilé, c'est aussi le numéro atomique du rubidium et ça nous fait une belle jambe.

Et c'est un nombre qui colle particulièrement bien à la journée d'aujourd'hui (qui, si jamais les générations futures s'y intéressent, s'annonce pour être belle et douce, avec peut-être un petit voile nuageux).

11 April, 2014 08:06AM

November 15, 2013

10 ans !

Eh ben dites-donc mes aïeux, le temps passe. Le 15 novembre 2003, j'émettais ma première facture en tant que consultant indépendant.

Eh ben dix ans plus tard, y'a eu des hauts et des bas, mais globalement tout va bien, et je continue à faire des factures de temps en temps, et ça me plaît toujours autant.

Touchons du bois pour que ça continue, et on en reparle dans dix ans !

15 November, 2013 02:45PM

October 10, 2013

Les rumeurs de la mort de ce blog…

…sont un peu exagérées. Mais c'est sûr, c'est calme, et apparemment une partie de mon lectorat s'en inquiète. Donc voici un lot de nouvelles pour ceux que ma vie passionne et qui n'ont plus accès au 3615 Roland.

Alors bon, suite à ce que je vous disais sur Eleven en mai, je me suis mis en quête d'un autre groupe de rock. J'avais cru en trouver un, mais j'ai l'impression que la motivation n'était pas universellement partagée, à tel point qu'on a dû faire moins d'une répétition par mois en moyenne. C'est pas des bonnes conditions, donc je suis de nouveau en recherche. Si vous cherchez un batteur pour jouer du rock aux environs de Montpellier, faites-moi signe.

Cela dit, je ne suis pas resté oisif pour autant : le taiko continue, l'association a été reprise en main, on répète, et hop hop hop on est même invités à jouer en public pas plus tard que ce week-end ! Ça va se passer au parc Borély à Marseille, à l'occasion du festival d'automne organisé par le consulat général du Japon. Plus de détails sur le site de Minami Taiko, vu que c'est comme ça qu'on s'appelle. Le site est neuf aussi, mais on y mettra des photos et peut-être des vidéos.

Sur les autres fronts : côté FusionForge c'est calme, mais la prochaine édition du Debian Administrator's Handbook / Cahier de l'Admin Debian avance petit à petit. On commence non pas à en voir le bout, mais à voir ce qu'il reste à faire avant d'en voir le bout. Mes autres récents petits bricolages de geek feront peut-être l'objet d'un billet dédié si je suis motivé.

Voilà voilà.

10 October, 2013 03:15PM