May 10, 2023

hackergotchi for Charles Plessy

Charles Plessy

Plussez pour patcher Firefox pour afficher du Markdown.

J'ai écrit auparavant que quand Firefox reçoit un fichier dont le type média est text/markdown, il le propose au téléchargement, alors que les autres navigateurs l'affichent comme un fichier texte.

Il est maintenant possible de plusser sur pour demander que Firefox formatte le markdown par défaut.

10 May, 2023 11:43PM

April 12, 2023

hackergotchi for Aurélien Jarno

Aurélien Jarno

Backup server upgraded to Bookworm

A few months ago, I switched my backup server to an ODROID-M1 SBC. It uses a RK3568 SoC with a quad-core Cortex-A55 and AES extensions (useful for disk encryption), and I added a 2 TB NVME SSD to the M2 slot. It also has a SATA connector, but the default enclosure does not have space for 2.5" drives. It's not the fastest SBC, but it runs stable and quite well as a backup server, and it's fanless, and low-power (less than 2 W idle). The support for the SoC has been added recently to the Linux kernel (it's used by various SBC), however the device tree for the ODROID-M1 was missing, so I contributed it based on the vendor one, and also submitted a few small fixes.

All the changes ended in the Bookworm kernel, and with the Bookworm release approaching, I decided it was the good moment to upgrade it. It went quite well, and now I can enjoy running dist-upgrade like on other stable servers without having to care about the kernel. I am currently using Borg as a backup software, but the upgrade also gave access to a newer Restic version supporting compression (a must have for me), so I may give it a try.

12 April, 2023 09:07AM by aurel32

April 11, 2023

New website, or kind of...

For over 15 years, I've hardly made any updates to my website, and it remains low on my priority list. So I made a radical decision to replace it entirely with my blog. The content of the website has been reduced to just two additional pages.

But nothing has been lost: nowadays, Wikipedia is a much better platform for sharing knowledge than random websites. And it happens that they already cover all that was on my website about subaquatic diving in French. They also offer a multitude of resources in electronics, including the topics that were on my website: LCD displays, I²C bus, barcodes, parallel ports, serial ports, and DCF77 reception.

Finally if you're in need of Debian QEMU images for various architectures, I recommend the Debian Quick Image Baker pre-baked images page instead.

11 April, 2023 08:29AM by aurel32

March 09, 2023

hackergotchi for Charles Plessy

Charles Plessy

If you work at Dreamhost, can you help us?

Update: thanks to the very kind involvment of the widow of our wemaster, we could provide enough private information to Dreamhost, who finally accepted to reset the password and the MFA. We have recovered evrything! Many thanks to everybody who helped us!

Due to tragic circumstances, one association that I am part of, Sciencescope got locked out of its account at Dreamhost. Locked out, we can not pay the annual bill. Dreamhost contacted us about the payment, but will not let us recover the access to our account in order to pay. So they will soon close the account. Our website, mailing lists and archives, will be erased. We provided plenty of evidence that we are not scammers and that we are the legitimate owners of the account, but reviewing it is above the pay grade of the custommer support (I don't blame them) and I could not convince them to let somebody higher have a look at our case.

If you work at Dreamhost and want to keep us as custommers instead of kicking us like that, please ask the support service in charge of ticket 225948648 to send the recovery URL to the secondary email adddresses (the ones you used to contact us about the bill!) in addition to the primary one (which nobody will read anymore). You can encrypt it for my Debian Developer key 73471499CC60ED9EEE805946C5BD6C8F2295D502 if you worry it gets in wrong hands. If you still have doubts I am available for calls any time.

If you know somebody working at Dreamhost can you pass them the message? This would be a big, big, relief for our non-profit association.

09 March, 2023 01:35PM

March 06, 2023

Vincent Bernat

Détection et suppression des DDoS avec Akvorado et Flowspec

Akvorado collecte des flux sFlow et IPFIX, les stocke dans une base de données ClickHouse et les présente dans une console web. Bien qu’il n’y ait pas de détection de DDoS intégrée, il est possible d’en créer une à partir de requêtes pour ClickHouse.

Détection des attaques DDoS

Supposons que nous voulions détecter des attaques DDoS ciblant nos clients. À titre d’exemple, nous considérons une attaque DDoS comme une collection de flux sur une minute ciblant une adresse IP client unique, à partir d’un port source unique et correspondant à l’une de ces conditions :

  • une bande passante moyenne de 1 Gbit/s,
  • une bande passante moyenne de 200 Mbit/s lorsque le protocole est UDP,
  • plus de 20 adresses IP sources et une bande passante moyenne de 100 Mbit/s, ou
  • plus de 10 pays sources et une bande passante moyenne de 100 Mbit/s.

Voici la requête SQL pour détecter de telles attaques au cours des 5 dernières minutes :

    toStartOfMinute(TimeReceived) AS TimeReceived,
    dictGetOrDefault('protocols', 'name', Proto, '???') AS Proto,
    SUM(((((Bytes * SamplingRate) * 8) / 1000) / 1000) / 1000) / 60 AS Gbps,
    uniq(SrcAddr) AS sources,
    uniq(SrcCountry) AS countries
  FROM flows
  WHERE TimeReceived > now() - INTERVAL 5 MINUTE
    AND DstNetRole = 'customers'
WHERE (Gbps > 1)
   OR ((Proto = 'UDP') AND (Gbps > 0.2)) 
   OR ((sources > 20) AND (Gbps > 0.1)) 
   OR ((countries > 10) AND (Gbps > 0.1))
  TimeReceived DESC,
  Gbps DESC

Voici un exemple de sortie1 où deux de nos utilisateurs sont attaqués. L’un d’eux subit apparemment une attaque d’amplification NTP, l’autre une attaque d’amplification DNS :

TimeReceived DstAddr SrcPort Proto Gbps sources countries
2023-02-26 17:44:00 ::ffff: 123 UDP 0.102 109 13
2023-02-26 17:43:00 ::ffff: 123 UDP 0.130 133 17
2023-02-26 17:43:00 ::ffff: 53 UDP 0.129 364 63
2023-02-26 17:43:00 ::ffff: 123 UDP 0.113 129 21
2023-02-26 17:42:00 ::ffff: 123 UDP 0.139 50 14
2023-02-26 17:42:00 ::ffff: 123 UDP 0.105 42 14
2023-02-26 17:40:00 ::ffff: 53 UDP 0.121 340 65

Suppression des attaques DDoS

Une fois détectée, il existe au moins deux façons d’arrêter l’attaque au niveau du réseau :

  • supprimer tout le trafic vers l’utilisateur ciblé (RTBH)
  • supprimer sélectivement les paquets correspondant aux motifs de l’attaque (Flowspec)

Suppression du trafic avec RTBH

La méthode la plus simple consiste à sacrifier l’utilisateur attaqué. Bien que cela aide l’attaquant, cela protège avant tout votre réseau. C’est une méthode prise en charge par tous les routeurs. Vous pouvez également déléguer cette protection à la plupart des fournisseurs de transit. Cela est utile si le volume des attaques dépasse la capacité de votre connexion Internet.

Cela fonctionne en annonçant avec BGP une route vers l’utilisateur attaqué avec une communauté spécifique. Le routeur de bordure modifie l’adresse du prochain routeur de ces routes vers une adresse IP spécifique configurée pour transférer le trafic vers l’interface « nulle ». La RFC 7999 définit 65535:666 à cette fin. C’est ce qu’on appelle un trou noir déclenché à distance (“remote triggered blackhole”, RTBH) et expliqué en détail dans la RFC 3882.

Il est également possible de bloquer la source des attaques en utilisant uRPF défini dans la RFC 3704. C’est expliqué dans la RFC 5635. Cependant, uRPF peut être une charge importante pour les ressources de votre routeur. Consultez “NCS5500 uRPF: Configuration et Impact sur l’échelle” pour un exemple des types de restrictions auxquelles vous devez vous attendre lorsque vous activez uRPF.

Pour annoncer les routes, nous pouvons utiliser BIRD. Voici un fichier de configuration complet pour permettre à tout routeur de les collecter :

log stderr all;
router id;

protocol device {
  scan time 10;

protocol bgp exporter {
  ipv4 {
    import none;
    export where proto = "blackhole4";
  ipv6 {
    import none;
    export where proto = "blackhole6";
  local as 64666;
  neighbor range external;
  dynamic name "exporter";
  dynamic name digits 2;
  graceful restart yes;
  graceful restart time 0;
  long lived graceful restart yes;
  long lived stale time 3600;  # keep routes for 1 hour!

protocol static blackhole4 {
  route blackhole {
    bgp_community.add((65535, 666));
  route blackhole {
    bgp_community.add((65535, 666));
protocol static blackhole6 {

Nous utilisons BGP LLGR pour garantir que les routes sont conservées pendant une heure, même si la connexion BGP est interrompue, notamment pendant une maintenance.

Du côté du récepteur, si vous disposez d’un routeur Cisco fonctionnant sous IOS XR, vous pouvez utiliser la configuration suivante pour éliminer le trafic reçu sur la session BGP. Comme la session BGP est dédiée à cette utilisation, la communauté 65535:666 n’est pas utilisée, mais vous pouvez aussi transférer ces routes à vos fournisseurs de transit.

router static
 vrf public
  address-family ipv4 unicast Null0 description "BGP blackhole"
  address-family ipv6 unicast
   2001:db8::1/128 Null0 description "BGP blackhole"
route-policy blackhole_ipv4_in_public
  if destination in ( le 31) then
  set next-hop
route-policy blackhole_ipv6_in_public
  if destination in (::/0 le 127) then
  set next-hop 2001:db8::1
router bgp 12322
 neighbor-group BLACKHOLE_IPV4_PUBLIC
  remote-as 64666
  ebgp-multihop 255
  update-source Loopback10
  address-family ipv4 unicast
   maximum-prefix 100 90
   route-policy blackhole_ipv4_in_public in
   route-policy drop out
   long-lived-graceful-restart stale-time send 86400 accept 86400
  address-family ipv6 unicast
   maximum-prefix 100 90
   route-policy blackhole_ipv6_in_public in
   route-policy drop out
   long-lived-graceful-restart stale-time send 86400 accept 86400
 vrf public
   use neighbor-group BLACKHOLE_IPV4_PUBLIC
   description akvorado-1

Lorsque le trafic est éliminé, il est toujours remonté par IPFIX et sFlow. Dans Akvorado, utilisez ForwardingStatus >= 128 comme filtre pour sélectionner celui-ci.

Bien que cette méthode soit compatible avec tous les routeurs, elle permet à l’attaque de réussir car la cible est complètement inaccessible. Si votre routeur le prend en charge, Flowspec peut filtrer sélectivement les flux pour arrêter l’attaque sans affecter le client.

Suppression du trafic avec Flowspec

Flowspec est défini dans la RFC 8955 et permet la transmission de spécifications de flux dans des sessions BGP. Une spécification de flux est un ensemble de critères à appliquer au trafic IP. Ceux-ci incluent le préfixe source et destination, le protocole IP, le port source et destination et la longueur des paquets. Chaque spécification de flux est associée à une action, encodée sous forme d’une communauté étendue : limitation du trafic, marquage ou redirection.

Pour annoncer des spécifications de flux avec BIRD, nous complétons notre configuration. La communauté étendue utilisée limite le trafic correspondant à 0 octet par seconde.

flow4 table flowtab4;
flow6 table flowtab6;

protocol bgp exporter {
  flow4 {
    import none;
    export where proto = "flowspec4";
  flow6 {
    import none;
    export where proto = "flowspec6";
  # […]

protocol static flowspec4 {
  route flow4 {
    sport = 53;
    length >= 1476 && <= 1500;
    proto = 17;
    bgp_ext_community.add((generic, 0x80060000, 0x00000000));
  route flow4 {
    sport = 123;
    length = 468;
    proto = 17;
    bgp_ext_community.add((generic, 0x80060000, 0x00000000));
protocol static flowspec6 {

Si vous avez un routeur ASR tournant sous IOS XR, la configuration ressemble à ceci :

vrf public
 address-family ipv4 flowspec
 address-family ipv6 flowspec
router bgp 12322
 address-family vpnv4 flowspec
 address-family vpnv6 flowspec
 neighbor-group FLOWSPEC_IPV4_PUBLIC
  remote-as 64666
  ebgp-multihop 255
  update-source Loopback10
  address-family ipv4 flowspec
   long-lived-graceful-restart stale-time send 86400 accept 86400
   route-policy accept in
   route-policy drop out
   maximum-prefix 100 90
   validation disable
  address-family ipv6 flowspec
   long-lived-graceful-restart stale-time send 86400 accept 86400
   route-policy accept in
   route-policy drop out
   maximum-prefix 100 90
   validation disable
 vrf public
  address-family ipv4 flowspec
  address-family ipv6 flowspec
   use neighbor-group FLOWSPEC_IPV4_PUBLIC
   description akvorado-1

Ensuite, il convient d’activer Flowspec sur toutes les interfaces :

 vrf public
  address-family ipv4
   local-install interface-all
  address-family ipv6
   local-install interface-all

Comme pour la configuration à base de RTBH, vous pouvez afficher les flux éliminés avec le filtre ForwardingStatus >= 128.

Détection des attaques DDoS (suite)

Dans l’exemple utilisant Flowspec, les flux sont aussi filtrés selon la longueur des paquets :

route flow4 {
  sport = 53;
  length >= 1476 && <= 1500;
  proto = 17;
  bgp_ext_community.add((generic, 0x80060000, 0x00000000));

C’est une addition importante : les requêtes DNS légitimes ont une taille inférieure à cela et ne sont donc pas filtrées2. Avec ClickHouse, vous pouvez obtenir les 10ème et 90ème centiles des tailles de paquets avec quantiles(0.1, 0.9)(Bytes/Packets).

Le dernier problème que nous devons résoudre est de rendre les requêtes plus rapides : elles peuvent avoir besoin de plusieurs secondes pour collecter les données et sont susceptibles de consommer des ressources substantielles de votre base de données ClickHouse. Une solution consiste à créer une vue matérialisée pour pré-agréger les résultats :

CREATE TABLE ddos_logs (
  TimeReceived DateTime,
  DstAddr IPv6,
  Proto UInt32,
  SrcPort UInt16,
  Gbps SimpleAggregateFunction(sum, Float64),
  Mpps SimpleAggregateFunction(sum, Float64),
  sources AggregateFunction(uniqCombined(12), IPv6),
  countries AggregateFunction(uniqCombined(12), FixedString(2)),
  size AggregateFunction(quantiles(0.1, 0.9), UInt64)
) ENGINE = SummingMergeTree
PARTITION BY toStartOfHour(TimeReceived)
ORDER BY (TimeReceived, DstAddr, Proto, SrcPort)
TTL toStartOfHour(TimeReceived) + INTERVAL 6 HOUR DELETE ;

CREATE MATERIALIZED VIEW ddos_logs_view TO ddos_logs AS
    toStartOfMinute(TimeReceived) AS TimeReceived,
    sum(((((Bytes * SamplingRate) * 8) / 1000) / 1000) / 1000) / 60 AS Gbps,
    sum(((Packets * SamplingRate) / 1000) / 1000) / 60 AS Mpps,
    uniqCombinedState(12)(SrcAddr) AS sources,
    uniqCombinedState(12)(SrcCountry) AS countries,
    quantilesState(0.1, 0.9)(toUInt64(Bytes/Packets)) AS size
  FROM flows
  WHERE DstNetRole = 'customers'

La table ddos_logs utilise le moteur SummingMergeTree. Lorsque la table reçoit de nouvelles données, ClickHouse remplace toutes les lignes ayant la même clé de tri, telle que définie par la directive ORDER BY, par une seule ligne qui contient des valeurs résumées3 en utilisant soit la fonction sum() soit la fonction d’agrégation explicitement spécifiée (uniqCombined et quantiles dans notre exemple).

Enfin, nous modifions notre requête initiale avec la requête suivante :

    dictGetOrDefault('protocols', 'name', Proto, '???') AS Proto,
    sum(Gbps) AS Gbps,
    sum(Mpps) AS Mpps,
    uniqCombinedMerge(12)(sources) AS sources,
    uniqCombinedMerge(12)(countries) AS countries,
    quantilesMerge(0.1, 0.9)(size) AS size
  FROM ddos_logs
  WHERE TimeReceived > now() - INTERVAL 60 MINUTE
WHERE (Gbps > 1)
   OR ((Proto = 'UDP') AND (Gbps > 0.2)) 
   OR ((sources > 20) AND (Gbps > 0.1)) 
   OR ((countries > 10) AND (Gbps > 0.1))
  TimeReceived DESC,
  Gbps DESC

Assemblage final

Pour résumer, la construction d’un système de suppression des attaques DDoS nécessite de suivre les étapes suivantes :

  1. définir un ensemble de critères pour détecter une attaque DDoS
  2. traduire ces critères en requêtes SQL
  3. pré-agréger les flux dans des tables SummingMergeTree
  4. interroger et transformer les résultats en un fichier de configuration pour BIRD
  5. configurer vos routeurs pour extraire les routes de BIRD

Un script Python comme celui qui suit permet de gérer la quatrième étape. Pour chaque cible attaquée, il génère à la fois une règle Flowspec et une route de type « trou noir ».

import socket
import types
from clickhouse_driver import Client as CHClient

# Insérez ici votre requête SQL

# Combien de règles anti-DDoS doit-on publier au plus ?

def empty_ruleset():
    ruleset = types.SimpleNamespace()
    ruleset.flowspec = types.SimpleNamespace()
    ruleset.blackhole = types.SimpleNamespace()
    ruleset.flowspec.v4 = []
    ruleset.flowspec.v6 = []
    ruleset.blackhole.v4 = []
    ruleset.blackhole.v6 = []
    return ruleset

current_ruleset = empty_ruleset()

client = CHClient(host="")
while True:
    results = client.execute(SQL_QUERY)
    seen = {}
    new_ruleset = empty_ruleset()
    for (t, addr, proto, port, gbps, mpps, sources, countries, size) in results:
        if (addr, proto, port) in seen:
        seen[(addr, proto, port)] = True

        # Flowspec
        if addr.ipv4_mapped:
            address = addr.ipv4_mapped
            rules = new_ruleset.flowspec.v4
            table = "flow4"
            mask = 32
            nh = "proto"
            address = addr
            rules = new_ruleset.flowspec.v6
            table = "flow6"
            mask = 128
            nh = "next header"
        if size[0] == size[1]:
            length = f"length = {int(size[0])}"
            length = f"length >= {int(size[0])} && <= {int(size[1])}"
        header = f"""
# Time: {t}
# Source: {address}, protocol: {proto}, port: {port}
# Gbps/Mpps: {gbps:.3}/{mpps:.3}, packet size: {int(size[0])}<=X<={int(size[1])}
# Flows: {flows}, sources: {sources}, countries: {countries}
route {table} {{
  dst {address}/{mask};
  sport = {port};
  {nh} = {socket.getprotobyname(proto)};
  bgp_ext_community.add((generic, 0x80060000, 0x00000000));

        # Blackhole
        if addr.ipv4_mapped:
            rules = new_ruleset.blackhole.v4
            rules = new_ruleset.blackhole.v6
route {address}/{mask} blackhole {{
  bgp_community.add((65535, 666));

        new_ruleset.flowspec.v4 = list(
        new_ruleset.flowspec.v6 = list(

        # TODO: publier les changements par courriel ou chat

        current_ruleset = new_ruleset
        changes = False
        for rules, path in (
            (current_ruleset.flowspec.v4, "v4-flowspec"),
            (current_ruleset.flowspec.v6, "v6-flowspec"),
            (current_ruleset.blackhole.v4, "v4-blackhole"),
            (current_ruleset.blackhole.v6, "v6-blackhole"),
            path = os.path.join("/etc/bird/", f"{path}.conf")
            with open(f"{path}.tmp", "w") as f:
                for r in rules:
            changes = (
                changes or not os.path.exists(path) or not samefile(path, f"{path}.tmp")
            os.rename(f"{path}.tmp", path)

        if not changes:

        proc = subprocess.Popen(
            ["birdc", "configure"],
        stdout, stderr = proc.communicate(None)
        stdout = stdout.decode("utf-8", "replace")
        stderr = stderr.decode("utf-8", "replace")
        if proc.returncode != 0:
                "{} error:\n{}\n{}".format(
                    "birdc reconfigure",
                        [" O: {}".format(line) for line in stdout.rstrip().split("\n")]
                        [" E: {}".format(line) for line in stderr.rstrip().split("\n")]

Jusqu’à ce qu’Akvorado intègre la détection et la lutte contre les attaques DDoS, les idées présentées dans ce billet fournissent une base solide pour commencer à construire votre propre système anti-DDoS. 🛡️

  1. ClickHouse peut exporter les résultats au format Markdown en ajoutant FORMAT Markdown à la requête. ↩︎

  2. Bien que la plupart des clients DNS réessaient avec TCP en cas d’échec, ce n’est pas toujours le cas : jusqu’à récemment, la bibliothèque Musl ne le faisait pas. ↩︎

  3. La vue matérialisée agrège également les données qu’elle a sous la main, à la fois pour l’efficacité et pour s’assurer que nous travaillons avec les bons types de données. ↩︎

06 March, 2023 07:34AM by Vincent Bernat

February 13, 2023

Langage inspiré de SQL pour filtrer les flux

Akvorado collecte les flux réseau à l’aide d’IPFIX ou de sFlow. Il les stocke dans une base de données ClickHouse. Une console web permet à l’utilisateur de faire des requêtes sur les données pour obtenir des graphiques. Un aspect intéressant de cette console est la possibilité de filtrer les flux avec un langage inspiré de SQL :

Filter editor in Akvorado console

Souvent, les interfaces web exposent un constructeur de requêtes pour concevoir de tels filtres. À la place, j’ai choisi de combiner un langage similaire à SQL avec un éditeur prenant en charge la complétion, la coloration syntaxique et la vérification syntaxique1.

L’analyseur syntaxique du langage est construit avec pigeon (Go) à partir d’une grammaire d’expression d’analyse syntaxique (parsing expression grammar ou PEG). Le composant à la base de l’éditeur est CodeMirror (TypeScript).

Analyseur syntaxique

Les grammaires PEG sont relativement récentes2 et sont une alternative aux grammaires contextuelles. Elles sont plus faciles à écrire et peuvent générer de meilleurs messages d’erreur. Par exemple, Python a basculé d’un analyseur de type LL(1) à un analyseur basé sur une grammaire PEG depuis Python 3.9.

pigeon génère un analyseur pour Go. Une grammaire est un ensemble de règles. Chaque règle est un identifiant, avec optionnellement une étiquette utilisée pour les messages d’erreur, une expression et une action en Go à exécuter. Vous pouvez trouver la grammaire complète dans parser.peg. Voici une règle simplifiée :

ConditionIPExpr "condition on IP" 
  column:("ExporterAddress"i { return "ExporterAddress", nil }
        / "SrcAddr"i { return "SrcAddr", nil }
        / "DstAddr"i { return "DstAddr", nil }) _ 
  operator:("=" / "!=") _ 
  ip:IP {
    return fmt.Sprintf("%s %s IPv6StringToNum(%s)",
      toString(column), toString(operator), quote(ip)), nil

L’identifiant de la règle est ConditionIPExpr. Elle attend soit ExporterAddress, soit SrcAddr, soit DstAddr, sans distinction de la case. L’action pour chaque cas renvoie le nom de la colonne correspondante. C’est ce qui est stocké dans la variable column. Ensuite, elle attend un des deux opérateurs possibles. Comme il n’y a pas de bloc de code, l’opérateur est stocké dans la variable operator. Ensuite, elle attend une chaîne validée par la règle IP qui est définie ailleurs dans la grammaire. Si c’est le cas, elle stocke le résultat dans la variable ip et exécute l’action finale. L’action transforme la colonne, l’opérateur et l’adresse IP en une expression SQL pour ClickHouse. Par exemple, si nous avons ExporterAddress =, nous obtenons ExporterAddress = IPv6StringToNum('').

La règle IP utilise une expression régulière rudimentaire mais vérifie si l’adresse correspondante est correcte dans le bloc d’action, grâce à netip.ParseAddr():

IP "IP address"  [0-9A-Fa-f:.]+ {
  ip, err := netip.ParseAddr(string(c.text))
  if err != nil {
    return "", errors.New("expecting an IP address")
  return ip.String(), nil

Cet analyseur transforme de manière sécurisée un filtre en une clause WHERE acceptée par ClickHouse3 :

WHERE InIfBoundary = 'external' 
AND ExporterRegion = 'france' 
AND InIfConnectivity = 'transit' 
AND SrcAS = 15169 
AND DstAddr BETWEEN toIPv6('2a01:e0f:ffff::') 
                AND toIPv6('2a01:e0f:ffff:ffff:ffff:ffff:ffff:ffff')

Intégration dans CodeMirror

CodeMirror est un éditeur de code polyvalent qui peut être facilement intégré dans les projets JavaScript. Dans Akvorado, le composant Vue.js InputFilter utilise CodeMirror et tire parti de fonctionnalités telles que la coloration syntaxique, la vérification syntaxique et la complétion. Le code source de ces fonctionnalités se trouve dans le répertoire codemirror/lang-filter/.

Coloration syntaxique

La grammaire PEG pour Go ne peut pas être utilisé directement4 et les exigences pour les analyseurs syntaxiques utilisés dans les éditeurs sont différentes : ils doivent être tolérants aux erreurs et fonctionner de manière incrémentielle, car le code est généralement mis à jour caractère par caractère. CodeMirror propose une solution via son propre générateur d’analyseur, Lezer.

Nous n’avons pas besoin que cet analyseur supplémentaire comprenne pleinement le langage des filtres. Seule la structure est nécessaire : les noms de colonnes, les opérateurs de comparaison et de logique, les valeurs entre guillemets ou non. La grammaire est donc assez courte et n’a pas besoin d’être mise à jour souvent :

@top Filter {

expression {
 Not expression |
 "(" expression ")" |
 "(" expression ")" And expression |
 "(" expression ")" Or expression |
 comparisonExpression And expression |
 comparisonExpression Or expression |
comparisonExpression {
 Column Operator Value

Value {
  String | Literal | ValueLParen ListOfValues ValueRParen
ListOfValues {
  ListOfValues ValueComma (String | Literal) |
  String | Literal

// […]
@tokens {
  // […]
  Column { std.asciiLetter (std.asciiLetter|std.digit)* }
  Operator { $[a-zA-Z!=><]+ }

  String {
    '"' (![\\\n"] | "\\" _)* '"'? |
    "'" (![\\\n'] | "\\" _)* "'"?
  Literal { (std.digit | std.asciiLetter | $[.:/])+ }
  // […]

L’expression SrcAS = 12322 AND (DstAS = 1299 OR SrcAS = 29447) est analysée ainsi :

Filter(Column, Operator, Value(Literal),
  And, Column, Operator, Value(Literal),
  Or, Column, Operator, Value(Literal))

La dernière étape est d’indiquer à CodeMirror la correspondance entre chaque symbole et sa catégorie pour la coloration syntaxique :

export const FilterLanguage = LRLanguage.define({
  parser: parser.configure({
    props: [
        Column: t.propertyName,
        String: t.string,
        Literal: t.literal,
        LineComment: t.lineComment,
        BlockComment: t.blockComment,
        Or: t.logicOperator,
        And: t.logicOperator,
        Not: t.logicOperator,
        Operator: t.compareOperator,
        "( )": t.paren,

Vérification syntaxique

La vérification syntaxique est déléguée à l’analyseur syntaxique en Go. Le point d’accès /api/v0/console/filter/validate accepte un filtre et retourne une structure JSON avec les éventuelles erreurs:

  "message": "at line 1, position 12: string literal not terminated",
  "errors": [{
    "line":    1,
    "column":  12,
    "offset":  11,
    "message": "string literal not terminated",

Le greffon pour CodeMirror interroge cette API et transforme chaque erreur en un diagnostic.


Le système de complétion adopte une approche hybride. Il répartit le travail entre le frontend et le backend pour offrir ses suggestions.

Le frontend utilise l’analyseur construit avec Lezer pour déterminer le contexte de la complétion : s’agit-il compléter un nom de colonne, un opérateur ou une valeur ? Il extrait également le nom de la colonne si nous complétons autre chose. Il transfère le résultat au backend via le point de terminaison /api/v0/console/filter/complete. Parcourir l’arbre syntaxique n’a pas été aussi facile que je le pensais, mais les tests unitaires ont beaucoup aidé.

Le backend utilise l’analyseur généré par pigeon pour compléter les noms de colonnes et les opérateurs de comparaison. Pour les valeurs, les complétions sont statiques out extraites de la base de données ClickHouse. Un utilisateur peut compléter un numéro AS à partir d’un nom d’organisation grâce au code suivant :

results := []struct {
  Label  string `ch:"label"`
  Detail string `ch:"detail"`
columnName := "DstAS"
sqlQuery := fmt.Sprintf(`
 SELECT concat('AS', toString(%s)) AS label, dictGet('asns', 'name', %s) AS detail
 FROM flows
 WHERE TimeReceived > date_sub(minute, 1, now())
 AND detail != ''
 AND positionCaseInsensitive(detail, $1) >= 1
 GROUP BY label, detail
`, columnName, columnName)
if err := conn.Select(ctx, &results, sqlQuery, input.Prefix); err != nil {
  c.r.Err(err).Msg("unable to query database")
for _, result := range results {
  completions = append(completions, filterCompletion{
    Label:  result.Label,
    Detail: result.Detail,
    Quoted: false,

À mon avis, ce système de complétion est un élément important qui fait de l’éditeur un moyen efficace de sélectionner des flux. Alors qu’un constructeur de requêtes aurait pu être plus convivial pour les débutants, la facilité d’utilisation et les fonctionnalités du système de complétion le rendent plus agréable à utiliser une fois que l’utilisateur familiarisé.

  1. De plus, créer un constructeur de requêtes me semblait une tâche assez rébarbative. ↩︎

  2. Elles ont été introduites en 2004 dans « Parsing Expression Grammars: A Recognition-Based Syntactic Foundation ». Les analyseurs LR ont été introduits en 1965, les analyseurs LALR en 1969 et les analyseurs LL dans les années 1970. Yacc, un générateur d’analyseurs populaire, a été écrit en 1975. ↩︎

  3. L’analyseur retourne une chaîne. Il ne génère pas un arbre syntaxique intermédiaire. Cela le rend plus simple et suffit à nos besoins. ↩︎

  4. Elle pourrait être manuellement traduite en JavaScript avec PEG.js↩︎

13 February, 2023 08:06AM by Vincent Bernat

February 11, 2023

Fiabiliser la plaque de déclenchement Geberit Sigma 70

Mes WC sont équipés d’une chasse d’eau avec plaque de déclenchement Geberit Sigma 70. Le discours commercial autour de ce dispositif à asservissement hydraulique vante le « mécanisme révolutionnaire qui n’utilise pas d’électronique embarquée ». En pratique, le déclenchement est très capricieux et a un taux d’échec particulièrement élevé. Évitez ce type de mécanisme ! Préférez lui une version intégralement mécanique comme le Geberit Sigma 20.

Après le passage de plusieurs plombiers, des échanges avec le service technique de Geberit et le remplacement à grands frais de l’intégralité du mécanisme, j’observais toujours un taux d’échec de plus de 50% pour la petite chasse. J’ai finalement réussi à réduire ce taux à 5% en appliquant deux patins ronds en silicone transparent de 8 mm de diamètre sur le dos de la plaque de déclenchement. Leurs emplacements sont indiqués par des ronds rouges sur la photo ci-dessous :

Plaque de déclenchement Geberit Sigma 70. En haut le mécanisme posé en applique et convertissant l'appui mécanique en une impulsion hydraulique. En bas, le dos de la plaque de déclenchement avec les deux emplacements où appliquer les patins.
Mécanisme Geberit Sigma 70. En haut: le mécanisme posé en applique. En bas, le dos de la plaque de déclenchement en verre. En rouge, les deux emplacements où appliquer les patins.

Comptez environ 5 € et autant de minutes pour cette opération.

11 February, 2023 09:22PM by Vincent Bernat

February 06, 2023

Encodage rapide et dynamique des Protocol Buffers en Go

Les Protocol Buffers sont un choix populaire pour la sérialisation de données structurées en raison de leur taille compacte, de leur rapidité de traitement, de leur indépendance du langage cible et de leur compatibilité. D’autres alternatives existent, notamment Cap’n Proto, CBOR et Avro.

Les structures de données sont habituellement décrites dans un fichier de définition de protocole (.proto). Le compilateur protoc et un greffon spécifique à un langage les convertissent en code:

$ head flow-4.proto
syntax = "proto3";
package decoder;
option go_package = "akvorado/inlet/flow/decoder";

message FlowMessagev4 {

  uint64 TimeReceived = 2;
  uint32 SequenceNum = 3;
  uint64 SamplingRate = 4;
  uint32 FlowDirection = 5;
$ protoc -I=. --plugin=protoc-gen-go --go_out=module=akvorado:. flow-4.proto
$ head inlet/flow/decoder/flow-4.pb.go
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
//      protoc-gen-go v1.28.0
//      protoc        v3.21.12
// source: inlet/flow/data/schemas/flow-4.proto

package decoder

import (
        protoreflect ""

Akvorado collecte les flux réseau à l’aide de IPFIX ou sFlow, les décode à l’aide de GoFlow2, les encode en Protocol Buffers et les envoie à Kafka pour les stocker dans une base de données ClickHouse. La collecte d’un nouveau champ, comme les adresses MAC source et destination, nécessite des modifications à plusieurs endroits, y compris le fichier de définition de protocole et le code de migration pour ClickHouse. De plus, le coût est supporté par tous les utilisateurs1. Il serait agréable d’avoir un schéma commun à l’application et de permettre aux utilisateurs d’activer ou de désactiver les champs dont ils ont besoin.

Bien que le principal objectif est la flexibilité, nous ne voulons pas sacrifier les performances. Sur ce front, c’est un véritable succès: lors de la mise à niveau de 1.6.4 à 1.7.1, les performances de décodage et d’encodage ont presque doublé ! 🤗

goos: linux
goarch: amd64
pkg: akvorado/inlet/flow
cpu: AMD Ryzen 5 5600X 6-Core Processor
                            │ initial.txt  │              final.txt              │
                            │    sec/op    │   sec/op     vs base                │
Netflow/with_encoding-12      12.963µ ± 2%   7.836µ ± 1%  -39.55% (p=0.000 n=10)
Sflow/with_encoding-12         19.37µ ± 1%   10.15µ ± 2%  -47.63% (p=0.000 n=10)

Encodage plus rapide des Protocol Buffers

J’utilise le code suivant pour mesurer les performances du processus de décodage et d’encodage. Initialement, la méthode Decode() est une simple façade au-dessus du producteur GoFlow2. Elle stocke les données décodées dans la structure en mémoire générée par protoc. Par la suite, certaines données seront encodées directement pendant le décodage des flux. C’est pourquoi nous mesurons à la fois le décodage et l’encodage2.

func BenchmarkDecodeEncodeSflow(b *testing.B) {
    r := reporter.NewMock(b)
    sdecoder := sflow.New(r)
    data := helpers.ReadPcapPayload(b,
        filepath.Join("decoder", "sflow", "testdata", "data-1140.pcap"))

    for _, withEncoding := range []bool{true, false} {
        title := map[bool]string{
            true:  "with encoding",
            false: "without encoding",
        var got []*decoder.FlowMessage
        b.Run(title, func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                got = sdecoder.Decode(decoder.RawFlow{
                    Payload: data,
                    Source: net.ParseIP(""),
                if withEncoding {
                    for _, flow := range got {
                        buf := []byte{}
                        buf = protowire.AppendVarint(buf, uint64(proto.Size(flow)))
                        proto.MarshalOptions{}.MarshalAppend(buf, flow)

L’implémentation Go de référence pour les Protocol Buffers, n’est pas la plus efficace. Pendant longtemps, l’alternative la plus courante était gogoprotobuf. Cependant, le projet est maintenant obsolète. vtprotobuf est un bon remplacement3.

goos: linux
goarch: amd64
pkg: akvorado/inlet/flow
cpu: AMD Ryzen 5 5600X 6-Core Processor
                            │ initial.txt │             bench-2.txt             │
                            │   sec/op    │   sec/op     vs base                │
Netflow/with_encoding-12      12.96µ ± 2%   10.28µ ± 2%  -20.67% (p=0.000 n=10)
Netflow/without_encoding-12   8.935µ ± 2%   8.975µ ± 2%        ~ (p=0.143 n=10)
Sflow/with_encoding-12        19.37µ ± 1%   16.67µ ± 2%  -13.93% (p=0.000 n=10)
Sflow/without_encoding-12     14.62µ ± 3%   14.87µ ± 1%   +1.66% (p=0.007 n=10)

Encodage dynamique des Protocol Buffers

Nous avons désormais une bonne référence départ. Voyons comment encoder nos Protocol Buffers sans un fichier .proto. Le format utilisé est relativement simple et repose beaucoup sur les entiers à longueur variable.

Les entiers à longueur variable sont un moyen efficace d’encoder des entiers non signés en utilisant un nombre variable d’octets, de un à dix, les petites valeurs utilisant moins d’octets. Ils fonctionnent en scindant les entiers par groupe de 7 bits et en utilisant le 8ème bit comme signal de continuation : il est mis à 1 pour tous les groupes sauf le dernier.

Encodage des entiers à longueur variable dans les Protocol Buffers : conversion de 150
Encodage des entiers à longueur variable

Pour notre utilisation, nous avons besoin de deux types seulement : les entiers à longueur variable et les séquences d’octets. Une séquence d’octets est codée en la préfixant par sa longueur sous forme d’entier à longueur variable. Lorsqu’un message est codé, chaque couple clé-valeur est transformé en un enregistrement composé d’un numéro de champ, d’un type et de la valeur. Le numéro de champ et le type sont codés en un seul entier de longueur variable appelé « tag ».

Message codé avec les Protocol Buffers : 3 entiers et 2 séquences d'octets
Message codé avec les Protocol Buffers

Nous utilisons les fonctions bas niveau suivantes pour construire le message codé :

Notre abstraction pour le schéma contient les informations appropriées pour coder un message (ProtobufIndex) et pour générer un fichier de définition de protocole (les champs commençant par Protobuf) :

type Column struct {
    Key       ColumnKey
    Name      string
    Disabled  bool

    // […]
    // For protobuf.
    ProtobufIndex    protowire.Number
    ProtobufType     protoreflect.Kind // Uint64Kind, Uint32Kind, …
    ProtobufEnum     map[int]string
    ProtobufEnumName string
    ProtobufRepeated bool

Nous avons quelques méthodes simples autour des fonctions protowire pour encoder directement les champs lors du décodage des flux. Ils sautent les champs désactivés ou ceux déjà encodés mais non répétables. Voici un extrait du décodeur sFlow:

sch.ProtobufAppendVarint(bf, schema.ColumnBytes, uint64(recordData.Base.Length))
sch.ProtobufAppendVarint(bf, schema.ColumnProto, uint64(recordData.Base.Protocol))
sch.ProtobufAppendVarint(bf, schema.ColumnSrcPort, uint64(recordData.Base.SrcPort))
sch.ProtobufAppendVarint(bf, schema.ColumnDstPort, uint64(recordData.Base.DstPort))
sch.ProtobufAppendVarint(bf, schema.ColumnEType, helpers.ETypeIPv4)

Les champs nécessaires dans la suite du traitement, comme les adresses source et destination, sont stockés non codés dans une structure séparée :

type FlowMessage struct {
    TimeReceived uint64
    SamplingRate uint32

    // For exporter classifier
    ExporterAddress netip.Addr

    // For interface classifier
    InIf  uint32
    OutIf uint32

    // For geolocation or BMP
    SrcAddr netip.Addr
    DstAddr netip.Addr
    NextHop netip.Addr

    // Core component may override them
    SrcAS     uint32
    DstAS     uint32
    GotASPath bool

    // protobuf is the protobuf representation for the information not contained above.
    protobuf      []byte
    protobufSet   bitset.BitSet

Le tableau protobuf contient les données encodées. Il est initialisé avec une capacité de 500 octets pour éviter les redimensionnements pendant l’encodage. Il y a également quelques octets réservés au début pour pouvoir encoder la taille totale en tant qu’entier de longueur variable. Lors de la finalisation de l’encodage, les champs restants sont ajoutés et la longueur du message est insérée dans l’espace libre au début :

func (schema *Schema) ProtobufMarshal(bf *FlowMessage) []byte {
    schema.ProtobufAppendVarint(bf, ColumnTimeReceived, bf.TimeReceived)
    schema.ProtobufAppendVarint(bf, ColumnSamplingRate, uint64(bf.SamplingRate))
    schema.ProtobufAppendIP(bf, ColumnExporterAddress, bf.ExporterAddress)
    schema.ProtobufAppendVarint(bf, ColumnSrcAS, uint64(bf.SrcAS))
    schema.ProtobufAppendVarint(bf, ColumnDstAS, uint64(bf.DstAS))
    schema.ProtobufAppendIP(bf, ColumnSrcAddr, bf.SrcAddr)
    schema.ProtobufAppendIP(bf, ColumnDstAddr, bf.DstAddr)

    // Add length and move it as a prefix
    end := len(bf.protobuf)
    payloadLen := end - maxSizeVarint
    bf.protobuf = protowire.AppendVarint(bf.protobuf, uint64(payloadLen))
    sizeLen := len(bf.protobuf) - end
    result := bf.protobuf[maxSizeVarint-sizeLen : end]
    copy(result, bf.protobuf[end:end+sizeLen])

    return result

Minimiser les allocations est essentiel pour maintenir de bonnes performances. Les tests doivent être exécutés avec le drapeau -benchmem pour surveiller le nombre d’allocations : chacune entraîne un coût indirect pour le ramasse-miette. Le profileur Go est un outil précieux pour identifier les zones du code qui peuvent être optimisées :

$ go test -run=__nothing__ -bench=Netflow/with_encoding \
>         -benchmem -cpuprofile profile.out \
>         akvorado/inlet/flow
goos: linux
goarch: amd64
pkg: akvorado/inlet/flow
cpu: AMD Ryzen 5 5600X 6-Core Processor
Netflow/with_encoding-12             143953              7955 ns/op            8256 B/op        134 allocs/op
ok      akvorado/inlet/flow     1.418s
$ go tool pprof profile.out
File: flow.test
Type: cpu
Time: Feb 4, 2023 at 8:12pm (CET)
Duration: 1.41s, Total samples = 2.08s (147.96%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) web

Après avoir utilisé le schéma interne au lieu du code généré à partir du fichier de définition, les performances se sont améliorées. Cependant, cette comparaison n’est pas tout à fait équitable car moins d’informations sont décodées et, auparavant, GoFlow2 décodait les flux vers sa propre structure qui était ensuite copiée dans notre version.

goos: linux
goarch: amd64
pkg: akvorado/inlet/flow
cpu: AMD Ryzen 5 5600X 6-Core Processor
                            │ bench-2.txt  │             bench-3.txt             │
                            │    sec/op    │   sec/op     vs base                │
Netflow/with_encoding-12      10.284µ ± 2%   7.758µ ± 3%  -24.56% (p=0.000 n=10)
Netflow/without_encoding-12    8.975µ ± 2%   7.304µ ± 2%  -18.61% (p=0.000 n=10)
Sflow/with_encoding-12         16.67µ ± 2%   14.26µ ± 1%  -14.50% (p=0.000 n=10)
Sflow/without_encoding-12      14.87µ ± 1%   13.56µ ± 2%   -8.80% (p=0.000 n=10)

Concernant les tests, nous utilisons : le paquet protoparse analyse le fichier de définition que nous avons construit dynamiquement et le paquet dynamic décode les messages. Jetez un œil à la méthode ProtobufDecode() method pour plus de détails4.

Pour obtenir les chiffres finaux, j’ai aussi optimisé le décodage dans GoFlow2. Il s’appuyait fortement sur binary.Read(). Cette fonction peut utiliser la réflexion dans certains cas et chaque appel alloue un tableau d’octets pour lire les données. En la remplaçant par une version plus efficace, on obtient encore une amélioration notable des performances :

goos: linux
goarch: amd64
pkg: akvorado/inlet/flow
cpu: AMD Ryzen 5 5600X 6-Core Processor
                            │ bench-3.txt  │             bench-4.txt             │
                            │    sec/op    │   sec/op     vs base                │
Netflow/with_encoding-12       7.758µ ± 3%   7.365µ ± 2%   -5.07% (p=0.000 n=10)
Netflow/without_encoding-12    7.304µ ± 2%   6.931µ ± 3%   -5.11% (p=0.000 n=10)
Sflow/with_encoding-12        14.256µ ± 1%   9.834µ ± 2%  -31.02% (p=0.000 n=10)
Sflow/without_encoding-12     13.559µ ± 2%   9.353µ ± 2%  -31.02% (p=0.000 n=10)

Il est maintenant plus facile de collecter de nouvelles données et le composant recevant les flux est désormais plus rapide ! 🚅


La plupart des paragraphes ont été traduits de l’anglais par ChatGPT en utilisant les instructions suivantes : “From now on, I will paste Markdown code in English and I would like you to translate it to French. Keep the markdown markup and enclose the result into a code block. Thanks.” Le résultat a été légèrement édité si nécessaire. Comparé à DeepL, ChatGPT est capable de conserver le formatage, les anglicismes, mais son français est moins bon et il est nécessaire de lui rappeler régulièrement les instructions.

  1. Bien que les champs vides ne sont pas sérialisés en Protocol Buffers, les colonnes vides dans ClickHouse occupent de la place, même si elles se compressent bien. De plus, les champs inutilisés sont toujours décodés et peuvent encombrer l’interface. ↩︎

  2. Il existe une fonction similaire pour NetFlow. Les protocoles NetFlow et IPFIX sont moins complexes à décoder que sFlow car ils utilisent une structure TLV plus simple. ↩︎

  3. vtprotobuf génère un code mieux optimisé en supprimant un niveau d’indirection. Il produit du code codant chaque champ en octets :

    if m.OutIfSpeed != 0 {
        i = encodeVarint(dAtA, i, uint64(m.OutIfSpeed))
        dAtA[i] = 0x6
        dAtA[i] = 0xd8


  4. Il existe également un paquet protoprint pour générer le fichier de définition. Je ne l’ai pas utilisé. ↩︎

06 February, 2023 08:58AM by Vincent Bernat

January 08, 2023

hackergotchi for Charles Plessy

Charles Plessy

Quelqu'un pourrait-il patcher Firefox pour afficher du Markdown ?

Quand Firefox reçoit un fichier dont le type média est text/markdown, il le propose au téléchargement, alors que les autres navigateurs l'affichent comme un fichier texte. Dans le ticket 1319262, il est proposé d'afficher les fichiers Markdown par défaut. Mais il faudrait un patch…

08 January, 2023 12:18AM

December 26, 2022

Vincent Bernat

Gérer une infrastructure avec Terraform, CDKTF et NixOS

Il y a quelques années, j’ai réduit mon infrastructure personnelle au strict minimum. Jusqu’en 2018, elle représentait une douzaine de conteneurs tournant sur un seul serveur Hetzner1. J’ai migré mon courriel vers Fastmail et mes zones DNS vers Gandi. Il ne me restait plus que mon blog à héberger. À ce jour, ma petite infrastructure est composée de 4 machines virtuelles exécutant NixOS sur Hetzner Cloud et Vultr, d’une poignée de zones DNS sur Gandi et Route 53, et de quelques distributions Cloudfront. Elle est gérée par CDK pour Terraform (CDKTF), tandis que les déploiements de NixOS sont gérés par NixOps.

Dans cet article, je présente brièvement Terraform, CDKTF et l’écosystème Nix. J’explique également comment utiliser Nix pour accéder à ces outils dans votre shell afin de les utiliser rapidement.

CDKTF : infrastructure en tant que code

Terraform est un outil d’« infrastructure en tant que code ». Vous pouvez définir votre infrastructure en déclarant des ressources avec le langage HCL. Ce dernier possède quelques fonctionnalités supplémentaires, comme des boucles permettant de déclarer plusieurs ressources à partir d’une liste, des fonctions intégrées que vous pouvez appeler dans les expressions et l’expansion de variables dans les chaînes de caractères. Terraform s’appuie sur un large ensemble de fournisseurs pour gérer les ressources.

Gérer des serveurs

Voici un court exemple utilisant le fournisseur pour Hetzner Cloud pour créer une machine virtuelle :

variable "hcloud_token" {
  sensitive = true
provider "hcloud" {
  token = var.hcloud_token

resource "hcloud_server" "web03" {
  name = "web03"
  server_type = "cpx11"
  image = "debian-11"
  datacenter = "nbg1-dc3"

resource "hcloud_rdns" "rdns4-web03" {
  server_id =
  ip_address = hcloud_server.web03.ipv4_address
  dns_ptr = ""

resource "hcloud_rdns" "rdns6-web03" {
  server_id =
  ip_address = hcloud_server.web03.ipv6_address
  dns_ptr = ""

L’expressivité de HCL est assez limitée et je trouve qu’un langage généraliste est plus pratique pour décrire les ressources. C’est là qu’intervient CDK pour Terraform : vous pouvez gérer votre infrastructure à l’aide de votre langage de programmation préféré, notamment TypeScript, Go et Python. Voici l’exemple précédent utilisant CDKTF et TypeScript :

import { App, TerraformStack, Fn } from "cdktf";
import { HcloudProvider } from "./.gen/providers/hcloud/provider";
import * as hcloud from "./.gen/providers/hcloud";

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    const hcloudToken = new TerraformVariable(this, "hcloudToken", {
      type: "string",
      sensitive: true,
    const hcloudProvider = new HcloudProvider(this, "hcloud", {
      token: hcloudToken.value,

    const web03 = new hcloud.server.Server(this, "web03", {
      name: "web03",
      serverType: "cpx11",
      image: "debian-11",
      datacenter: "nbg1-dc3",
      provider: hcloudProvider,
    new hcloud.rdns.Rdns(this, "rdns4-web03", {
      serverId: Fn.tonumber(,
      ipAddress: web03.ipv4Address,
      dnsPtr: "",
      provider: hcloudProvider,
    new hcloud.rdns.Rdns(this, "rdns6-web03", {
      serverId: Fn.tonumber(,
      ipAddress: web03.ipv6Address,
      dnsPtr: "",
      provider: hcloudProvider,

const app = new App();
new MyStack(app, "cdktf-take1");

La commande de cdktf synth génère un fichier de configuration pour Terraform, terraform plan prévisualise les changements et terraform apply les applique. Maintenant que vous disposez d’un langage généraliste, vous pouvez utiliser des fonctions.

Gérer des enregistrements DNS

Si l’utilisation de CDKTF pour 4 serveurs web peut sembler un peu exagérée, il en va tout autrement lorsqu’il s’agit de gérer quelques zones DNS. Avec DNSControl, qui utilise JavaScript comme langage, j’ai pu définir la zone avec ce bout de code :

D("", REG_NONE, DnsProvider(DNS_BIND, 0), DnsProvider(DNS_GANDI),
  FastMailMX('', {subdomains: ['vincent']}),

Cela produit 38 enregistrements. Avec CDKTF, j’écris :

new Route53Zone(this, "",
  .www("@", servers)
  .www("vincent", servers)
  .www("media", servers)

Toute la magie est située dans les fonctions appelées. Vous pouvez regarder le fichier dns.ts dans le dépôt cdktf-take1 pour comprendre comment cela fonctionne. Rapidement :

  • Route53Zone() crée une zone sur Route 53,
  • sign() signe la zone avec une clef maître,
  • registrar() inscrit la zone auprès du registre de domaines et configure DNSSEC,
  • www() crée les enregistrements A et AAAA pour les serveurs web,
  • fastmailMX() crée les enregistrements MX et d’autres enregistrements liés pour configurer Fastmail en tant que fournisseur de courriel.

Voici le contenu de la fonction fastmailMX(). Elle génère quelques enregistrements et retourne la zone en cours pour faciliter le chaînage :

fastmailMX(subdomains?: string[]) {
  (subdomains ?? [])
    .concat(["@", "*"])
    .forEach((subdomain) =>
      this.MX(subdomain, [
  this.TXT("@", "v=spf1 ~all");
  ["mesmtp", "fm1", "fm2", "fm3"].forEach((dk) =>
    this.CNAME(`${dk}._domainkey`, `${dk}.${}`)
  this.TXT("_dmarc", "v=DMARC1; p=none; sp=none");
  return this;

Je vous encourage à parcourir le dépôt pour plus de détails !

À propos de Pulumi

Ma première tentative autour de Terraform a été d’utiliser Pulumi. Vous pouvez trouver cette tentative sur GitHub. C’est assez similaire à ce que je fais actuellement avec CDKTF. La principale différence est que j’utilise Python au lieu de TypeScript2 car ce dernier ne m’était pas familier à l’époque.

Pulumi est antérieur à CDKTF et il utilise une approche légèrement différente. CDKTF génère une configuration pour Terraform (au format JSON au lieu de HCL), laissant la planification, la gestion des états et le déploiement à ce dernier. Il est donc lié aux limites de ce qui peut être exprimé par Terraform, notamment lorsque vous devez transformer des données obtenues d’une ressource à une autre3. Pulumi a besoin de fournisseurs spécifiques pour chaque ressource. De nombreux fournisseurs encapsulent des fournisseurs Terraform.

Bien que Pulumi offre une bonne expérience utilisateur, je suis passé à CDKTF car écrire des fournisseurs pour Pulumi est une corvée. CDKTF ne nécessite pas de passer par cette étape. En dehors des grands acteurs (AWS, Azure et Google Cloud), l’existence, la qualité et la fraîcheur des fournisseurs Pulumi sont inégales. La plupart des fournisseurs s’appuient sur un fournisseur Terraform et il se peut qu’ils soient en retard de quelques versions, qu’il leur manque quelques ressources ou qu’ils présentent des bogues qui leur sont propres.

Lorsqu’un fournisseur n’existe pas, vous pouvez en écrire un à l’aide de la bibliothèque pulumi-terraform-bridge. Le projet Pulumi fournit un modèle à cet effet. J’ai eu une mauvaise expérience avec celui-ci lors de l’écriture de fournisseurs pour Gandi et Vultr : le Makefile installe automatiquement Pulumi en utilisant curl | sh et ne fonctionne pas avec /bin/sh. Il y a un manque d’intérêt pour les contributions communautaires4 ou même pour les fournisseurs pour les acteurs tiers.

NixOS & NixOps

Nix est un langage de programmation purement fonctionnel. Nix est aussi le nom du gestionnaire de paquets qui est construit au-dessus du langage Nix. Il permet aux utilisateurs d’installer des paquets de manière déclarative. nixpkgs est un dépôt de paquets. Vous pouvez installer Nix au-dessus d’une distribution Linux ordinaire. Si vous voulez plus de détails, une bonne ressource est le site officiel, notamment la section « Apprendre ». La courbe d’apprentissage est rude, mais la récompense est grande.

NixOS : distribution Linux déclarative

NixOS est une distribution Linux construite au-dessus du gestionnaire de paquets Nix. Voici un bout de configuration pour ajouter quelques paquets :

environment.systemPackages = with pkgs;

Il est possible de modifier une dérivation5 existante pour utiliser une version différente, activer une fonctionnalité spécifique ou appliquer un correctif. Voici comment j’active et configure Nginx pour désactiver le module stream, ajouter le module de compression Brotli et ajouter le module d’anonymisation des adresses IP. De plus, au lieu d’utiliser OpenSSL 3, je continue à utiliser OpenSSL 1.16.

services.nginx = {
  enable = true;

  package = (pkgs.nginxStable.override {
    withStream = false;
    modules = with pkgs.nginxModules; [
    openssl = pkgs.openssl_1_1;

Si vous avez besoin d’ajouter certaines modifications, c’est également possible. À titre d’exemple, voici comment j’ai corrigé en avance les failles de sécurité découvertes en 2019 dans Nginx en attendant que cela soit corrigé dans NixOS7 :

services.nginx.package = pkgs.nginxStable.overrideAttrs (old: {
  patches = oldAttrs.patches ++ [
    # HTTP/2: reject zero length headers with PROTOCOL_ERROR.
    (pkgs.fetchpatch {
      url =[].patch;
      sha256 = "a48190[…]";
    # HTTP/2: limited number of DATA frames.
    (pkgs.fetchpatch {
      url =[].patch;
      sha256 = "af591a[…]";
    #  HTTP/2: limited number of PRIORITY frames.
    (pkgs.fetchpatch {
      url =[].patch;
      sha256 = "1ad8fe[…]";

Si cela vous intéresse, jetez un coup d’œil à ma configuration relativement réduite : common.nix contient la configuration à appliquer sur tous les serveurs (SSH, utilisateurs, paquets communs), web.nix contient la configuration pour les serveurs web et isso.nix exécute Isso dans un conteneur systemd.

NixOps : outil de déploiement pour NixOS

Sur un seul nœud, la configuration de NixOS se trouve dans le fichier /etc/nixos/configuration.nix. Après l’avoir modifiée, vous devez exécuter la commande nixos-rebuild switch. Nix va chercher toutes les dépendances possibles dans le cache binaire et construit le reste. Il crée une nouvelle entrée dans le menu du chargeur de démarrage et active la nouvelle configuration.

Pour gérer plusieurs nœuds, il existe plusieurs options, dont NixOps, deploy-rs, Colmena et morph. Je ne les connais pas toutes, mais de mon point de vue, les différences ne sont pas si importantes. Il est également possible de construire un tel outil soi-même car Nix fournit les blocs de construction les plus importants : nix build et nix copy. NixOps est l’un des premiers outils publiés mais je vous encourage à explorer les alternatives.

La configuration de NixOps est écrite avec la langage Nix. Voici une configuration simplifiée pour déployer, et, à l’aide des fonctions server et web :

  server = hardware: name: imports: {
    deployment.targetHost = "${name}";
    networking.hostName = name;
    networking.domain = "";
    imports = [ (./hardware/. + "/${hardware}.nix") ] ++ imports;
  web = hardware: idx: imports:
    server hardware "web${lib.fixedWidthNumber 2 idx}" ([ ./web.nix ] ++ imports);
in {
  network.description = "Luffy infrastructure";
  network.enableRollback = true;
  defaults = import ./common.nix;
  znc01 = server "exoscale" [ ./znc.nix ];
  web01 = web "hetzner" 1 [ ./isso.nix ];
  web02 = web "hetzner" 2 [];

Connecter le tout avec Nix

L’écosystème Nix est une solution unifiée aux différents problèmes liés à la gestion des logiciels et des configurations. Les environnements de développement déclaratifs et reproductibles en constituent une caractéristique très intéressante. Cela ressemble aux environnements virtuels de Python, mais ils ne sont pas spécifiques à un langage.

Courte introduction aux « flakes » Nix

J’utilise les « flakes », une nouvelle fonctionnalité de Nix qui améliore la reproductibilité en fixant toutes les dépendances et en isolant le processus de construction. Bien que cette fonctionnalité soit marquée comme expérimentale8, elle est de plus en plus populaire et vous pouvez trouver flake.nix et flake.lock à la racine de certains dépôts.

A titre d’exemple, voici le contenu du flake.nix livré avec Snimpy, un outil SNMP interactif pour Python reposant sur libsmi, une bibliothèque C :

  inputs = {
    nixpkgs.url = "nixpkgs";
    flake-utils.url = "github:numtide/flake-utils";
  outputs = { self, ... }@inputs:
    inputs.flake-utils.lib.eachDefaultSystem (system:
        pkgs = inputs.nixpkgs.legacyPackages."${system}";
        # nix build
        packages.default = pkgs.python3Packages.buildPythonPackage {
          name = "snimpy";
          src = self;
          preConfigure = ''echo "1.0.0-0-000000000000" > version.txt'';
          checkPhase = "pytest";
          checkInputs = with pkgs.python3Packages; [ pytest mock coverage ];
          propagatedBuildInputs = with pkgs.python3Packages; [ cffi pysnmp ipython ];
          buildInputs = [ pkgs.libsmi ];
        # nix run + nix shell
        apps.default = { 
          type = "app";
          program = "${self.packages."${system}".default}/bin/snimpy";
        # nix develop
        devShells.default = pkgs.mkShell {
          name = "snimpy-dev";
          buildInputs = [

Si Nix est installé sur votre système :

  • nix run github:vincentbernat/snimpy exécute Snimpy,
  • nix shell github:vincentbernat/snimpy fournit un shell avec Snimpy prêt à être utilisé,
  • nix build github:vincentbernat/snimpy construit le paquet Python,
  • nix develop . fournit un shell pour développer autour de Snimpy depuis un clône du dépôt9.

Pour plus d’informations sur les flakes, regardez le tutoriel de Tweag.

Nix et CDKTF

A la racine du dépôt que j’utilise pour CDKTF, il y a un fichier flake.nix pour configurer un shell avec Terraform et CDKTF installés et avec les variables d’environnement nécessaires pour automatiser mon infrastructure.

Terraform est déjà présent dans nixpkgs, mais je dois appliquer une rustine sur le fournisseur Gandi. Ce n’est pas un problème avec Nix !

terraform = pkgs.terraform.withPlugins (p: [
    (old: {
      src = pkgs.fetchFromGitHub {
        owner = "vincentbernat";
        repo = "terraform-provider-gandi";
        rev = "feature/livedns-key";
        hash = "sha256-V16BIjo5/rloQ1xTQrdd0snoq1OPuDh3fQNW7kiv/kQ=";

CDKTF est écrit en TypeScript. J’ai un fichier package.json avec toutes les dépendances nécessaires, y compris celles pour utiliser TypeScript comme langage cible :

  "name": "cdktf-take1",
  "version": "1.0.0",
  "main": "main.js",
  "types": "main.ts",
  "private": true,
  "dependencies": {
    "@types/node": "^14.18.30",
    "cdktf": "^0.13.3",
    "cdktf-cli": "^0.13.3",
    "constructs": "^10.1.151",
    "eslint": "^8.27.0",
    "prettier": "^2.7.1",
    "ts-node": "^10.9.1",
    "typescript": "^3.9.10",
    "typescript-language-server": "^2.1.0"

J’utilise Yarn pour obtenir un fichier yarn.lock qui peut ensuite être utilisé directement pour construire la dérivation contenant toutes les dépendances :

nodeEnv = pkgs.mkYarnModules {
  pname = "cdktf-take1-js-modules";
  version = "1.0.0";
  packageJSON = ./package.json;
  yarnLock = ./yarn.lock;

L’étape suivant est de générer les fournisseurs CDKTF à partir des fournisseurs Terraform et de les inclure dans une dérivation :

cdktfProviders = pkgs.stdenvNoCC.mkDerivation {
  name = "cdktf-providers";
  nativeBuildInputs = [
  src = nix-filter {
    root = ./.;
    include = [ ./cdktf.json ./tsconfig.json ];
  buildPhase = ''
    export HOME=$(mktemp -d)
    export PATH=${nodeEnv}/node_modules/.bin:$PATH
    ln -nsf ${nodeEnv}/node_modules node_modules

    # Build all providers we have in terraform
    for provider in $(cd ${terraform}/libexec/terraform-providers; echo */*/*/*); do
      echo "Build $provider@$version"
      cdktf provider add --force-local $provider@$version | cat
    echo "Compile TS → JS"
  installPhase = ''
    mv .gen $out
    ln -nsf ${nodeEnv}/node_modules $out/node_modules

Enfin, nous définissons l’environnement de développement :

devShells.default = pkgs.mkShell {
  name = "cdktf-take1";
  buildInputs = [
  shellHook = ''
    # No telemetry
    # No autoinstall of plugins
    # Do not check version
    # Access to node modules
    export PATH=$PWD/node_modules/.bin:$PATH
    ln -nsf ${nodeEnv}/node_modules node_modules
    ln -nsf ${cdktfProviders} .gen

    # Credentials
    for p in \
      njf.nznmba.pbz/Nqzvavfgengbe \
      urgmare.pbz/ivaprag@oreang.pu \
      ihyge.pbz/ihyge@ivaprag.oreang.pu; do
        eval $(pass show $(echo $p | tr 'A-Za-z' 'N-ZA-Mn-za-m') | grep '^export')
    eval $(pass show personal/cdktf/secrets | grep '^export')
    export TF_VAR_hcloudToken="$HCLOUD_TOKEN"
    export TF_VAR_vultrApiKey="$VULTR_API_KEY"

Les dérivations listées dans buildInputs sont disponibles dans le shell fourni. Le contenu de shellHook est exécuté lors du démarrage du shell. Il établit des liens symboliques pour rendre disponible l’environnement JavaScript construit à une étape précédente, ainsi que les fournisseurs CDKTF générés. Il exporte également toutes les informations d’identification10.

J’utilise également direnv avec un fichier .envrc pour passer automatiquement dans l’environnement de développement. Cela permet également à ce dernier d’être disponible depuis Emacs, notamment lors de l’utilisation de lsp-mode pour obtenir les complétions. nix develop . permet aussi d’activer manuellement l’environnement.

J’utilise les commandes suivantes pour déployer11 :

$ cdktf synth
$ cd cdktf.out/stacks/cdktf-take1
$ terraform plan --out plan
$ terraform apply plan
$ terraform output -json > ~-automation/nixops-take1/cdktf.json

La dernière commande produit un fichier JSON contenant les données nécessaires pour finir le déploiement avec NixOps.


Le fichier JSON exporté par Terraform contient la liste des serveurs avec quelques attributs :

  "hardware": "hetzner",
  "ipv4Address": "",
  "ipv6Address": "2a01:4ff:f0:b91::1",
  "name": "",
  "tags": [

Dans le fichier network.nix, cette liste est importée et transformée en un ensemble d’attributs décrivant les serveurs. Une version simplifiée ressemble à cela :

  lib = inputs.nixpkgs.lib;
  shortName = name: builtins.elemAt (lib.splitString "." name) 0;
  domainName = name: lib.concatStringsSep "." (builtins.tail (lib.splitString "." name));
  server = hardware: name: imports: {
    networking = {
      hostName = shortName name;
      domain = domainName name;
    deployment.targetHost = name;
    imports = [ (./hardware/. + "/${hardware}.nix") ] ++ imports;
  cdktf-servers-json = (lib.importJSON ./cdktf.json).servers.value;
  cdktf-servers = map
        tags-maybe-import = map (t: ./. + "/${t}.nix") s.tags;
        tags-import = builtins.filter (t: builtins.pathExists t) tags-maybe-import;
        name = shortName;
        value = server s.hardware tags-import;
  // []
} // builtins.listToAttrs cdktf-servers

Pour web05, on obtient ceci :

web05 = {
  networking = {
    hostName = "web05";
    domainName = "";
  deployment.targetHost = "";
  imports = [ ./hardware/hetzner.nix ./web.nix ];

Comme pour CDKTF, à la racine du dépôt que j’utilise pour NixOps, il y a un fichier flake.nix pour fournir un shell avec NixOps configuré. Comme NixOps ne supporte pas les déploiements progessifs, j’utilise généralement ces commandes pour déployer sur un unique serveur12 :

$ nix flake update
$ nixops deploy --include=web04
$ ./tests

Si les tests se déroulent sans soucis, je déploie les autres nœuds un par un avec la commande suivante :

$ (set -e; for h in web{03..06}; do nixops deploy --include=$h; done)

La commande nixops deploy déploie tous les serveurs en parallèle et peut donc provoquer une panne si tous les serveurs Nginx sont indisponibles au même moment.

Cet article est en chantier depuis trois ans. Le contenu a été mis à jour et affiné au fur et à mesure de mes expérimentations. Il y a encore beaucoup à explorer13, mais j’estime que le contenu est désormais suffisant pour être publié ! 🎄

  1. C’était un AMD Athlon 64 X2 5600+ avec 2 Go de RAM et 2 disques de 400 Go en RAID logiciel. Je payais quelque chose autour de 59 € par mois pour cela. Si c’était une bonne affaire en 2008, en 2018, ce n’était plus rentable. Il fonctionnait sous Debian Wheezy avec Linux-VServer pour l’isolation, tous deux dépassés en 2018. ↩︎

  2. Je n’ai pas non plus utilisé Python car le support de Poetry dans Nix était cassé quand j’ai commencé à essayer d’utiliser CDKTF↩︎

  3. Pulumi peut appliquer des fonctions arbitraires à l’aide de apply(). Cela permet de transformer les données qui ne sont pas connues lors de l’étape de planification. Terraform a des fonctions pour un usage similaire mais elles sont plus limitées. ↩︎

  4. Les deux modifications mentionnées ne sont pas encore fusionnées. La seconde est remplacée par la PR #61, soumise deux mois plus tard, qui impose l’utilisation de /bin/bash. J’ai également soumis la PR #56, qui a été fusionnée 4 mois plus tard et rapidement annulée sans explication. ↩︎

  5. Grosso modo, une dérivation est un synonyme pour paquet dans l’écosystème Nix↩︎

  6. OpenSSL 3 a de nombreux problèmes de performance↩︎

  7. NixOS peut être un peu lent à intégrer les correctifs car il est nécessaire de reconstruire une partie du cache binaire. Dans ce cas précis, cela a été rapide : la vulnérabilité et les correctifs ont été publiés le 13 août 2019 et disponibles dans NixOS le 15 août. À titre de comparaison, Debian n’a publié la version corrigée que le 22 août, ce qui est inhabituellement tardif. ↩︎

  8. Comme les flakes sont expérimentaux, de nombreuses documentations ne les utilisent pas et c’est un aspect supplémentaire à apprendre. ↩︎

  9. Comme dans les autres exemples, il est possible de remplacer . par github:vincentbernat/snimpy. Cependant, obtenir les dépendances de Snimpy sans son code source a peu d’intérêt. ↩︎

  10. J’utilise le gestionnaire de mots de passe pass. Le nom des mots de passe sont brouillés uniquement pour éviter les courriers indésirables. ↩︎

  11. La commande cdktf sait appeler les commandes terraform, mais je préfère les utiliser directement car elles sont plus flexibles. ↩︎

  12. Si le changement est risqué, je désactive le serveur avec CDKTF. Cela le retire des enregistrements DNS. ↩︎

  13. Je voudrais remplacer NixOps avec une alternative gérant les déploiements progressifs et les tests. Je voudrais aussi passer à Nomad ou Kubernetes pour déployer les applications. ↩︎

26 December, 2022 03:18PM by Vincent Bernat

December 16, 2022

hackergotchi for Charles Plessy

Charles Plessy

Les grots mots dans Debian.

Une conversation sur la list debian-project a attiré mon attention sur un mot italien signifiant quelque chose comme « auriez-vous la gentillesse d'aller voir ailleurs ? », mais en version plus directe et vulgaire. J'ai ensuite utilisé pour étudier plus en détail son emploi.

Je l'ai trouvé dans :

  • le code source de XEmacs ;
  • une liste de gros mots pour policer les conversations dans BZFlag ;
  • le générateur aléatoire de phrases PolyGen ;
  • le code source du jeu de plateau Tagua ;
  • une base de données d'épigrammes vulguaires pour la plateforme éducative WIMS ;
  • le jeu de mots croisés parololottero ;
  • une base de données d'épigrammes vulguaires pour messages de bienvenue ou signatures de courriels ;
  • des listes de mots de passes trop fréquents ;
  • un commentaire destiné à un déonmmé Wolf dans le code source d'un autre programme ;
  • a collection of rude gestures in the xwrists package.

Ce fut une promenade rafraîchissante et récréactive dans l'univers des paquets Debian.

16 December, 2022 01:00PM

November 08, 2022

hackergotchi for Aur&#233;lien Jarno

Aurélien Jarno

riscv64 porterbox

For quite some time, many people asked for a riscv64 porterbox. Now we've got one called

A big thanks to SiFive for providing the HiFive Unmatched board and OSUOSL for assembling the hardware and hosting it.

08 November, 2022 10:52PM by aurel32

October 04, 2022

hackergotchi for Debian France

Debian France

Évènements fin 2022 - début 2023

Bonjour à toutes et tous,

Dans les mois qui viennent, trois évènements auront lieu dans lesquels l'association Debian France tiendra un stand afin d'y faire de la promotion du projet Debian, mais aussi pour y proposer quelques goodie.

Comme chaque évènement, nous sommes à la recherche de volontaires pour tenir le stand Debian France. Pour chacun d'eux, un Framadate est ouvert pour recenser les volontaires et leurs disponibilités.

1) Open Source Experience - Paris

2) Capitole du libre - Toulouse

3) FOSDEM - Bruxelles (Belgique)

  • Dates : 4 et 5 Février 2023
  • Site de l'évènement :
  • Il s'agit d'un salon ou le stand Debian est tenu par de membres Debian France mais aussi des contributeurs d'autres pays. La page d'inscription n'est pas encore ouverte, mais sera disponible sur le Wiki Debian à l'adresse suivante :

N'hésitez pas à contacter l'association pour toutes question à l'adresse ou bien sur IRC, réseau OFTC, canal #debian-france.

Bien à vous et en espérant vous compter parmi nous,

Quentin et Alban - Secrétaires Debian France

04 October, 2022 10:42PM

August 07, 2022

hackergotchi for Aur&#233;lien Jarno

Aurélien Jarno

GNU libc 2.34 in unstable

The GNU libc version 2.34 has just been accepted into unstable. Getting it ready has been more challenging than other versions, as this version integrates a few libraries (libpthread, libdl, libutil, libanl) into libc. While this is handled transparently at runtime, there are a few corner cases at build time:

  • For backwards compatibility, empty static archives (e.g. libpthread.a) are provided, so that the linker options keep working. However a few cmake files shipped in some packages still reference the path to the shared library symlink (e.g. which is now removed.

  • A few symbols have also been moved from libresolv to libc and their __ prefix removed. While compatibily symbols are provided in the shared library for runtime compatiblity, this does not work at link time for static libraries referencing this symbol.

The next challenge is to get it migrating into testing!

For the adventurous persons, GNU libc 2.35 is now available in experimental. And as people keep asking, the goal is to get the just released GNU libc 2.36 into Bookworm.

07 August, 2022 09:25PM by aurel32

February 24, 2022

hackergotchi for Charles Plessy

Charles Plessy

Types media, cuvée 2022.

En début d'année j'ai mis à jour une centaine de types de media associés à des extensions de nom de fichier dans le fichier /etc/mime.types, distribué par le paquet media-types. La plupart des changements sont des additions en provenance des déclarations récentes à'IANA. Les thèmes les plus répendus sont les télécomunications, la sécurité informatique, le commerce, la santé, et l'automatisation industrielle. L'énorme majorité provient du monde occidental. Le reste du monde a-t-il décidé d'avancer sans nous ?

24 February, 2022 12:32PM

February 08, 2022

Stéphane Blondon

Hello Debian en Brainfuck est un service qui permet d’afficher des captures d’écran de logiciels. C’est assez pratique pour se faire une idée d’une interface par exemple. Une capture d’écran montrait déjà l’interpréteur Brainfuck beef affichant un classique
Hello Word!. Mais on peut aussi personnaliser en affichant un
Hello Debian! :

Utilisation de beef


Brainfuck est un langage dont l’intérêt principal est d’être difficilement compréhensible par un humain. Pas la peine de s’étendre sur ses spécificités, wikipedia le fait très bien. Il ressemble à une machine de Turing: le programme déplace un curseur dans un tableau et modifie les valeurs contenues dans les cellules du tableau.
Voici une version commentée du programme utilisé (le début est quasi-identique au hello world fourni sur la page wikipedia puisqu’on veut écrire la même chose) :

++++++++++          affecte 10 à la case 0
[                   boucle initialisant des valeurs au tableau 
   >                avance à la case 1 
   +++++++          affecte 7 à la case 1
   >                avance à la case 2
   ++++++++++       affecte 10 à la case 2 
   >                avance à la case 3
   +++              affecte 3 à la case 3
   >                avance à la case 4
   +                affecte 1 à la case 4
   >                avance à la case 5
   +++++++++++      affecte 11 à la case 5
   <<<<<            retourne à la case 0
   -                enlève 1 à la case 0
]                   jusqu'à ce que la case 0 soit = à 0

La boucle initialise le tableau en 10 itérations et son état est alors :

Case 0 1 2 3 4 5
Valeur 0 70 100 30 10 110

Suite du programme :

>++                 ajoute 2 à la case 1 (70 plus 2 = 72)
.                   imprime le caractère 'H' (72)
>+                  ajoute 1 à la case 2 (100 plus 1 = 101)
.                   imprime le caractère 'e' (101)
+++++++             ajoute 7 à la case 2 (101 plus 7 = 108)
.                   imprime le caractère 'l'  (108)
.                   imprime le caractère 'l'  (108)
+++                 ajoute 3 à la case 2 (108 plus 3 = 111)
.                   imprime le caractère 'o' (111)
>++                 ajoute 2 à la case 3 (30 plus 2 = 32)
.                   imprime le caractère ' '(espace) (32)

<<<                 revient à la case 0
++                  ajoute 2 à la case 0 (0 plus 2 = 2)
[                   une boucle
   >                avance à la case 1 
   --               enlève 4 à la case 1 (72 moins 4 = 68)
   >                avance à la case 2
   -----            enlève 10 à la case 2 (111 moins 10 = 101)
   <<               retourne à la case 0
   -                enlève 1 à la case 0
]                   jusqu'à ce que la case 0 soit = à 0

>                   va case 1
.                   affiche 'D'
>                   va case 2
.                   affiche 'e'
---                 enlève 3 à la case 2 (101 moins 3 = 98)
.                   affiche 'b'
>>>                 va case 5
-----               enlève 5 à la case 5
.                   affiche 'i'
<<<                 va case 2
-                   enlève 1 à la case 2
.                   affiche 'a'
>>>                 va case 5
+++++               ajoute 5 à la case 5
.                   affiche 'n'
<<                  va à la case 3
+                   ajoute 1 à la case 3
.                   affiche un point d'exclamation

>                   va à la case 4
.                   imprime le caractère 'nouvelle ligne' (10)

Une capture de l’exécution du programme est disponible pour les interpréteurs beef et hsbrainfuck sur
Les images disponibles sur sont aussi réutilisées par le service (par exemple et par certains gestionnaires de paquets.
Si vous avez envie d’ajouter des captures d’écran à des paquets qui n’en auraient pas (les plus courants sont déjà faits), sachez que l’affichage n’est pas direct car il y a une validation manuelle des images envoyées. Le délai reste limité à quelques jours (voire à la journée).

08 February, 2022 07:50PM by ascendances

December 25, 2021

hackergotchi for Aur&#233;lien Jarno

Aurélien Jarno

James Webb Space Telescope launched!

The long awaited James Webb Space Telescope has finally been successfully launched today. It is a Xmas gift for many people who have been waiting for it for many years.

On a more personal side, I am happy and proud to have contributed to a tiny part of a tiny piece of software of this huge project over the last 15 years: the Instrument Performance Simulator of the NIRSpec instrument.

25 December, 2021 03:10PM by aurel32

April 18, 2021

Florent Gallaire

Debian et RMS, la montagne a accouché d’une souris

Suite au retour de Richard Stallman (RMS) au board de la Free Software Foundation (FSF), pas moins de neuf anciens Debian Project Leader (DPL) – Neil McGovern, Stefano Zacchiroli, Ian Jackson, Lucas Nussbaum, Martin Michlmayr, Mehdi Dogguy, Sam Hartman, Sam Hocevar et Steve McIntyre – ainsi que l’actuel DPL Jonathan Carter, ont signé une lettre ouverte initiée par Molly de Blanc et intitulée An open letter to remove Richard M. Stallman from all leadership positions.

Rappelons que Richard Stallman n’est rien de moins que l’inventeur des quatre libertés essentielles définissant le logiciel libre et du concept juridique de copyleft, ainsi que le fondateur de la Free Software Foundation et du projet GNU (Linux sans le noyau).

Richard Stallman à la Fête de l'Humanité 2014 (par Thesupermat)

Steve Langasek a ensuite soumis une General Resolution (GR) proposant que la personne morale Debian soutienne officiellement la prise de position de ses leaders. Mais rien ne s’est passé comme prévu, et ce qui devait être un référendum consensuel a tourné au pugilat sur la mailing list debian-vote en mars et en avril, ces discussions publiques n’étant bien sûr que la partie émergée de l’iceberg.

Huit options ont finalement été soumises au vote :

  1. « Call for the FSF board removal, as in« 
  2. « Call for Stallman’s resignation from all FSF bodies »
  3. « Discourage collaboration with the FSF while Stallman is in a leading position »
  4. « Call on the FSF to further its governance processes »
  5. « Support Stallman’s reinstatement, as in« 
  6. « Denounce the witch-hunt against RMS and the FSF »
  7. « Debian will not issue a public statement on this issue »
  8. « Further Discussion » (default option)

Pour faire court, c’est l’option 7 qui l’a emporté : Debian will not issue a public statement on this issue. Voici une représentation du résultat du scrutin qui utilise la méthode Condorcet :

Résultat du vote de la GR concernant Richard Stallman

En s’essayant à un peu de taxinomie politique, on constate que les options peuvent être classées en trois groupes. Les options explicites, anti et pro parlent d’elles-mêmes, mais comment connaître l’orientation d’une option implicite ? Sans la condamner, mais en refusant de participer à une chasse aux sorcières, l’option 7 constitue bien un soutien implicite à RMS. Le nombre de voix par rapport à l’option par défaut Further Discussion est le moyen le plus simple d’évaluer ce vote :

  • anti-RMS explicite (droite) : options 1, 2, 3 et 4 pour 203 + 222 + 219 + 221 = 216 voix de moyenne
  • pro-RMS implicite (centre) : option 7 pour 277 voix
  • pro-RMS explicite (gauche) : options 5 et 6 pour 52 + 84 = 68 voix de moyenne

Concernant les suffrages exprimés, il n’y a donc pas eu de vol de scrutin et la méthode Condorcet évite effectivement les problèmes de type Ballon d’or 2018, où l’éparpillement des voix d’un camp permet à une option minoritaire de l’emporter. En effet, une large majorité des votants voulait la peau de RMS, mais cette large majorité voulait aussi préserver le projet Debian d’une explosion probable, et a permis à l’option centriste de l’emporter de justesse.

Cependant, le système de vote de Debian a failli sur un point fondamental mais qui n’avait pourtant jamais semblé poser problème jusqu’ici. En effet, un vote concernant une General Resolution n’est pas secret, ce qui est une pratique totalitaire qui doit être changée. On peut ainsi consulter le détail des votes de chaque votant. S’agissant d’un sujet aussi controversé, la sincérité du scrutin a très probablement été altérée par un taux de participation inférieur à ce qu’il aurait pu être, avec seulement 420 votants sur 1018 Debian Developers.


18 April, 2021 07:19AM by fgallaire

Highvoltage 2.0 : Jonathan Carter réélu DPL pour 2021

Jonathan Carter (Highvoltage) vient d’être réélu Debian Project Leader (DPL). Il va donc pouvoir continuer le travail commencé l’année dernière.

La victoire de Jonathan est sans surprise, car sans réelle opposition, Sruthi Chandran incarnant pour la seconde année consécutive une candidature de témoignage – non-homme, non-blanc -, mais n’étant malheureusement pas une prétendante crédible à la victoire. Voici une représentation du résultat du scrutin qui utilise la méthode Condorcet :

DPL 2021
Bravo à toi Jonathan, et bonne chance dans la mise en œuvre de ton programme !

18 April, 2021 01:47AM by fgallaire

March 21, 2021

Quel DPL pour 2021 ?

Le temps passe vite, et cela fait déjà presque un an que Jonathan Carter a été élu Debian Project Leader (DPL). Chaque développeur Debian pouvait donc se porter candidat entre le 7 et le 13 mars à la suite du traditionnel appel à candidatures.

Le 11 mars Jonathan exprimait le souhait de se représenter, tout comme Sruthi Chandran, elle aussi déjà candidate l’année dernière, dans ce qui constituera un remake de l’élection 2020.

Il y aura donc deux candidats cette année :

Les presque mille développeurs Debian seront libres de voter du 4 au 17 avril lors d’un vote utilisant la méthode Condorcet.

Vous pouvez retrouver tous les débats de la campagne sur la mailing list debian-vote.

21 March, 2021 01:02PM by fgallaire

November 17, 2020

September 27, 2020

Stéphane Blondon

Effet boomerang pour les contributions à du logiciel libre

Lorsqu’on corrige une anomalie ou qu’on a ajoute une fonctionnalité à un logiciel ou une bibliothèque, on peut la garder pour soi ou la partager. La deuxième solution demande un peu plus d’efforts à court terme mais est préférable à long terme.

Le délai de retour d’un correctif ou d’une amélioration dépend de l’endroit où il est proposé : plus il est poussé loin et plus il va mettre de temps à revenir mais le nombre de personnes/machines bénéficiant du correctif sera plus grand.

Les différentes possibilités

Effet boomerang d'une contribution

Gardé pour soi

Cette méthode est absente du schéma puisqu’elle consiste à ne pas envoyer la modification à l’extérieur. C’est le plus rapide à mettre en œuvre, d’autant plus que la qualité du correctif n’est validée qu’en interne (juste soi-même ou par l’équipe intégrant la modification). Diverses façons d’arriver à ses fins sont possibles comme surcharger la signature de la méthode qui pose problème, attraper l’erreur non traitée correctement, intégrer la bibliothèque dans le code et la modifier directement (vendoring), etc.

Par contre, personne d’autre ne bénéficie du correctif et personne d’extérieur ne fera une revue de code.

Publication solitaire

La vitesse de mise au point est équivalente à la méthode précédente. Le déploiement prend un peu de temps. Elle permet de rendre la modification disponible pour les autres utilisateurs s’ils la trouvent. Ce phénomène est visible avec l’incitation au fork proposée par les forges comme Github, Gitlab, Bitbucket, etc, sans pousser la modification vers le développeur amont (via une pull request). Cette technique est utilisée lorsque des développeurs :

  1. forkent un dépôt,
  2. créent un commit modifiant le nouveau dépôt,
  3. font dépendre leur application de ce commit (npm install git+https://alice@forge...).

Cependant, ce comportement n’est pas limité aux forges publiques : il existait déjà avant en publiant le correctif dans un article de blog, une liste de diffusion (liste non exhaustive).

Envoyé vers la distribution

La correction est envoyée dans la distribution Linux utilisée ; c’est souvent fait en incluant la modification dans un fichier, attaché à un rapport de bogue sur la distribution.

Une fois que la modification sera intégrée et qu’un nouveau paquet sera publié, l’ensemble des utilisateurs, y compris l’auteur, en bénéficieront. Cela évite de maintenir la modification de son côté lorsque de nouvelles versions du paquet seront publiées. La durée d’intégration est plus longue selon la réactivité du mainteneur du paquet et le mode de publication (version espacée ou rolling release). Bien évidemment, le bénéfice de la modification sera perdu en cas de changement de distribution.

Cette solution est nécessaire pour corriger/améliorer un élément spécifique d’un paquet de la distribution. Cela peut arriver dans deux cas :

  • soit parce que c’est un paquet spécifique à la distribution (le paquet apt pour debian par exemple)
  • soit parce qu’une modification du logiciel spécifique à la distribution a une influence sur la modification soumise

Envoyé vers le développeur amont

Plutôt que d’envoyer le correctif vers la distribution utilisée, il est alors envoyé directement vers le développeur du logiciel. Si le développement est hébergé sur une forge publique, cela suppose le faire un fork (comme dans le cas d’une publication solitaire), puis de faire une pull request (terme Github), merge request (terme Gitlab). Sinon, il faut regarder quelle est la forme attendue : en postant sur une liste de diffusion, ou directement vers le mainteneur, etc. Il sera nécessaire de répondre aux remarques et demandes de corrections pour que la modification soit intégrée dans le logiciel amont.

Comme dans le cas d’une intégration dans la distribution, une fois intégrée, la modification sera disponible pour tous :

  • soit en réutilisant le logiciel directement via le paquet issus du langage (par exemple gem pour ruby, wheel pour python, crate pour Rust, etc.)
  • soit parce que la version du logiciel sera elle aussi intégrée dans la distribution et donc obtenue dans un paquet de la distribution

Ce type de contributions sont les plus longues à revenir au contributeur mais elles permettent le déploiement le plus large (et donc la plus grande disponibilité pour soi et pour les autres).

Autres considérations

S’il n’est pas possible d’attendre le retour de la modification, la solution optimale est de faire un correctif local et un envoi vers la distribution ou vers le développeur amont (pour qu’une solution long terme soit aussi disponible automatiquement).

Pour bénéficier de l’envoi amont, il faut que le temps de retour soit inférieur au temps de changement de techno/bibliothèque. Dans un écosystème où les outils et bibliothèques sont abandonnés très rapidement, l’effort d’intégration peut être perçu comme vain puisque la personne ayant fait le développement aura peu le temps d’en profiter. D’un point de vue général, avec une majorité de personnes faisant ce calcul, cela ne fait qu’empirer le problème, avec des multitudes de fork s’ignorant mutuellement, chacun avec une fonctionnalité ou une correction différente. Javascript me semble être dans cette situation.

À propos du schéma

Le schéma a été réalisé avec Dia, installable par le paquet du même nom pour Debian et dérivées.
Fichier source .dia

27 September, 2020 07:09PM by ascendances

May 28, 2020

Olivier Berger (pro)

Expérimentations autour de TPs en distanciel, TPs sur le Cloud

J’ai participé au colloque IMT4ET de l’IMT, pour faire une courte présentation sur le thème des Travaux Pratiques à distance et des expérimentations sur les TP “virtuels” sur le Cloud sur lesquelles je travaille en ce moment.

Update: a version in english is also available.

J’y parle de Guacamole et MeshCentral, d’Antidote, de Eclipse Che et de Labtainers, les différents trucs excitants du moment, mais aussi de kubernetes, docker et de trucs louches comme du DevOps académique 😉

Les slides sont disponibles en ligne, et voici une vidéo ou j’expose mes idées sur la question :

Update : une version rédigée de mon propos est parue sur le site “Innovation pédagogique”, si vous préférez une version textuelle.

N’hésitez pas à me contacter si vous voulez creuser les sujets présentés, pour collaborer sur tous ces outils en logiciel libre.

28 May, 2020 08:54PM by Olivier Berger

April 19, 2020

Florent Gallaire

Jonathan Carter élu DPL pour 2020

C’est Jonathan Carter qui vient d’être élu Debian Project Leader (DPL) pour l’année 2020, succédant ainsi à Sam Hartman qui avait été élu en 2019.

Arrivé l’an passé derrière Sam Hartman presque à égalité avec Martin Michlmayr et Joerg Jaspert, Jonathan l’emporte logiquement cette année dans une élection sans réelle concurrence.

En effet, Brian Gupta avait immédiatement indiqué que le seul objet de sa candidature était de constituer un référendum, qui s’est révélé peu concluant, sur la création des fondations Debian US et Debian Europe ; tandis que la jeune indienne Sruthi Chandran, dont on devrait réentendre parler dans les prochaines années, manquait de légitimité pour le poste n’étant développeuse Debian que depuis un an.

Bravo à toi Jonathan, et bonne chance dans la mise en œuvre de ton programme !

19 April, 2020 02:18AM by fgallaire

March 23, 2020

hackergotchi for Debian France

Debian France

Debian France renouvelle ses instances

L'assemblée générale annuelle de l'association Debian-France vient de se terminer. Pas de confinement ici, puisque tout se passe en ligne et peut donc continuer envers et contre tout. Pour rappel, Debian France est une association qui se propose de représenter Debian en France, voire en Europe puisqu'elle est la seule organisation de confiance (Trusted Organization) active du projet Debian sur ce continent. Ce statut lui permet ainsi de recueillir des dons pour le projet Debian et de gérer le budget du projet qui lui incombe, en parallèle du sien.

L'assemblée générale a renouvelé le tiers de son conseil d'administration, actant ainsi l'entrée de Cyril Brulebois, un développeur Debian de longue date, au sein de son organe directeur. Le CA a reconduit le bureau de 2019, mais a élu un nouveau président: Jean-Philippe MENGUAL.

2019 avait marqué un véritable redécolage de Debian France: présence marquée aux FOSDEM, au Capitole du libre, à Paris, Lyon, organisation d'une minidebconf à Marseille, d'un meet-up à Bordeaux. Elle espère faire pareil en 2020, mais avec une claire volonté de mieux associer la communauté francophone des développeurs et des utilisateurs de Debian. Tout ce que fait l'asso doit avoir un "label" Debian clair, être partagé ici, et avec le projet dans son ensemble quand un budget est nécessaire ou pour les événements d'ampleur internationale (minidebconf). Dès février, Debian France a, via Debian, soutenu la tenue d'un sprint de l'équipe Ruby par exemple.

L'association espère donc mieux communiquer avec toute la communauté et s'articuler avec toutes ses composantes, comme debian-facile.

L'enjeu, outre une promotion plus marquée de Debian (Ubuntu étant moins présent), c'est aussi d'inspirer des gens qui, en entendant parler des actions, peuvent vouloir y contribuer. Ils sont les bienvenus! Tenir les stands, participer aux choix de goodies, adhérer à l'association, candidater au conseil d'administration pour 2021, autant de choses qui aideront à faire vivre l'asso et promouvoir le projet Debian. L'asso est "trusted organization", donc gère une partie du budget de Debian, elle doit donc être composée, au CA et au bureau, de développeurs Debian (pas exclusivement mais bon). Autant dire qu'avec moins de 100 développeurs vivant en France, toute bonne volonté est bienvenue! Et toute candidature à être développeur Debian est une bonne idée si vous vous en sentez capable et en avez envie.

Haut-les-coeurs donc, et merci à tous ceux qui suivent l'association et le projet! L'association remercie tous ses membres qui ont participé à l'assemblée générale et son bureau qui a géré cette année avec enthousiasme et dynamisme. Elle espère que cette année sera riche en synergies et partages, dans l'esprit du logiciel libre.

23 March, 2020 05:34PM

November 17, 2019

Paris Open Source Summit 2019

Debian France tiendra un stand à l'occasion du Paris Open Source Summit, les 10 et 11 Décembre 2019 aux Docks de Paris - 87 Avenue des Magasins Généraux, 93300 Aubervilliers.

Des développeurs Debian ainsi que des membres de l'association Debian France seront là pour répondre à vos questions. Des goodies Debian seront également disponibles !

Nous serons présents au village associatif, emplacement A32 parmi les nombreux autres stands.

17 November, 2019 10:09PM

September 16, 2019

Debian Buster Party à Lille - 2019

Lille - Fêtons l'arrivée de Debian Buster !

Une fête consacrée à Debian Buster et plus largement à Debian se déroulera à Lille, le samedi 5 octobre 2019 de 10h00 à 18h00.


  • 10h : début de l'atelier
  • 12h : auberge espagnole, options véganes
  • l'après-midi : la foire aux installations continue !
  • 16h : discussions au sujet de Debian et des logiciesl libres
  • 17h : goûter et gateaux pour fêter Buster !



16 September, 2019 07:33PM

Capitole du libre 2019

Debian France tiendra un stand à l'occasion du Capitole du libre, les 16 et 17 novembre 2019 à l'INP-ENSEEIHT de Toulouse.

Des développeurs Debian ainsi que des membres de l'association Debian France seront là pour répondre à vos questions. Des goodies Debian seront également disponibles !

Nous serons présents au village associatif parmi les nombreux autres stands.

16 September, 2019 09:57AM

June 05, 2019

hackergotchi for Gr&#233;gory Colpart

Grégory Colpart

Mini-DebConf Marseille 2019 (fr)

L’idée d’organiser une mini-DebConf à Marseille est née à Toulouse en 2017 : après avoir participé avec plaisir à plusieurs (mini)DebConfs, se lancer dans l’organisation d’un tel évènement est une manière de rendre la pareille et de contribuer à Debian !

Fin 2018, après avoir réuni les personnes motivées, nous avons choisi la date du 25/26 mai 2019 et dimensionner l’évènement pour 50 à 70 personnes en sélectionnant un lieu approprié au centre-ville de Marseille. Je ne vais pas m’attarder ici sur détails de l’organisation (appel à conférences, enregistrement des participants, composition du programme etc.), car nous allons publier bientôt un « Howto Organizing a mini-DebConf » pour partager notre expérience.

Tout a commencé dès le mercredi 22 mai, où la formidable équipe vidéo DebConf s’est réunie pour un sprint de 3 jours pour préparer la couverture de l’événement avec le matériel déjà arrivé et former les membres qui gèreront le matériel pour la mini-DebConf Hambourg.

Vendredi 24 mai, l’équipe de traduction francophone de Debian est arrivée pour un sprint d’une journée. La plupart d’entre eux ne s’était jamais rencontré physiquement !

Une majeure partie des participants sont arrivés dans l’après-midi du vendredi 24 mai. Le bureau d’accueil (Front-Desk) était déjà prêt, et les arrivants ont pu récupérer leur badge et un T-shirt de l’événement. Pour des raisons écologiques, nous avions décidé de minimiser les goodies offerts au participants donc pas de sacs ou papiers superflus, mais un booklet distribué en amont. Si besoin, des goodies Debian (stickers, casquettes, polos, etc.) étaient aussi en vente au Front-Desk.

La soirée de vendredi a débuté avec un mini-CheeseWineBOF avec des denrées locales (fromages, vins, pastis, olives, fruits et légumes) et apportées par des participant(e)s : merci à Valhalla pour fromage italien, ainsi qu’à Urbec et Tzafrir !

La soirée de vendredi s’est poursuivie : pendant que l’équipe vidéo finalisait son installation dans la salle de conférence, les participants ont été invités à une réunion du Linux Users Group de Marseille : une présentation de Florence Devouard, pionnière de Wikipédia, qui est revenue l’historique de Wikipédia/Wikimédia avec de nombreuses anecdotes. La soirée s’est achevée avec une tradition locale : la dégustation de pizzas marseillaises. Le week-end n’est pas encore commencé, et déjà de bons moments sont partagés entre les participants !

Samedi matin, c’était le coup d’envoi officiel de la mini-DebConf ! Ouverture des portes à 8h30 pour le petit déjeuner : cookies fait-maison, café en grains, nous avons proposé durant tout le week-end de la cuisine locale, fait-main et végétarienne. Autre objectif : minimiser les déchets, et dans cette optique nous avons réfléchi à différents dispositifs : couverts en dur, tasses à étiqueter, Ecocups, etc.

75 participants s’étaient inscrits, ce qui correspondait au maximum de la capacité du lieu. Et 73 sont effectivement venus, ce qui est un bel exploit, notamment pour une conférence totalement gratuite. Si l’on compte quelques participants non-inscrits, nous avons été au total plus de 75 participants, soit au-delà de nos espérances !

À 9h45, c’est la conférence d’ouverture ! Jérémy déroule le programme du week-end, remercie les sponsors et rappelle le Code of Conduct, le système d’autorisations pour les photos, etc.

À 10h, c’est parti pour la première conférence ! Les choses sérieuses débutent : Cyril Brulebois – release manager du Debian Installer – détaille le fonctionnement de la migration d’un package vers Testing, et propose une solution pour visualiser les dépendances entre les packages et comprendre ainsi pourquoi un package peut être bloqué.

On enchaîne ensuite avec Peter Green – co-fondateur du projet Raspbian – qui présente l’outil autoforwardportergit qu’il utilise pour automatiser la création de packages Debian modifiés pour Raspbian.

Après une pause-café, c’est Raphaël Hertzog qui revient sur 5 ans du projet Debian LTS (Long Term Support). Il explique l’historique ainsi que le fonctionnement : la gestion des sponsors, le travail réparti entre plusieurs développeurs, l’offre extended LTS, l’infrastructure. Le sujet du financement des contributeurs provoquera plusieurs questions et suscitera un Lightning Talk sur le sujet dimanche matin.

Durant le midi, pendant que l’infatiguable équipe vidéo forme des débutants à ses outils, un déjeuner est servi sous forme de buffet végétalien ou végétarien. Nous sommes fiers d’avoir réussi à offrir une cuisine fait-maison avec des produits frais et locaux, et sans gâchis grâce à une bonne gestion des quantités.

Après le déjeuner, c’est l’heure de la KSP (Key Signing Party) organisée par Benoît. L’occasion pour chacun d’échanger des signatures de clés GPG et de renforcer le réseau de confiance.

Et l’on repart pour un cycle de conférences, avec Elena “of Valhalla” Grandi qui présente le protocole ActivityPub pour des réseaux sociaux fédérés comme Mastodon, Pixelfed, etc.

C’est au tour de Laura Arjona Reina venue de Madrid pour présenter la Welcome Team au sein de Debian qui œuvre pour accueillir les nouveaux arrivants.

Ensuite, Denis Briand – fraîchement élu président de Debian France – nous parle de l’association Debian France, de son but, de ses actions et de ses projets.

C’est au tour de Frédéric Lenquette d’aborder le sujet « Hardening and Secure Debian Buster » en explorant toutes les possibilités de sécurisation d’une Debian 10.

Enfin, dernière conférence de la journée de samedi : une partie de l’équipe de traduction francophone (Thomas Vincent, Jean-Philippe Mengual and Alban Vidal) présente son travail : comment fonctionne le travail en équipe, quelles tâches peuvent être faites par des débutants, etc.

Samedi soir, fin de la première journée : tous les participants sont invités à prolonger les échanges à la Cane Bière, un bar proche de la mini-DebConf.

Dimanche matin, on repart avec une présentation de l’équipe vidéo (représentée par Nicolas Dandrimont et Louis-Philippe Véronneau) qui révèle ses secrets pour assurer la couverture vidéo des (mini)DebConfs !

Puis on enchaîne avec une session de 6 Lightning Talks animés par Eda : « kt-update » (Jean-François Brucker), « the Debian Constitution » (Judit Foglszinger), « Elections, Democracy, European Union » (Thomas Koch), les méthodes de vote de Condorcet et du Jugement Majoritaire (Raphaël Hertzog), « encrypt the whole disk with LUKS2 » (Cyril Brulebois), « OMEMO – the big fish in the Debian bowl » (Martin) et « Paye ton Logiciel Libre » (Victor).

Après quelques mots pour clôturer les conférences, c’est déjà l’heure du rangement pour certains, tandis que d’autres en profitent pour faire un mini-DayTrip : descendre la Canebière à pied et embarquer au Vieux Port pour l’archipel du Frioul pour marcher et nager !

Nous remercions les 75 participant(e)s venus du monde entier (Canada, USA, Israël, Angleterre, Allemagne, Espagne, Suisse, Australie, Belgique etc.) ! Nous remercions également la fantastique équipe vidéo qui réalise un travail remarquable et impressionnant de qualité. Nous remercions Debian France qui a organisé l’événement, et les sponsors : Bearstech, Logilab et Evolix. Nous remercions la Maison du Chant de nous avoir mis à disposition les locaux. Nous remercions Valentine et Célia qui ont assuré tous les repas, il y a eu de nombreux compliments. Nous remercions Florence Devouard d’avoir assuré une belle présentation vendredi soir, ainsi que tous les orateurs(ices) de la mini-DebConf. Et je tiens à remercier tous les bénévoles qui ont assuré la préparation et le bon déroulement de l’événement : Tristan, Anaïs, Benoît, Juliette, Ludovic, Jessica, Éric, Quentin F. et Jérémy D. Mention spéciale à Eda, Moussa, Alban et Quentin L. pour leur implication et leur motivation, et à Sab et Jérémy qui se sont plongés avec moi dans cette folle aventure depuis plusieurs mois : you rock guys !

Twitter :
Mastodon :
Photos :
Vidéos :

05 June, 2019 01:57PM by Gregory Colpart

January 08, 2019

Stéphane Blondon

Processeur Intel -> Architecture AMD64 pour Debian


Nom courant Dénomination Debian Disponibilité
x86 i386 rarement en vente après 2010
x86_64 amd64 à moins d’acheter des ordinateurs spécifiques, il n’y a plus que ça pour le grand public

Si vous venez d’acheter un ordinateur, choisissez amd64.

L’histoire, avec un grand L

Intel avait conçu une architecture 8086, améliorée successivement jusqu’au 286 (un processeur 16 bits).
Au milieu des années 80, Intel améliore cette architecture qui devient 32 bits (avec les dénominations commerciales 386 puis 486, Pentium, Pentium II, etc.), nommée i386 par Debian, communément appelée x86. Cette architecture est aussi parfois nommée ia32 pour « Intel Architecture 32 bits ». D’autres constructeurs de processeurs comme AMD ou Cyrix concevaient des processeurs compatibles. C’est donc cette même architecture (i386) qui devait être utilisée pour ces processeurs.

Autocollant Intel Pentium 4 (32 bits) comme on en trouvait collé sur des ordinateurs portables au début des années 2000

Puis Intel décida de faire un nouveau processeur, 64 bits, incompatible avec les x86. Associé à HP, une nouvelle gamme de processeur, Itanium, voit le jour en 2001. La dénomination Debian est donc ia64 (« Intel Architecture 64 bits »). C’est un échec commercial, dû à des performances décevantes et l’absence de compatibilité ascendante. Cette gamme sera arrêtée dans l’indifférence générale en 2013.

Parallèlement à Intel, AMD décide d’étendre le processeur x86 pour qu’il fonctionne en 64 bits tout en ayant une compatibilité 32 bits. Cette architecture est souvent appelée x86_64, parfois x64. En 2003, AMD vend l’Athlon 64, premier processeur disponible au public de cette nouvelle architecture. Debian la désigne par le terme amd64. Des accords entre AMD et Intel permettant aussi à Intel de produire cette architecture, Intel a emboîté le pas à AMD et produit aussi des processeurs compatibles amd64. C’est pourquoi les processeurs modernes Intel nécessitent cette architecture lors de l’installation d’un système Debian.

Bien plus récent que le Pentium4, c’est un processeur 64 bits. Les autocollants, c’est bien joli mais pas très informatif.

D’autres architectures moins connues voire complètement oubliées existent

Debian est installable sur de nombreuses autres architectures, mais qui ne sont pas orientées grand public. La seule exception étant peut-être ARM avec les cartes RaspberryPi (cf. wiki).

Des exemples d’autres architectures et processeurs associés : (à la toute fin du message)

08 January, 2019 09:10PM by ascendances

October 16, 2018

Didier Raboud

Raksha – Une idée

J’étais donc ce week-end en cours CG (responsables de groupes) pour l’ASVd à Froideville. Je tombe sur une conversation entre Chat et Pélican au sujet du lancement d’une commission IT au niveau cantonal pour fournir des services aux groupes du canton.

On continue la discussion, qui embraie rapidement sur un échange d’idées sur Framasoft, MiData ( et les différentes initiatives pour fournir des services IT aux groupes scouts du canton.

Pour un petit historique, il y’a déjà eu plusieurs initiatives dans ce sens, mais actuellement, je n’ai pas connaissance d’équipes actives ou fonctionnelles pour ça:

  • Pour l’ASVd:
    • un bénévole s’occupe des services cloud (NextCloud), email, listes et site Internet (WordPress).
    • des groupes DropBox continuent d’exister.
  • Pour les groupes:
    • rien de centralisé, mais différentes initiatives isolées naîssent et meurent (Trello, Mattermost, etc)

Bref. La discussion a finalement tourné autour des idées suivantes:

  • Un service scout
  • S’inspirer de ce que fait Framasoft et les collectifs Chatons: décentraliser les services et reprendre le contrôle!
  • Commencer petit; proposer quelque chose de spécifique aux scouts suisses, voir même scouts vaudois pour commencer.
  • Tirer profit du bénévolat, mais couvrir tous les frais
  • Offrir des services « collectifs » (une instance cloud par canton) et « spécifiques » (une instance Mattermost par groupe)
  • Avoir des ambitions techniques élevées:
    • uniquement du logiciel libre
    • automatisation des processus
    • confiance dans les données (backup)
    • monitoring des services
    • intégrations qui font sens
    • authentification unifiée
    • reproductibilité du projet

Tout ça est évidemment à discuter, clarifier, raffiner, prioriser avec les premiers intéressés. Mais… Je cherchais un nom, en rapport autant avec le champ lexical des chats (Chatons) et du scoutisme. J’avais d’abord pensé à « gamelle », qui me plaisait bien, mais tous les `.ch` étaient pris. « Veillée », vraiment bien, et veillé est libre; mais il y’aurait confusion avec le même nom sans accent. ☹

En feuilletant mon Livre de la Jungle de poche (non, non, en vrai: ), j’ai commencé à parcourir les différents animaux de l’histoire en testant leur disponibilité en .ch . Et c’est là que Mère Louve; Raksha, est apparue libre!

Raksha : la louve grise, également appelée Mère-Louve ou La démone, mère adoptive de Mowgli. Elle le défend lorsque Shere-Khan le réclame à l’entrée de sa tanière.

C’est plutôt un bon nom: les scouts avec une âme de louveteaux reconnaîtront le nom immédiatement, et c’est également un animal qui a des petits par portées, avec un aspect de défense des intérêts des scouts, et un aspect de collectif. Des chatons au louveteaux, on n’est pas très loin!

Bref. On doit se voir pour en discuter!

16 October, 2018 08:15AM by OdyX

September 27, 2018

Stéphane Blondon

Accéder à une console lorsque gdm plante

S’il est impossible d’avoir un terminal en appuyant simultanément sur ctrl+alt+F6 , il est possible de paramétrer Grub pour démarrer Linux avec un environnement multi-utilisateur mais sans interface graphique (runlevel 3) :

Lorsque le menu de Grub s’affiche, appuyer sur e pour modifier temporairement la configuration.
Puis ajouter 3 à la fin de la ligne :
linux /boot/vmlinuz-… root=UUID=12345678-… ro quiet 3
Puis appuyer sur la/les touches indiquées par Grub pour exécuter cette entrée.

J’ai trouvé plusieurs explications indiquant d’utiliser text à la place de 3 mais ça ne fonctionne pas avec la version avec laquelle j’ai subi ce problème (2.02+dfsg1-6).

La solution vient de, possibilité 5.

…Et Grub était innocent : c’était un problème de paquets mis-à-jour mais non configurés.

27 September, 2018 06:39AM by ascendances

June 01, 2018

Installer Matomo sur Debian 9

Imaginons qu’Airgan, une plateforme communautaire payante de location et de réservation d’organes, veuille améliorer le suivi des visites sur son site web. Matomo est une réponse possible à ce besoin.

Matomo, anciennement Piwik, est un service web pour collecter des statistiques de visites. L’entreprise propose une version libre, auto-hébergeable et une version hébergée uniquement par Matomo qui inclut des fonctions non disponibles dans la version libre.

Matomo fournit un fichier .deb, permettant d’installer le service facilement sur une machine Debian. Cet article présente quelques éléments à prendre en compte.

Le changement de nom de Piwik à Matomo date de Janvier 2018. Tout n’a pas été transféré et la documentation ou les variables laissent parfois encore apparaître l’ancien nom.

Installation du paquet piwik

Le paquet n’est pas inclus dans la distribution mais est fourni dans un dépôt tiers géré par Matomo.
La documentation pour installer le paquet fourni par Matomo est disponible à Il suffit de la suivre.

Installation du paquet php-mbstring

Le fonctionnement du service nécessite que le paquet php-mbstring soit installé. Si ce n’est pas le cas, une erreur lors de la configuration de Matomo (dans quelques étapes, patientez !) sera affichée :

Capture d'écran de l'erreur

Une pull-request sur Github a été faite pour ajouter php-mbstring aux dépendances. Cette étape ne sera peut-être plus nécessaire dans la prochaine version ?

Configuration du service web

Le paquet ne dépend pas d’un serveur web en particulier. Le code d’example suivant suppose que c’est Apache2 qui est installé. N’importe quel autre serveur web fonctionnerait aussi.

    ServerName matomo.airgan.tld

    # ce sera bien pratique quand on aura des problèmes
    ErrorLog /srv/airgan/logs/matomo-http-error.log
    CustomLog /srv/airgan/logs/matomo-http-access.log combined
    LogLevel info

    # les deux lignes importantes
    DocumentRoot /usr/share/piwik
    DirectoryIndex index.php

Ensuite, il faut activer le virtualhost :
sudo a2ensite matomo.conf
sudo systemctl reload apache2

Ajouter un utilisateur pour la base de données

Un serveur de base de données MySQL ou MariaDB doit être installé. Ensuite, il faut se connecter sur ce serveur pour créer un utilisateur qui pourra créer la base de données et les tables nécessaires lors de la configuration de Matomo (c’est juste après cette étape, vous avez bien fait de patienter !).

#Créer un utilisateur nommé matomo :
CREATE USER matomo@'localhost';
SET PASSWORD FOR matomo@'localhost' = PASSWORD('secret');
#Lui donner les droits pour créer la base de données nécessaire au service :

Configurer le service Matomo

Avec un navigateur web, allez sur le domaine paramétré dans la configuration du serveur web (matomo.airgan.tld dans notre exemple). Il suffit de suivre les étapes de l’interface pour finir l’installation. Elle correspond à l’étape « The 5-minute Matomo Installation » sur

Une fois cette étape terminée, l’installtion est terminée et aller sur le domaine permet de voir l’interface de connexion pour accéder aux statistiques de visite.

Versions utilisées

L’installation ayant servie à écrire l’article a été faite sur
Debian GNU/Linux 9.3 (stretch) avec les versions suivantes des paquets :


Dans le futur, il est possible que la livraison des organes se fasse à vélo. À étudier dans un prochain business plan.

01 June, 2018 03:51PM by ascendances

May 22, 2018

Olivier Berger (pro)

Recrutement ingénieur·e DevOps pour conteneurs de Travaux Pratiques en informatique/réseaux

MAJ : nous avons trouvé le candidat. Le poste n’est plus disponible.

Nous recrutons un·e ingénieur·e en informatique pour travailler à l’application des concepts et technologies DevOps (conteneurs Docker, Git, Linux, libre, …) pour la mise au point et l’hébergement de dispositifs de Travaux Pratiques virtualisés, qui seront utilisés pour des enseignements d’informatique et de réseaux, sur un CDD de 1 an, à Télécom SudParis, à Évry (91).

Pour en savoir plus, voir le descriptif du poste que j’ai mis en ligne.

22 May, 2018 08:25AM by Olivier Berger

May 18, 2018

Prochaine conférence MiNET sur les systèmes d’exploitation 24/05 Évry (France)

La prochaine conférence MiNET, le 24/05/2018 après-midi, promet d’être très intéressante sur le sujet des systèmes d’exploitation, avec 4 intervenants pointus :

  • Julia Lawall : “Introduction to Coccinelle and its usage in the Linux Kernel
  • Sebastien Valat : “Memory management and OS paging for high performance computing
  • Pierre Pronchery : “DeforaOS: Un voyage dans le développement de système d’exploitation
  • Cyril Brulebois : “Maintenir et développer la distribution Debian

Plus de détails sur

N’hésitez pas à nous rejoindre à Évry pour participer à cette conférence, ou à suivre la retransmission sur la chaîne Youtube de MiNET.



18 May, 2018 09:06AM by Olivier Berger

December 01, 2017

Conférence sur SoftwareHeritage par Roberto Di Cosmo

Nous avons eu le plaisir d’accueillir le 7/11/2017 Roberto Di Cosmo pour présenter le projet Software Heritage à Télécom SudParis, dans le cadre d’un séminaire du laboratoire Samovar.

La conférence de Roberto a été enregistrée. Les transparents sont disponibles en PDF. Voici la vidéo ci-dessous (ou en MP4 depuis l’archive de Software heritage):

Merci encore à Roberto et à toute l’équipe du projet.

01 December, 2017 01:05PM by Olivier Berger

April 21, 2017

hackergotchi for Rapha&#235;l Hertzog

Raphaël Hertzog

Le logiciel libre a t’il une couleur politique ?

En pleine campagne présidentielle, après avoir échoué à obtenir les parrainages pour Charlotte Marchandise, j’ai décidé de soutenir Jean-Luc Mélenchon.

Il se trouve que le volet numérique du programme de la France Insoumise est très bien ficelé et fait la part belle aux logiciels libres.

Mais face aux enjeux, ce n’est évidemment pas mon seul critère de choix. L’élément décisif pour ma part est la mise en place d’une assemblée constituante avec des citoyens tirés au sort pour changer nos institutions et notre système électoral à bout de souffle. Il nous faut le jugement majoritaire (cliquez le lien pour tester la méthode sur cette élection présidentielle) pour en finir avec le vote utile. Il faut dépasser la monarchie présidentielle et apprendre à travailler ensemble pour le bien de tous.

Mais même en allant au delà de ces deux aspects, je me retrouve en accord avec le programme de la France Insoumise sur la quasi totalité des thématiques sauf l’Europe et sur le revenu universel (qui est absent!).

Pour autant, je n’aime pas le personnage de Jean-Luc Mélenchon (ce n’est pas pour rien que je soutenais Charlotte Marchandise) et son historique politique (cumul dans le temps…) n’est pas en phase avec mes convictions, mais il n’y a pas de candidat parfait et il a promis de démissionner une fois la nouvelle constitution en place alors je m’en accommode.

Bref, pour en revenir avec le sujet de mon article, très peu de candidats[1] à la présidence ont pris des positions aussi claires en faveur des logiciels libres alors je m’interroge. Est-ce un hasard que le seul projet qui défend le logiciel libre soit aussi celui qui me correspond le mieux par ailleurs ? Ou bien est-ce que le fait que je fasse partie de la communauté du logiciel libre peut avoir une relation avec le côté humaniste/progressiste/écologiste qui m’attire en politique ?

J’ai l’habitude de présenter le logiciel libre comme apolitique, car les gens de gauche y voient un modèle de coopération et de partage des communs, et les gens de droite y voient la liberté totale et un marché ouvert avec une concurrence parfaite. Et parfois j’ai l’impression que cette distinction se retrouve aussi dans la différence de terminologie « logiciel libre » vs « open-source »…

L’existence même de ces deux tendances discréditerait alors la corrélation que je semble observer. Mais tout de même, lorsqu’on parle de « communauté du logiciel libre » j’ai remarqué que ceux qui se reconnaissent derrière ce label sont plutôt des contributeurs qui sont portés par des motivations (au moins partiellement) altruistes et lorsque je discute avec d’autres contributeurs bénévoles aussi impliqués que moi, il est assez rare que je tombe sur des personnes avec des valeurs en forte opposition aux miennes.

Ceux pour qui le logiciel libre se résume à l’open-source ne semblent pas s’identifier à la notion de communauté du logiciel libre et sont moins impliqués/présents/visibles dans les événements qui fédèrent les communautés (conférences, sprints, etc.).

Qu’en dites-vous ? Faites-vous le même constat que moi ? Ou bien avez-vous une expérience diamétralement opposée à la mienne ?

Il est possible (voire probable) que la communauté Debian (dont je fais partie) ne soit pas forcément représentative de l’ensemble de la communauté du libre. L’existence même du contrat social comme texte fondateur explique peut-être un biais vers le côté humaniste/progressiste.

En tout cas, avec le nombre de chercheurs qui ont déjà étudié les développeurs de logiciels libres, je m’étonne que cette problématique n’ait pas encore été étudiée. Si vous connaissez une étude à ce sujet, partagez la dans les commentaires, cela m’intéresse et je rajouterai volontiers un lien dans l’article.

[1] François Asselineau soutient aussi le logiciel libre. Mais j’ai l’impression que c’est plus par anti-impérialisme américain — car les logiciels propriétaires dominants viennent de là — que par conviction.

21 April, 2017 12:36PM by Raphaël Hertzog

February 13, 2017

Mes activités libres en janvier 2017

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

Ce mois-ci ce sont 10 heures de travail sur les mises à jour de sécurité pour Debian 7 Wheezy qui ont été subventionnées. Elles ont été consacrées aux tâches suivantes :

  • J’ai passé en revue de multiples CVE affectant ntp, et décidé de les marquer comme « no-dsa » (de manière identique à ce qui a été réalisé pour Jessie);
  • J’ai relancé les auteurs amont de jbig2dec (ici) et XML::Twig (par message privé) concernant les rapports de bogue n’ayant pas encore eu de retour de leur part;
  • J’ai demandé plus de détails sur la liste oss-security au sujet de la CVE-2016-9584, car le fait qu’elle ait déjà été remontée à l’amont n’était pas évident. Il s’est avéré que c’était bien le cas, j’ai donc mis à jour le suiveur de sécurité en conséquence;
  • Après avoir obtenu une réponse sur jbig2dec, j’ai commencé à rétroporter le patch désigné par l’amont, ce qui ne fut pas chose facile. Lorsque cela a été fait, j’ai également reçu le fichier permettant de reproduire le problème qui est à l’origine du rapport… et qui ne provoquait malheureusement plus le même problème avec la vieille version de jbig2dec présente dans Wheezy. Cela étant, Valgrind a tout de même identifié des lectures en-dehors de l’espace mémoire alloué. C’est à partir de cet instant que j’ai examiné avec plus d’attention l’historique Git, et découvert que les trois dernières années n’avaient vu principalement que des correctifs de sécurité pour des cas similaires n’ayant jamais été remontés en tant que CVE. En conséquence, j’ai ouvert une discussion sur comment régler cette situation;
  • Matthias Geerdsen a remonté dans le n°852610 une régression concernant libtiff4. J’ai confirmé le problème et passé de nombreuses heures à élaborer un correctif. Le patch ayant entraîné la régression était spécifique à Debian, car l’amont n’avait pas encore corrigé le problème. J’ai publié un paquet mis à jour dans la DLA-610-2.

Empaquetage Debian

La période de gel « fort » approchant, j’ai procédé à quelques mises à jour de dernière minute :

  • schroot 1.6.10-3 : correction de quelques problèmes anciens avec la manière dont les montages bind sont partagés, et autres corrections importantes;
  • live-boot 1:20170112 : correction d’un échec au démarrage sur système de fichier FAT, et autres corrections mineures;
  • live-config 5.20170112 : regroupement de plusieurs patchs utiles en provenance du BTS;
  • J’ai fini la mise à jour de hashcat 3.30 avec sa nouvelle bibliothèque privée, et corrigé en même temps le bogue critique pour la publication n°851497. Le travail avait été initié par des collègues de l’équipe pkg-security team.

Travaux divers

Parrainages J’ai parrainé un nouvel envoi de asciidoc abaissant une dépendance en recommandation (cf. le n°850301). J’ai parrainé une nouvelle version amont de dolibarr.

Discussions J’ai appuyé plusieurs modifications préparées par Russ Allbery sur debian-policy. J’ai aidé Scott Kitterman au sujet d’une incompréhension sur la manière dont les fichiers de service Postfix sont supposés fonctionner, en lien avec le rapport n°849584. J’ai discuté dans le rapport n°849913 d’une régression dans la compilation des compilateurs croisés, et fourni un patch afin d’éviter le problème. Guillem est finalement parvenu à une meilleure solution.

Bogues J’ai analysé le n°850236 concernant l’échec d’un test Django durant la première semaine suivant chaque année bisextile. J’ai créé le n°853224 afin de remonter plusieurs petits problèmes en lien avec les scripts mainteneur de desktop-base.


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 January 2016 contribuée par Weierstrass01.

13 February, 2017 10:37AM by Raphaël Hertzog

February 02, 2017

Élections présidentielles, logiciel libre et Charlotte Marchandise

L’élection présidentielle approche et commence à prendre une grande place médiatique. À cette occasion, les associations comme l’April essaient d’interpeller les candidats pour les sensibiliser sur le sujet…

En temps qu’association, il faut garder ses distances et ne pas prendre position. Mais en tant qu’individu, je peux aller plus loin et soutenir explicitement un candidat qui partage les valeurs du logiciel libre.

Charlotte MarchandiseC’est ce que je veux faire aujourd’hui. Je vous invite à découvrir Charlotte Marchandise. C’est la gagnante des primaires citoyennes organisées par et son programme politique est en parfaite adéquation avec mes valeurs (revenu de base inconditionnel, 6ème république, transition écologique, etc.) y compris sur le logiciel libre (voir ici l’article dédié de son programme).

C’est une candidature citoyenne non-partisane qui ne peut donc s’appuyer sur aucun financement pré-existant. Elle a donc besoin de nos dons. J’ai déjà fait un don conséquent et je vous invite à en faire de même. Cliquez ici pour accéder au formulaire permettant de soutenir la campagne de Charlotte Marchandise.

Si vous ne pouvez pas donner, je vous invite simplement à parler de Charlotte et de son programme dans votre entourage et à partager cet article. Si vous avez un peu de temps à investir, vous pouvez participer à la recherche de parrainages.

Je fais partie de ceux qui ne veulent plus de la classe politique en place et qui souhaite une réforme des institutions et du système électoral en premier lieu. Avec cette candidature citoyenne, « hackons le système » !

02 February, 2017 01:57PM by Raphaël Hertzog

January 14, 2017

Mes activités libres en décembre 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

Ce mois-ci ce sont 10 heures de travail sur les mises à jour de sécurité pour Debian 7 Wheezy qui ont été subventionnées. Elles ont été consacrées aux tâches suivantes :

  • J’ai publié la DLA-741-1 concernant unzip. Ce fut une mise à jour facile;
  • J’ai passé en revue le patch de Roberto Sanchez pour la CVE-2014-9911 concernant ICU;
  • J’ai publié la DLA-759-1 concernant nss, en collaboration avec Antoine Beaupré. J’ai fusionné et mis à jour le travail de Guido pour activer la suite de tests au cours de la compilation, et pour ajouter les tests DEP-8;
  • J’ai créé le dépôt Git qui sera utilisé pour la maintenance de php5 dans Debian LTS, et j’ai commencé à travailler sur une mise à jour. J’ai ajouté les patchs pour 2 CVE (CVE-2016-3141 et CVE-2016-2554), ainsi que quelques fichiers binaires requis par certains tests (qui échouent, à l’heure actuelle).

Empaquetages divers

Avec l’approche du gel définitif de Stretch, certains clients m’ont demandé de pousser des paquets dans Debian et/ou de corriger des paquets sur le point d’être retirés de cette distribution.

Alors que j’essayais de ramener uwsgi dans testing, j’ai créé les rapport de bogue n°847095 (libmongoclient-dev: Ne devrait pas rentrer en conflit avec le paquet de transition mongodb-dev) et n°847207 (uwsgi: FTBFS sur de multiples architectures avec des références indéfinies à des symboles uwsgi_*), de même que j’ai travaillé sur quelques-uns des bogues critiques pour la publication qui maintenaient le paquet hors de testing.

J’ai également travaillé sur quelques nouveaux paquets (lua-trink-cjson, lua-inotify, lua-sandbox-extensions) qui améliorent le paquet « hindsight » dans certains cas d’usage, et j’ai parrainé une mise à jour de rozofs dans experimental, afin de corriger un conflit de fichiers avec inn2 (cf. le n°846571).

Travaux Debian divers

Debian Live J’ai publié deux mises à jour de live-build. Avec la seconde ont été ajoutées plusieurs options de personnalisation de la configuration GRUB (que nous utilisons dans Kali pour surcharger le thème, et ajouter de nouvelles entrées au menu), à la fois pour le boot EFI et pour le boot normal.

Rapports de bogue divers Rapport de bogue n°846569 concernant libsnmp-dev, afin de tenir compte de la transition libssl (j’avais remarqué que le paquet n’était pas maintenu, j’ai en conséquence fait appel aux nouveaux mainteneurs potentiels sur la liste debian-devel). Le n°847168 sur devscripts pour debuild qui a commencé à échouer lorsque lintian échouait (régression inattendue). Le n°847318 concernant lintian, afin d’éviter les faux-positifs sur les paquets Kali (ce qui était ennuyeux du fait de la régression debuild précédemment mentionnée). Le n°847436 concernant un problème de mise à jour avec tryton-server. Le n°847223 concernant firefoxdriver, dans la mesure où il dépendait toujours d’iceweasel au lieu de firefox.

Parrainage J’ai parrainé une nouvelle version d’asciidoc (rapport de bogue n°831965), ainsi que de ssldump (version 0.9b3-6), pour la transition libssl. J’ai également poussé une nouvelle version de mutter, afin de corriger le n°846898 (elle était déjà prête dans SVN).

Distro Tracker

Pas grand chose de nouveau, j’ai corrigé le n°814315 en basculant quelques URLs restantes vers https. J’ai fusionné les patchs d’efkin pour corriger la suite de tests fonctionnels (cf. le n°814315), ce qui constitue une contribution vraiment très utile ! Ce même contributeur s’est attaqué à un autre ticket (le n°824912) concernant l’ajout d’une API pour récupérer les objets d’action. Cela représente une tâche plus importante et demande quelques réflexions. Je dois encore lui faire mes retours sur ses derniers patchs (après déjà deux itérations).

Travaux divers

J’ai mis à jour la formule salt letsencrypt-sh pour la version 0.3.0, et ajouté la possibilité de personnaliser le script hook pour recharger le serveur Web.

Le compte Twitter @planetdebian n’est plus actif depuis que a fermé ses portes, et que son remplaçant ( n’apprécie pas le fil RSS de J’ai créé le n°848123 concernant planet-venus, ce dernier ne préservant pas l’attribut isPermalink dans le tag guid.


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 December 2016 contribuée par Weierstrass01.

14 January, 2017 01:55PM by Raphaël Hertzog

December 11, 2016

Mes activités libres en novembre 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

Dans les 11 heures de travail (rémunérées) qui m’incombaient, je suis parvenu à publier la DLA-716-1, aussi connue sous le nom de tiff 4.0.2-6+deb7u8, corrigeant les CVE-2016-9273, CVE-2016-9297 et CVE-2016-9532. On dirait bien que ce paquet est concerné par de nouvelles CVE tous les mois.

J’ai ensuite consacré pas mal de temps à passer en revue toutes les entrées dans dla-needed.txt. Je souhaitais me débarrasser des commentaires erronés ou qui ne sont plus pertinents, et en même temps aider Olaf, qui s’occupait du « frontdesk LTS » pour la première fois. Cela a abouti au marquage de pas mal d’entrées comme « no-dsa » (c’est à dire que rien ne sera fait pour elles, leur gravité ne le justifiant pas), telles que celles affectant dwarfutils, dokuwiki, irssi. J’ai supprimé libass, car la CVE ouverte était sujette à débat et marquée comme « pas importante ». Tandis que je faisais cela, j’ai corrigé un bogue dans le script bin/review-update-needed que nous utilisons pour identifier les entrées n’ayant fait aucun progrès dernièrement.

Je me suis ensuite attaqué à libgc, et publié la DLA-721-1, ou libgc 1:7.1-9.1+deb7u1. Elle corrige la CVE-2016-9427. Le patch était important et a du être rétroporté manuellement, car il ne s’appliquait pas correctement.

Enfin, la dernière tâche réalisée fut le test d’une nouvelle version d’imagemagick et la revue d’une mise à jour préparée par Roberto.

Travaux concernant pkg-security

L’équipe pkg-security continue sur sa bonne lancée : j’ai parrainé le travail de patator concernant le nettoyage d’une dépendance inutile de pycryptopp, qui allait être retiré de Testing du fait du ticket n°841581. Après m’être penché sur ce bogue, il s’est avéré que celui-ci était résolu dans libcrypto++ 5.6.4-3. Je l’ai donc clôturé.

J’ai parrainé plusieurs envois : polenum, acccheck, sucrack (mises à jour mineures), bbqsql (nouveau paquet importé de Kali). Quelques temps plus tard, j’ai corrigé quelques soucis dans le paquet bbsql, qui avait été rejeté de NEW.

Je me suis également occupé de quelques bogues critiques pour la publication, et liés à la transition vers openssl 1.1 : j’ai adopté dans l’équipe sslsniff et corrigé le n°828557, par une compilation dépendante de libssl1.0-dev. Ceci après avoir ouvert le ticket amont correspondant. J’ai fait la même chose pour ncrack et le n°844303 (le ticket amont est ici). Quelqu’un d’autre s’est occupé de samdump2, mais j’ai tout de même adopté le paquet dans l’équipe pkg-security, dans la mesure où il s’agit d’un paquet concernant le thème de la sécurité. J’ai aussi effectué un envoi en tant que non-mainteneur d’axel et du n°829452 (cela ne concerne pas pkg-security, mais nous l’utilisons dans Kali).

Travaux Debian divers

Django J’ai participé à la discussion débattant de l’opportunité de laisser Django compter le nombre de développeurs qui l’utilisent. L’impact quant à la diffusion de données personnelles que ce changement entraînerait a suscité l’intérêt des listes de diffusion Debian, et jusqu’à celui de LWN.

Sur un plan plus technique, j’ai poussé la version 1.8.16-1~bpo8+1 vers jessie-backports, et corrigé le bogue critique pour la publication n°844139. Pour se faire, j’ai rétroporté deux commits amont, ce qui a mené à l’envoi 1.10.3-2. Je me suis ensuite assuré que cela était également corrigé dans la branche amont 1.10.x.

dpkg et /usr fusionné. En parcourant debian-devel, j’ai découvert que le bogue n°843073 menaçait la fonctionnalité d’un /usr fusionné. Dans la mesure où le bogue était présent dans du code que j’avais écrit il y a plusieurs années, et du fait que Guillem n’était pas intéressé par sa correction, j’ai passé une heure à mettre au point un patch relativement propre que ce dernier pourrait appliquer. Guillem n’a malheureusement pas encore réussi à sortir une nouvelle version de dpkg embarquant ces patchs. Espérons que cela ne tardera plus trop.

Debian Live J’ai fermé le n°844332 , qui demandait le retrait de live-build de Debian. Étant marqué comme orphelin, j’avais toujours gardé un œil sur ce paquet, et avait poussé quelques petites corrections vers Git. J’ai décidé cette fois d’adopter officiellement le paquet au sein de l’équipe debian-live, et de travailler un peu plus dessus. J’ai passé en revue tous les patchs en attente dans le suiveur de bogues, et poussé de nombreuses modifications vers Git. Quelques changements restent à faire pour finaliser un meilleur rendu du menu GRUB, et j’ai prévu de pousser une nouvelle version très prochainement.

Diverses créations de tickets J’ai créé deux tickets amont concernant uwsgi, afin d’aider à la correction de bogues ouverts et critiques pour la publication affectant ce paquet. J’ai créé le n°844583 concernant sbuild, afin de supporter les suffixes arbitraires de version pour les recompilations binaires (binNMU). Et j’ai créé le n°845741 concernant xserver-xorg-video-qxl, afin qu’il soit corrigé pour la transition vers xorg 1.19.

Zim. Alors que j’essayais de corriger le n°834405 et de mettre à jour les dépendances requises, j’ai découvert que je devais mettre à jour pygtkspellcheck en premier lieu. Le mainteneur de ce paquet étant malheureusement aux abonnés absents (MIA – missing in action), je l’ai adopté en tant que membre de l’équipe python-modules.

Distro Tracker. J’ai corrigé un petit bogue, qui entraînait l’affichage d’une affreuse trace à l’occasion de requêtes avec un HTTP_REFERER non-ASCII.


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 November 2016 contribuée par Weierstrass01.

11 December, 2016 07:37PM by Raphaël Hertzog

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

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 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

root@server ~# systemctl stop nginx.service
root@server ~# certbot certonly -d

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/ que j'utilise avec la commande root@server ~# ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

server {
    listen 443;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;


    ssl_prefer_server_ciphers on;

    ssl_dhparam /etc/nginx/dhparams.pem;

    root /srv/;
    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.

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"


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

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

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

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
# Inspired by <>
systemctl stop nginx.service
/opt/certbot/certbot-auto renew -nvv --standalone > /var/log/letsencrypt/renew.log 2>&1
systemctl start nginx.service
if [ "$LE_STATUS" != 0 ]; then
echo Automated renewal failed:
tail -n 200 /var/log/letsencrypt/renew.log
exit 1

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 <>
Description=Renouvellement des certificats letsencrypt


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 <>
Description=Renouvellement des certificats letsencrypt

OnCalendar=*-*-* 04:20:42



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

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 ;
  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

April 28, 2016

hackergotchi for Tanguy Ortolo

Tanguy Ortolo

Pour des cartes restaurant anonymes


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 11, 2016

Carl Chenet

Richard Stallman ce samedi à Choisy-le-roi

Pour information j’ai découvert ce week-end que Richard Stallman sera présent à la médiathèque de Choisy-le-roi ce samedi 16 avril 2016 à 17h. Pour information des Parisiens indécrottables, c’est en très proche banlieue parisienne :p Comptez par exemple entre 20 et 30 mn depuis le centre de Paris en passant par le RER C pour y arriver.


Bref si vous n’avez jamais vu le monsieur et ses célèbres conférences ou que vous aimeriez une mise-à-jour sur ses positions, c’est l’occasion de le voir. Pour ma part j’y serai.

Peut-être à samedi donc 😉

11 April, 2016 06:53AM by Carl Chenet

April 07, 2016

« La » communauté du Logiciel Libre, ça n’existe pas

Suivez-moi aussi sur Diaspora*diaspora-banner ou Twitter 

J’avais depuis quelques temps envie d’écrire un billet de blog au sujet de la soi-disant communauté du Logiciel Libre et le dernier article de Frédéric Bezies , où il regrette le manque de coordination et d’unité de cette communauté, m’a donné la motivation pour finalement expliquer pourquoi tant de gens se désillusionnent quant à « cette » communauté.

« La » communauté du Logiciel Libre, ça n’existe pas

Il est en effet vain dans la plupart des cas de parler de « la » communauté du Logiciel Libre. On peut – et je le fais souvent moi-même – parler de la communauté du Logiciel Libre pour regrouper dans un même sac tous les acteurs touchant de près ou de loin au Logiciel Libre, mais c’est une dénomination vague, peu précise et que l’on ne doit pas employer à tort et à travers.

Et pour cause, car aussi bien d’un point de vue technique que d’un point de vue idéologique, nous, les acteurs de cette soi-disant communauté, sommes profondément et sûrement irrémédiablement divisés.

Les communautés techniques

Rappelons-le car beaucoup de personnes même proches du Logiciel Libre ont tendance à l’oublier. 99% du temps, un projet du Logiciel Libre, c’est au départ un individu isolé non rémunéré qui se motive et prend son courage à deux mains pour écrire du code et porter seul – au moins au début – un projet pour répondre à un besoin existant qui le dérange lui.

Ce faisant, il s’insère dans une communauté technique, celle des outils qu’il utilise pour régler son problème, puis le jour où son projet est prêt, s’il fait le choix de le rendre public, dans une communauté idéologique répondant aux critères que l’on verra au chapitre suivant.

python-logo-master-v3-TMLa communauté Python, avec sa propre licence : la PSF, sa propre vision, ses propres objectifs

Au premier niveau, le développeur du Logiciel Libre, c’est donc un utilisateur des outils qui sont mis à disposition par une communauté technique. Il adhère souvent aux idées derrière les outils qu’ils utilisent au quotidien parce qu’il y voit un avantage direct et ressent la cohérence des choix techniques et idéologiques faits par la communauté l’ayant précédé.

Maintenant si on parle de « la » communauté du Logiciel Libre, ça sous-entend que le premier niveau dont je parlais à l’instant se fond  dans un deuxième niveau, un niveau plus vaste, plus abstrait, plus global. Donc plus éloigné du développeur au quotidien, touchant des problématiques qu’il ne ressent peut-être pas tous les jours.

Alors qu’au quotidien pour lui, « sa » communauté, c’est par exemple le langage Python et ses membres, pas Perl. Ou la distribution Debian et les buts du projet Debian, pas les systèmes BSD. On se construit donc aussi en opposition à d’autre communautés techniques et idéologiques.

freebsdFreeBSD, système d’exploitation et suite d’outils qui privilégient la licence BSD

Les développeurs contribuent donc – le plus souvent dans le cadre de leur temps libre, le plus souvent de façon non-rémunérée, et dans ce domaine seule la motivation permet d’avancer – aux sujets qui nous intéressent et nous motivent au sein d’une communauté technique et idéologique et pas sur les sujets dont « la communauté du Logiciel Libre » aurait besoin.

La diversité des acteurs et de leurs idées, de leurs approches techniques et des solutions qu’ils trouvent au quotidien  sont les éléments qui rendent aussi attractif pour beaucoup d’entre nous ce milieu technique et idéologique.

GPL contre BSD/MIT

J’ai évoqué et développé ce point dans l’un de mes précédents articles le danger Github : d’un point de vue idéologique, principalement deux idées du Logiciel Libre coexistent.

La vision incarnée par la licence GPL peut être résumée à une notion fondamentale intégrée par ses défenseurs et ses détracteurs : contaminante.  La GPL va nourrir d’elle-même la communauté en réinjectant automatiquement dans le parc logiciel sous GPL tous les dérivés des logiciels eux-mêmes sous GPL. La communauté sert la communauté. Les utilisateurs de la GPL trouvent cohérents de n’utiliser que du Logiciel Libre pour ne pas nourrir l’ennemi , c’est-à-dire le logiciel privateur.

Les licences BSD/MIT sont pour leur part plus permissives, permissives à l’extrême. Rappelons qu’un logiciel dérivé d’un logiciel sous licence  BSD/MIT peut être déposé sous une licence propriétaire. Les licences BSD/MIT sont donc non-contaminantes. On a donc la liberté de rendre un logiciel – libre à la base – privateur. Ce qui se fait beaucoup et l’on retrouve les systèmes d’exploitation BSD dans nombre de système d’exploitation propriétaires. voir à ce sujet la liste à couper le souffle des produits commerciaux reposant sur FreeBSD.

Les défenseurs des licences BSD/MIT parlent de liberté réelle face à la GPL, ses détracteurs de la liberté de se tirer une balle dans le pied. Étant donné que les défenseurs de ces licences permissives type BSD/MIT trouvent normal la coexistence du Logiciel Libre et du logiciel privateur, ils utilisent eux-mêmes les deux sans problème, ce qui est cohérent idéologiquement.


Donc au final deux visions très différentes du Logiciel Libre – la GPL plus conquérante, les BSD/MIT plus flexibles – coexistent.

Des communautés constituent le Logiciel Libre

On l’a vu, il serait donc plus précis de parler des communautés qui constituent le Logiciel Libre. Elles sont à la fois techniques et idéologiques et apportent des outils concrets à leurs membres. Elles se définissent par rapport à ce qu’elles construisent, à leurs contributions, mais aussi par opposition aux autres communautés techniques et idéologiques. Il est donc impossible de parler d’une communauté du Logiciel Libre, à moins de la réduire au peu d’idées transverses aux différentes communautés techniques et idéologique la constituant.

J’ai pu remarquer que de nombreux intervenants parlent souvent de la communauté du Logiciel Libre pour parler en fait d’un sous-ensemble de celle-ci, en fait de leur communauté.Par exemple un défenseur de la GPL va parler de la communauté du Logiciel Libre en omettant l’idée de liberté complète derrière les licences BSD/MIT. Ou un idéologue auto-proclamé du Logiciel Libre va déclarer de grandes directions que « le Logiciel Libre » devrait prendre dans une approche top-down alors que, comme nous l’avons vu, tous les contributeurs techniques du Logiciel libre intègrent avant tout une communauté technique et idéologique précise, un sous-ensemble de « la » communauté du Logiciel libre.

trollLes trolls, une activité prisée des Libristes

Au final il est peut-être rageant de voir au quotidien des projets s’affronter, se troller, de voir des projets réinventer ce qui existent déjà au lieu de l’améliorer. Il semble même incompréhensible de voir des projets entièrement recoder pour des questions de licences ou parfois juste d’ego entre membres de ce qu’on croit être une même communauté. Mais cela tient à une incompréhension de l’organisation et des interactions des projets du Logiciel Libre entre eux.

L’explication tient au fait que le Logiciel Libre est constitué de nombreuses communautés, qui partagent quelques grandes idées communes certes, mais qui portent chacune des solutions techniques, une vision et une identité propres. Elles arrivent à se rejoindre très ponctuellement autour d’un effort commun sur un point extrêmement consensuel, mais il sera tout simplement impossible de les faire toutes et en permanence converger vers des grands objectifs qui bénéficieraient (ou pas) à  une vague communauté globale dans laquelle se reconnaîtraient tous les acteurs du Logiciel Libre.

La diversité des communautés qui le compose fait la force du Logiciel Libre, nous partageons quelques grandes idées et nous inventons au quotidien nos propres solutions. Et c’est de cette façon que nous avons avancé jusqu’à aujourd’hui.

07 April, 2016 10:00PM by Carl Chenet

April 03, 2016

Nouveau forum pour l’emploi dans la communauté du Logiciel Libre et opensource

Suivez-moi aussi sur Diaspora*diaspora-banner ou Twitter 

Un rapide message pour annoncer le lancement d’un forum dédié à l’emploi dans la communauté du Logiciel Libre et opensource :

Le forum de :


Devant le succès de , le site d’emploi de la communauté du Logiciel Libre et opensource, et la communauté d’utilisateurs qui s’est constitué autour, il était dommage de s’arrêter à l’échange d’offres d’emplois. C’est pourquoi créé un lieu d’échange et de discussions pour sa communauté, avec des catégories comme les rémunérations, le droit du travail, les questions des jeunes diplômés, des les étudiants ou l’entrepreunariat.

banieres linux vert

Ce nouveau forum est fièrement propulsé par le nouveau moteur de forums Flarum, un logiciel libre sous licence MIT.

Au plaisir de discuter bientôt avec vous sur le forum de

Quelques liens pour finir :

03 April, 2016 10:00PM by Carl Chenet

March 31, 2016

Le danger Github (revu et augmenté)

Suivez-moi aussi sur Diaspora*diaspora-banner ou Twitter 

Alors que le projet CPython (implémentation historique du projet Python) a annoncé son passage chez Github (avec quelques restrictions, nous reviendrons là-dessus), il est plus que jamais important de s’interroger sur les risques encourus d’utiliser un logiciel propriétaire dans notre chaîne de création du Logiciel Libre.

Des voix critiques s’élèvent régulièrement contre les risques encourus par l’utilisation de Github par les projets du Logiciel Libre. Et pourtant l’engouement autour de la forge collaborative de la startup Californienne à l’octocat continue de grandir.

codercatL’octocat, mascotte de Github

Ressentis à tort ou à raison comme simples à utiliser, efficaces à l’utilisation quotidienne, proposant des fonctionnalités pertinentes pour le travail collaboratif en entreprise ou dans le cadre d’un projet de Logiciel Libre, s’interconnectant aujourd’hui à de très nombreux services d’intégration continue, les services offerts par Github ont pris une place considérable dans l’ingénierie logicielle ces dernières années.

Quelles sont ces critiques et sont-elles justifiées ? Nous proposons de les exposer dans un premier temps dans la suite de cet article avant de peser le pour ou contre de leur validité.

1. Points critiques

1.1 La centralisation

L’application Github appartient et est gérée par une entité unique, à savoir Github, inc, société américaine. On comprend donc rapidement qu’une seule société commerciale de droit américain gère l’accessibilité à la majorité des codes sources des applications du Logiciel Libre, ce qui représente un problème pour les groupes utilisant un code source qui devient indisponible, pour une raison politique ou technique.


De plus cette centralisation pose un problème supplémentaire : de par sa taille, ayant atteint une masse critique, elle s’auto-alimente. Les personnes n’utilisant pas Github, volontairement ou non, s’isolent de celles qui l’utilisent, repoussées peu à peu dans une minorité silencieuse. Avec l’effet de mode, on est pas « dans le coup » quand on n’utilise pas Github, phénomène que l’on rencontre également et même devenu typique des réseaux sociaux propriétaires (Facebook, Twitter, Instagram).

1.2 Un logiciel privateur

Lorsque vous interagissez avec Github, vous utilisez un logiciel privateur, dont le code source n’est pas accessible et qui ne fonctionne peut-être pas comme vous le pensez. Cela peut apparaître gênant à plusieurs points de vue. Idéologique tout d’abord, mais peut-être et avant tout pratique. Dans le cas de Github on y pousse du code que nous contrôlons hors de leur interface. On y communique également des informations personnelles (profil, interactions avec Github). Et surtout un outil crucial propriétaire fourni par Github qui s’impose aux projets qui décident de passer chez la société américaine : le gestionnaire de suivi de bugs.

windowsWindows, qui reste le logiciel privateur par excellence, même si d’autres l’ont depuis rejoint

1.3 L’uniformisation

Travailler via l’interface Github est considéré par beaucoup comme simple et intuitif. De très nombreuses sociétés utilisent maintenant Github comme dépôt de sources et il est courant qu’un développeur quittant une société retrouve le cadre de travail des outils Github en travaillant pour une autre société. Cette fréquence de l’utilisation de Github dans l’activité de développeur du Libre aujourd’hui participe à l’uniformisation du cadre de travail dudit développeur.

L'uniforme évoque l'armée, ici l'armée des clonesL’uniforme évoque l’armée, ici l’armée des clones

2. Validité des points critiques

2.1 Les critiques de la centralisation

2.1.1 Taux de disponibilité du service

Comme dit précédemment, Github est aujourd’hui la plus grande concentration de code source du Logiciel Libre. Cela fait de lui une cible privilégiée.  Des attaques massives par dénis de service ont eu lieu en mars et août 2015. De même, une panne le 15 décembre 2015 a entraîné l’indisponibilité de 5% des dépôts. Idem le 15 novembre. Et il s’agit des incidents récents déclarés par les équipes de Github elles-mêmes. On peut imaginer un taux d’indisponibilité moyen des services bien supérieur.


2.1.2 Blocage de la construction du Logiciel Libre par réaction en chaîne

Aujourd’hui plusieurs outils de gestion des dépendances comme npm dans le monde javascript, Bundler dans le monde Ruby ou même pip pour le monde Python sont capables d’aller chercher le code source d’une application directement depuis Github. Les projets du Logiciel Libre étant de plus en plus intriqués, dépendants les uns des autres, si l’un des composants de la chaîne de construction vient à manquer, c’est toute la chaîne qui s’arrête.

Un excellent exemple de cet état de fait est la récente affaire du npmgate (voir l’article Du danger d’un acteur non-communautaire dans votre chaîne de production du Logiciel Libre). Github peut très bien demain être mis en demeure par une entreprise de retirer du code source de son dépôt, ce qui pourrait entraîner une réaction en chaîne menant à l’impossibilité de construire de nombreux projets du Logiciel Libre, comme cela vient d’arriver à la communauté Node.js à cause de la société Npm, inc. gérant l’infrastructure de l’installeur automatisé npm.

2.2 Un peu de recul historique : SourceForge

Même si l’ampleur du phénomène n’a pas été la même, il est bon de rappeler que Github n’est pas apparu ex-nihilo et avait un prédécesseur ayant joui en son temps d’un engouement important : SourceForge.

Fortement centralisé, reposant également sur de fortes interactions avec la communauté, SourceForge est un SAAS fortement vieillissant  ces dernières années et subit une véritable hémorragie de ses utilisateurs au profit de Github. Ce qui signifie beaucoup d’ennuis pour ceux qui y sont restés. Pour le projet Gimp, il s’agit tout d’abord d’abus publicitaires trompeurs indignes, qui entraînent également le départ du projet VLC , puis l’apparition d’installeurs comprenant des adwares se faisant passer pour l’installeur officiel Windows de Gimp. Et enfin purement et simplement le piratage du compte SourceForge du projet Gimp par… les équipes de SourceForge elle-même.

Nous voyons ici des exemples récents et très concrets des pratiques dont sont capables les sociétés commerciales lorsqu’elles sont sous la pression de leurs actionnaires. D’où la nécessité de bien comprendre l’enjeu représenté par le fait de leur confier une centralisation des données et des échanges ayant de fortes conséquences sur le fonctionnement et les usages de la communauté du Logiciel Libre et opensource.


2.3 Les critiques relatives à utiliser un logiciel privateur

2.3.1 Une communauté, différents rapports au logiciel propriétaire

Cette critique, avant tout idéologique, se heurte à la conception même que chacun des membres de la communauté se fait du Logiciel Libre et opensource, et en particulier d’un critère : contaminant ou non, qu’on résume en général par GPL versus MIT/BSD.



Les défenseurs du Logiciel Libre contaminant vont être gênés d’utiliser un logiciel propriétaire car ce dernier ne devrait pas exister. Il doit être assimilé, pour citer Star Trek,  car il est une boîte noire communicante, qui met en danger la vie privée, détourne nos usages à des fins commerciales, gêne ou contraint la liberté de jouir entièrement de ce qu’on a acquis, etc.


Les pendants d’une totale liberté sont moins complexés dans leur utilisation des logiciels privateurs puisqu’ils acceptent l’existence desdits logiciels privateurs au nom d’une liberté sans restriction. Ils acceptent même que le code qu’ils développent aboutissent dans ces logiciels, ce qui arrive bien plus souvent qu’on ne le croit, voir à ce sujet la liste à couper le souffle des produits commerciaux reposant sur FreeBSD. On peut donc voir dans cette aile de la communauté du Logiciel Libre une totale sérénité à utiliser Github. Et ce qui est cohérent vis-à-vis de l’idéologie soutenue. Si vous êtes déjà allé au Fosdem, un coup d’œil dans l’amphithéâtre Janson permet de se rendre compte de la présence massive de portables Apple tournant sous MacOSX.

FreeBSD, principal projet des BSD sous licence MITFreeBSD, principal projet des BSD sous licence BSD

2.3.2 Les pertes de données et obstructions liées à l’usage d’un logiciel privateur

Mais au-delà de cet aspect idéologique pur et pour recentrer sur l’infrastructure de Github elle-même, l’utilisation du gestionnaire de suivi de bugs de Github pose un problème incontournable. Les rapports de bugs sont la mémoire des projets du Logiciel Libre. Il constitue le point d’entrée des nouveaux contributeurs, des demandes de fonctionnalités, des rapports de bugs et donc la mémoire, l’histoire du projet qui ne peut se limiter au code seul. Il est courant de tomber sur des rapports de bugs lorsque vous copiez/collez votre message d’erreur dans un moteur de recherche. Mémoire précieuse non seulement pour le projet lui-même, mais aussi pour ses utilisateurs actuels et à venir.

Github propose d’extraire les rapports de bugs via son API, certes, mais combien de projets anticiperont une éventuelle défaillance de Github  ou un retournement de situation arrêtant brusquement le service ? Très peu à mon avis. Et comment migrer vers un nouveau système de suivi de bugs les données fournies par Github ?

L’exemple de l’utilitaire de gestion de listes de choses à faire (TODO list) Astrid, racheté par Yahoo! il y a quelques années reste un très bon exemple de service ayant grandi rapidement, largement utilisé et qui a fermé du jour au lendemain, proposant pendant quelques semaines seulement d’extraire ses données. Et il s’agissait là d’un simple gestionnaire de tâches à faire. Le même problème chez Github serait dramatiquement plus difficile à gérer pour de très nombreux projets, si on leur laisse la possibilité de le gérer. Certes le code reste disponible et pourra continuer de vivre ailleurs, mais la mémoire du projet sera perdue, alors qu’un projet comme Debian approche aujourd’hui les 800000 rapports de bugs. Une vraie mine d’or d’informations sur les problèmes rencontrés, les demandes de fonctionnalités et le suivi de ces demandes. Les développeurs du projet CPython passant chez Github ont anticipé ce problème et ne vont pas utiliser le système de suivi de bugs de Github.

mastering-issuesIssues, le suivi de bug propriétaire de Github

Autre perte si Github disparaît ou devient inaccessible : le travail de revue des « push requests » (abrégées par PRs) en cours. Pour les lecteurs qui ne connaîtraient pas cette fonctionnalité de Github, il s’agit d’adresser de cloner le dépôt Github d’un projet, de modifier ce clone pour l’adapter à vos besoins, puis ensuite de proposer vos modifications au dépôt d’origine. Le propriétaire du dépôt d’origine va alors étudier les modifications qui lui ont été proposées et si elles lui conviennent les fusionner à son propre dépôt. Il s’agit donc d’une fonctionnalité très importante offerte de Github, qui propose de réaliser les différentes opérations graphiquement via son interface.

Toutefois le travail de revue des modifications proposées peut être long et il est courant d’avoir, pour un projet qui marche bien, plusieurs PRs en cours. Et il est également courant d’échanger des commentaires via ces PRs et/ou via le système de suivi de bugs propriétaires de Github dont nous avons parlé plus haut.

Le code en lui-même n’est donc pas perdu si Github devient inaccessible (quoique, voire plus bas un cas spécifique), mais le travail de revue matérialisée par les éventuels demandes et commentaires présents dans les PRs et les suivis de bugs associés l’est bien, lui. Rappelons également que Github permet de cloner des projets via son interface web propriétaire, puis d’y apporter toujours via la même interface des modifications et ensuite de générer des PRs sans télécharger aucunement le code sur son poste. Dans ce cas de figure, si Github devient indisponible, la perte du code et du travail en cours est totale.

Enfin certains utilisateurs se servent de Github entre autre comme d’une application de favoris, afin de suivre l’activité de leurs projets préférés en s’abonnant à ces projets par la fonctionnalité « Watch ».  Ce travail de réunion de données pour la veille technologique est perdu  en cas d’indisponibilité du service Github.

Proposed Debian LogoDebian, l’un des principaux projets du Logiciel Libre avec autour de 1000 contributeurs officiels


2.4 L’uniformisation

La communauté du Logiciel Libre oscille sans cesse entre un besoin de normes afin de réduire le travail nécessaire pour l’interopérabilité et l’attrait de la nouveauté, caractérisée par l’intrinsèque besoin de différence vis-à-vis de l’existant.

Github a popularisé l’utilisation de Git, magnifique outil qui aujourd’hui touche des métiers bien différents des programmeurs auxquels il était initialement lié. Peu à peu, tel un rouleau compresseur, Git a pris une place si centrale que considérer l’usage d’un autre gestionnaire de sources est quasiment impossible aujourd’hui, particulièrement en entreprise, malgré l’existence de belles alternatives qui n’ont malheureusement pas le vent en poupe, comme Mercurial.


Un projet de Logiciel Libre qui naît aujourd’hui, c’est un dépôt Git sur Github avec un pour sommairement le décrire. Les autres voies sont totalement ostracisées. Et quelle est la punition pour celui qui désobéit ? Peu ou pas de contributeurs potentiels. Il semble très difficile de pousser aujourd’hui le contributeur potentiel à se lancer dans l’apprentissage d’un nouveau gestionnaire de sources ET une nouvelle forge pour chaque projet auquel on veut contribuer. Un effort que fournissait pourtant tout un chacun il y a quelques années.

Et c’est bien dommage car Github, en proposant une expérience unique et originale à ses utilisateurs, taille  à grands coups de machette dans les champs des possibles. Alors oui, sûrement que Git est aujourd’hui le meilleur des système de gestion de versions. Mais ça n’est pas grâce à cette domination sans partage qu’un autre pourra émerger. Et cela permet à Github d’initier à Git les nouveaux arrivants dans le développement  à un ensemble de fonctionnalités très restreint, sans commune mesure avec la puissance de l’outil Git lui-même.

3. Centralisation, uniformisation, logiciels privateurs et bientôt… fainéantise ?

Le combat contre la centralisation est une part importante de l’idéologie du Logiciel Libre car elle accroît le pouvoir de ceux qui sont chargés de cette centralisation et qui la contrôlent sur ceux qui la subissent. L’aversion à l’uniformisation née du combat contre les grandes firmes du logiciel souhaitant imposer leur vision fermée et commerciale du monde du logiciel a longtemps nourri la recherche réelle d’innovation et le développement d’alternatives brillantes. Comme nous l’avons décrit, une partie de la communauté du Libre s’est construit en opposition aux logiciels privateurs, les considérant comme dangereux. L’autre partie, sans vouloir leur disparition, a quand même choisi un modèle de développement à l’opposé de celui des logiciels privateurs, en tout cas à l’époque car les deux mondes sont devenus de plus en plus poreux au cours des dernières années.


L’effet Github est donc délétère au point de vue des effets qu’il entraîne : la centralisation,  l’uniformisation, l’utilisation de logiciels privateurs comme leur système de gestion de version, au minimum. Mais la récente affaire de la lettre « Cher Github… » met en avant un dernier effet, totalement inattendu de mon point de vue : la fainéantise. Pour les personnes passées à côté de cette affaire, il s’agit d’une lettre de réclamations d’un nombre très important de représentants de différents projets du Logiciel Libre qui réclament à l’équipe de Github d’entendre leurs doléances, apparemment ignorées depuis des années, et d’implémenter de nouvelles fonctionnalités demandées.

Mais depuis quand des projets du Logiciel Libre qui se heurtent depuis des années à un mur tentent-ils de faire pleurer le mur et n’implémentent pas la solution qui leur manquent ? Lorsque Torvald a subi l’affaire Bitkeeper et que l’équipe de développement du noyau Linux n’a plus eu l’autorisation d’utiliser leur gestionnaire de versions, Linus a mis au point Git. Doit-on rappeler que l’impossibilité d’utiliser un outil ou le manque de fonctionnalités d’un programme est le moteur principal de la recherche d’alternative et donc du Logiciel Libre ? Tous les membres de la communauté du Logiciel Libre capable de programmer devrait avoir ce réflexe. Vous n’aimez pas ce qu’offre Github ? Optez pour Gitlab. Vous n’aimez pas Gitlab ? Améliorez-le ou recodez-le.

gitlabLogo de Gitlab, une alternative possible à Github

Que l’on soit bien d’accord, je ne dis pas que tout programmeur du Libre qui fait face à un mur doit coder une alternative. En restant réaliste, nous avons tous nos priorités et certains de nous aiment dormir la nuit (moi le premier). Mais lorsqu’on voit 1340 signataires de cette lettre à Github et parmi lesquels des représentants de très grands projets du Logiciel Libre, il me paraît évident que les volontés et l’énergie pour coder une alternative existe. Peut-être d’ailleurs apparaîtra-t-elle suite à cette lettre, ce serait le meilleur dénouement possible à cette affaire.

Finalement, l’utilisation de Github suit cette tendance de massification de l’utilisation d’Internet. Comme aujourd’hui les utilisateurs d’Internet sont aspirés dans des réseaux sociaux massivement centralisés comme Facebook et Twitter, le monde des développeurs suit logiquement cette tendance avec Github. Même si une frange importante des développeurs a été sensibilisée aux dangers de ce type d’organisation privée et centralisée, la communauté entière a été absorbée dans un mouvement de centralisation et d’uniformisation. Le service offert est utile, gratuit ou à un coût correct selon les fonctionnalités désirées, confortable à utiliser et fonctionne la plupart du temps. Pourquoi chercherions-nous plus loin ? Peut-être parce que d’autres en profitent et profitent de nous pendant que nous sommes distraits et installés dans notre confort ? La communauté du Logiciel Libre semble pour le moment bien assoupie.

cat-sleeping-fireplaceLe « lion » devant la cheminée

Texte sous licence Creative Commons CC BY-ND 3.0 FR

31 March, 2016 09:00PM by Carl Chenet

March 28, 2016

Du danger d’un acteur non-communautaire dans votre chaîne de production du Logiciel Libre

Suivez-moi aussi sur Diaspora*diaspora-banner ou Twitter 

La récente affaire désormais connue sous le nom de npmgate (voir plus bas si cet événement ne vous dit rien) est encore une illustration à mon sens du danger intrinsèque d’utiliser le produit possédé et/ou contrôlé par un acteur non-communautaire dans sa chaîne de production du Logiciel Libre. J’ai déjà tenté à plusieurs reprises d’avertir mes consœurs et confrères du Logiciel Libre sur ce danger, en particulier au sujet de Github dans mon billet de blog Le danger Github.

L’affaire npmgate

Pour rappel sur cette affaire précise du npmgate, l’entreprise américaine a demandé à l’entreprise npm Inc., également société américaine, qui gère le site et l’infrastructure derrière l’installeur automatisé de modules Node.js npm, de renommer un module nommé kik écrit par Azer Koçulu, auteur prolifique de cette communauté. Il se trouve qu’il est également l’auteur d’une fonction left-pad de 11 lignes massivement utilisée comme dépendance dans de très très nombreux logiciels enNode.js. Ce monsieur avait exprimé un refus à la demande de


Cette entreprise, qui pour des raisons obscures de droits d’auteur semblait prête à tout pour faire respecter sa stupide demande (elle utilise d’ailleurs elle-même du Logiciel Libre, à savoir au moins jquery, Python, Packer et Jenkins d’après leur blog et en profite au passage pour montrer ainsi sa profonde gratitude à l’égarde de la communauté), s’est donc adressé à npm, inc, qui, effrayée par une éventuelle violation du droit d’auteur, a obtempéré, sûrement pour éviter tout conflit juridique.

Azer Koçulu, profondément énervé d’avoir vu son propre droit d’auteur et sa volonté bafoués, a alors décidé de retirer de la publication sur l’ensemble de ses modules, dont le très utilisé left-pad. Bien que ait apparemment tenté de publier un module avec le même nom, le jeu des dépendances et des différentes versions a provoqué une réaction en chaîne provoquant l’échec de la construction de très nombreux projets.

Sourceforge, Github, et … bientôt ?

Sourceforge, devant un besoin accru de rentabilité et face à la desaffection de ses utilisateurs au profit, on l’imagine, de Github, a commencé à ne plus respecter les prérequis essentiels d’une forge logicielle respectueuse de ses utilisateurs.


J’ai présenté assez exhaustivement les dangers liés à l’utilisation de Github dans une chaîne de production du Logiciel dans mon article de blog le danger Github, à savoir en résumé la centralisation, qui avec de nombreux installeurs automatisés qui vont maintenant directement chercher les différents composants sur Github, si Github vient à retirer une dépendance, il se produira une réaction en chaîne équivalente au npmgate. Et cela n’est qu’une question de temps avant que cela n’arrive.

Autres risques, l’emploi de logiciel propriétaire comme l’outil de suit de bugs de Github issues, la fermeture et la portabilité limitées des données hébergées par eux et l’effet plus insidieux mais de plus en plus réel d’une sorte de fainéantise communautaire, inédite dans  notre communauté dans la recherche de solutions libres à des produits propriétaires existants et hégémoniques, sentiment également ressenti par d’autres.


Le danger de l’acteur non-communautaire

Devant la massification des interdépendances entre les différents projets et le développement important du Logiciel Libre, aujourd’hui rejoint par les principaux acteurs hier du logiciel privateur comme Microsoft ou Apple qui aujourd’hui adoptent et tentent de récupérer à leur profit nos usages, il est plus que jamais dangereux de se reposer sur un acteur non-communautaires, à savoir en général une entreprise, dans la chaîne de création de nos logiciels.


C’est un modèle séduisant à bien des égards. Facile, séduisant, en général peu participatif (on cherche à ce que vous soyez un utilisateur content), souvent avec un niveau de service élevé par rapport à ce que peut fournir un projet communautaire naissant, une entreprise investissant dans un nouveau projet, souvent à grand renfort de communication, va tout d’abord apparaître comme une bonne solution.

Il en va malheureusement bien différemment sur le moyen ou long terme comme nous le prouve les exemples suscités. Investir dans la communauté du Logiciel Libre en tant qu’utilisateur et créateur de code assure une solution satisfaisant tous les acteurs et surtout pérenne sur le long terme. Ce que chacun de nous recherche car bien malin qui peut prévoir le succès et la durée de vie qu’aura un nouveau projet logiciel.

28 March, 2016 09:00PM by Carl Chenet

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 03:52PM 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

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

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 Olivier Berger

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


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