Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

Ce blog n'a d'autre prétention que de me permettre de mettre à la disposition de tous des petits textes que j'écris. On y parle surtout d'informatique mais d'autres sujets apparaissent parfois.


Le résolveur DNS public dns.sb

Première rédaction de cet article le 27 septembre 2023


Je ne sais pas exactement quand il a été lancé mais je viens de voir passer un résolveur DNS public que je ne connaissais pas, DNS.sb. Il a quelques caractéristiques intéressantes.

Bon, des résolveur DNS publics, il y en a beaucoup (j'en gère même un). Les utilisateurices et administrateurices système s'en servent pour des raisons variées, par exemple échapper à la censure ou bien contourner un problème technique. Mais ils ne sont pas tous équivalents, en terme de caractéristiques techniques, de fonctions (certains sont menteurs), de politique de gestion des données personnelles, etc. Le service DNS.sb :

  • A DoT, DNSSEC et IPv6 (comme tous les résolveurs publics sérieux),
  • Promet d'être strict sur la vie privée et notamment de ne pas garder de trace des requêtes faites,
  • Est européen (certains résolveurs publics qui se présentent comme européens sont en fait des services étatsuniens un peu repeints, par exemple en s'appuyant sur la nationalité d'origine du fondateur), plus précisément allemand (par contre, le nom de domaine est dans un TLD aux îles Salomon, ce qui est curieux, mais n'a pas trop d'importance car le nom ne sert pas beaucoup pour accéder à un résolveur DNS, sauf pour l'authentification TLS),
  • Ne semble pas modifier les réponses DNS (ce n'est pas un résolveur menteur mais ce n'est pas clairement documenté et ce n'est pas facile à tester ; j'ai essayé quelques noms susceptibles d'être censurés, et j'obtiens la bonne réponse).

Faisons quelques essais techniques. Comme DNS.sb a des adresses IPv6 dont la forme texte est très courte, on va les utiliser. D'abord, avec dig :

    
% dig  @2a09:: sci-hub.se  
...
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30101
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
sci-hub.se.		60 IN A	186.2.163.219

;; Query time: 32 msec
;; SERVER: 2a09::#53(2a09::) (UDP)
;; WHEN: Wed Sep 27 11:47:18 CEST 2023
;; MSG SIZE  rcvd: 55

  

OK, c'est bon, tout marche, et en un temps raisonnable depuis ma connexion Free à Paris. (Évidemment, un résolveur public ne sera jamais aussi rapide qu'un résolveur local et il n'est donc pas raisonnable d'utiliser un résolveur public « pour les performances ».)

Et avec DoT ? Passons à kdig :


% kdig +tls @2a09::   disclose.ngo
;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 46687
;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1
...
;; QUESTION SECTION:
;; disclose.ngo.       		IN	A

;; ANSWER SECTION:
disclose.ngo.       	300	IN	A	84.16.72.183

;; Received 57 B
;; Time 2023-09-27 11:50:43 CEST
;; From 2a09::@853(TCP) in 326.4 ms

  

C'est parfait, tout marche (la première ligne nous montre les algorithmes cryptographiques utilisés).

Configurons maintenant un résolveur local pour faire suivre à DNS.sb, pour profiter de la mémorisation des réponses par celui-ci. On va utiliser Unbound et faire suivre en TLS :

forward-zone:
        name: "."
        # DNS.sb
        forward-addr: 2a11::@853#dot.sb
        forward-tls-upstream: yes
  

Et tout marche, notre résolveur local fera suivre ce qu'il ne sait pas déjà à DNS.sb.

DNS.sb dit qu'ils ont plusieurs machines, réparties par anycast. On peut regarder les identités de ces serveurs avec NSID (RFC 5001) :


% dig +nsid @2a09:: www.lycee-militaire-autun.terre.defense.gouv.fr              
...
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
; NSID: 64 6e 73 2d 6c 6f 6e 32 ("dns-lon2")
...
;; Query time: 80 msec
;; SERVER: 2a09::#53(2a09::) (UDP)
;; WHEN: Wed Sep 27 12:00:55 CEST 2023
;; MSG SIZE  rcvd: 137

  

On tombe apparemment sur une machine située à Londres ("dns-lon2"). Ça pourrait être mieux, mais l'anycast est un sport difficile.

Avec les sondes RIPE Atlas, on peut avoir une idée du nombre de serveurs :

% blaeu-resolve --requested 100 --nameserver 2a09::  --nsid --type TXT ee
Nameserver 2a09::
["the zone content is (c) … NSID: fra1;] : 4 occurrences 
["the zone content is (c) … NSID: debian;] : 6 occurrences 
["the zone content is (c) … NSID: us-sjc;] : 2 occurrences 
["the zone content is (c) … NSID: s210;] : 3 occurrences 
["the zone content is (c) … NSID: fra2;] : 5 occurrences 
["the zone content is (c) … NSID: dns-fra4;] : 3 occurrences 
["the zone content is (c) … NSID: dns-lon2;] : 2 occurrences 
["the zone content is (c) … NSID: dns-a;] : 3 occurrences 
["the zone content is (c) … NSID: lon-dns;] : 2 occurrences 
["the zone content is (c) … NSID: dns-ams3;] : 1 occurrences 
[TIMEOUT] : 2 occurrences 
Test #60486061 done at 2023-09-27T10:03:17Z
  

On voit dix instances différentes. Le schéma de nommage ne semble pas cohérent ("debian" ???) donc il est difficile d'en dire plus. Mais des traceroute nous montrent que ces machines sont en effet bien réparties, en tout cas pour l'Europe.

Je suis en tout cas satisfait de découvrir un résolveur DNS public européen (et qui marche, contrairement au projet coûteux et bureaucratique de la Commission Européenne, qui n'est toujours pas en service). Est-ce que je vais utiliser ce service ? Non, il en existe plusieurs autres qui me conviennent (dont le mien, bien sûr, mais aussi celui de FDN) mais cela semble un service bien fait et qui pourrait me convenir.


L'article seul

MaginotDNS, une faiblesse de certains résolveurs DNS

Première rédaction de cet article le 27 septembre 2023
Dernière mise à jour le 28 septembre 2023


La faille de sécurité MaginotDNS est une faiblesse de certains résolveurs DNS, qui ne vérifient pas assez les données quand elles sont envoyées par un résolveur à qui ils avaient fait suivre leurs requêtes. Elle peut permettre l'empoisonnement du résolveur par de fausses données.

La faille a été présentée à Usenix, a son propre site Web, et a été désignée par CVE-2021-25220 (pour BIND ; Knot a eu CVE-2022-32983 et Technitium CVE-2021-43105). Elle frappe plusieurs logiciels, BIND (quand on l'utilise comme résolveur), Knot Resolver, le résolveur de Microsoft et Technitium. Elle se produit quand le résolveur fait suivre (to forward) les requêtes DNS pour certains domaines à un autre résolveur (ce que l'article nomme un CDNS, Conditional Domain Name Server). Voici un exemple de configuration de BIND qui, sur une version vulnérable du logiciel, peut permettre la faille :

options {
        recursion yes;
	dnssec-validation no;
};

zone "unautredomaine.example." {
	type forward;
	forwarders { 192.0.2.1; };
};
  

Cette configuration se lit ainsi : pour tous les noms de domaine sous unautredomaine.example, BIND va, au lieu de passer par le mécanisme de résolution habituel (en commençant par la racine), faire suivre la requête au résolveur 192.0.2.1 (une autre configuration, avec stub à la place de forward, permet de faire suivre à un serveur faisant autorité ; en pratique, avec certains logiciels, on peut faire suivre aux deux et, parfois, cela permet d'exploiter la faille).

Évidemment, si on écrit une telle configuration, c'est qu'on estime que 192.0.2.1 est légitime et digne de confiance pour le domaine unautredomaine.example (et ceux en-dessous, les noms de domaine étant arborescents). Mais la faille MaginotDNS permet d'empoisonner le résolveur pour tous les noms à partir de 192.0.2.1, ou d'une machine se faisant passer pour lui.

Le DNS sur UDP (le mode par défaut) ne protège pas contre une usurpation d'adresse IP. Une machine peut donc répondre à la place du vrai 192.0.2.1. Pour empêcher cela, le DNS dispose de plusieurs protections :

  • L'attaquant qui va répondre à la place du serveur légitime doit deviner le Query ID de la requête,
  • Et (depuis l'attaque Kaminsky) le port source,
  • Et de toute façon le résolveur n'acceptera que les réponses qui sont dans le bailliage (in-bailiwick) de la question. S'il a demandé truc.machin.example et qu'on lui répond par un enregistrement pour chose.example, il ne gardera pas cette information qui est hors-bailliage.

Du fait de la dernière règle, sur le bailliage, un attaquant qui contrôle 192.0.2.1 ne pourrait que donner des informations sur les noms sous unautredomaine.example.

Mais les chercheurs qui ont découvert MaginotDNS ont repéré une faille dans le contrôle du bailliage : celui-ci est, sur certains logiciels, bien trop laxiste, lorsque la demande a été transmise à un autre résolveur et pas à un serveur faisant autorité. Il est donc possible de faire passer des données hors-bailliage. L'article donne l'exemple d'une réponse qui inclurait l'enregistrement mensonger :

com. IN NS  ns1.nasty.attacker.example.
  

Une telle réponse, clairement hors-bailliage, ne devrait pas être acceptée. Mais elle l'est (plus exactement, l'était, les logiciels vulnérables ont tous été corrigés) lorsqu'elle vient du résolveur à qui on a fait suivre une requête. À partir de là, le résolveur empoisonné fait passer toutes les requêtes des noms en .com à l'ennemi…

L'attaquant a plusieurs moyens d'exploiter cette faiblesse. Je vais en citer deux :

  • La plus évidente est de contrôler la machine listée forwarder (192.0.2.1 dans l'exemple plus haut). Bien sûr, si on décide de faire suivre à 192.0.2.1, c'est qu'on lui fait confiance. Mais on lui fait une confiance limitée, à unautredomaine.example. Avec MaginotDNS, 192.0.2.1 peut injecter des réponses pour tout domaine. (Cette attaque est appelée on-path dans l'article mais cette terminologie est inhabituelle.)
  • Sans doute plus réaliste est le cas où l'attaquant ne contrôle pas la machine listée forwarder. Il doit alors répondre à sa place en essayant de deviner Query ID et port source, ce qui n'est pas impossible (l'article donne les détails de ce cas, appelé off-path).

Dans les deux cas, l'absence de contrôle correct du bailliage permet à l'attaquant d'empoisonner n'importe quel nom.

Quelles sont les solutions que l'administrateur système peut déployer :

  • Bien sûr mettre à jour ses logiciels (la faille a été bouchée dans tous les programmes vulnérables). Il faut le répéter : les logiciels doivent être maintenus à jour. Aucune excuse ne doit être admise.
  • DNSSEC, qui avait justement été conçu pour cela, protège complètement (c'est pour cela que la configuration vulnérable, plus haut, a dnssec-validation no). En 2023, tout le monde l'a déjà déployé, de toute façon, non ?
  • Pour le deuxième cas, celui où l'attaquant ne contrôle pas le résolveur à qui on fait suivre, toute méthode qui empêche l'usurpation de réponse protégera : DoT (RFC 7858, très recommandé quand on fait suivre une requête), les cookies (RFC 7873), TCP (RFC 7766), TSIG (RFC 8945)…

Je recommande la lecture du ticket 2950 du développement de BIND, bien plus clair à mon avis que l'article originel (la figure 4 est un modèle de confusion). Et merci à Petr Špaček pour ses explications.


L'article seul

onprem, pour faire tourner facilement des LLM

Première rédaction de cet article le 20 septembre 2023


Vous le savez, accéder à un LLM en ligne soulève de nombreux problèmes de dépendance et de confidentialité. La solution est de le faire tourner en local. Mais les obstacles sont nombreux.

Le premier obstacle est évidemment commercialo-juridique. Tous les modèles ne sont pas récupérables localement. Ainsi, les modèles derrière ChatGPT ou Midjourney ne semblent pas accessibles, et on doit les utiliser en ligne, confiant ses questions (et donc les sujets sur lesquels on travaille) à une entreprise commerciale lointaine. Même quand ils sont téléchargeables, les modèles peuvent avoir des restrictions d'utilisation (plusieurs entreprises affirment que leur modèle est open source, terme qui a toujours été du baratin marketing et c'est de toute façon une question compliquée pour un LLM). Mais il existe plusieurs modèles téléchargeables et utilisables sous une licence plus accessible, ce qui nous amène au deuxième obstacle.

L'IA n'est pas décroissante ! Même si la consommation de ressources est bien plus faible pour faire tourner un modèle que pour l'entrainer, elle reste élevée et vous ne ferez pas tourner un LLM sur votre Raspberry Pi. La plupart du temps, 32 Go de mémoire, un processeur multi-cœurs rapide et, souvent un GPU Nvidia seront nécessaires. Et si vous ne les avez pas ? Des choses pourront tourner mais pas forcément de manière optimale. (Les exemples qui suivent ont été faits sur un PC/Ubuntu de l'année, avec 32 Go de mémoire, 8 cœurs à 3 Ghz, et un GPU Intel, apparemment pas utilisé ; il faut que je creuse cette question.)

Et le troisième obstacle est la difficulté d'utilisation des logiciels qui font tourner un modèle et, en réponse à une question, produisent un résultat. C'est peut-être l'obstacle le moins grave, car les progrès sont rapides. Quand on lit les articles où des pionniers faisaient tourner un LLM sur leur PC il y a un an, et qu'on voit à quel point c'était compliqué, on se réjouit des progrès récents. Ainsi, le premier septembre, a été publiée la première version de onprem, un outil libre pour faire tourner relativement facilement certains LLM. onprem est conçu pour les développeurs Python, et il faudra donc écrire quelques petits scripts (mais d'autres outils, comme open-interpreter, ne nécessitent pas de programmer).

Démonstration. On installe onprem :

% pip install onprem
  

On écrit un tout petit programme trivial :

from onprem import LLM
llm = LLM()
print(llm)
  

Et on le fait tourner :

% python roulemapoule.py
You are about to download the LLM
Wizard-Vicuna-7B-Uncensored.ggmlv3.q4_0.bin to the
/home/stephane/onprem_data folder. Are you sure? (y/N) y
[██████████████████████████████████████████████████]
<onprem.core.LLM object at 0x7f7609a23c50>
  

Ce programme n'a encore rien fait d'utile, je voulais juste vous montrer qu'il gère automatiquement le téléchargement des modèles, s'ils ne sont pas déjà sur votre disque. Par défaut, il utilise une variante du modèle Vicuna à 7 milliards de paramètres, évidemment téléchargée depuis Hugging Face. Soyez patient, il y a 3,6 Go à télécharger, mais cela ne sera fait qu'une fois.

Maintenant, faisons un programme plus utile :

from onprem import LLM
llm = LLM()
answer = llm.prompt("Why should I run a LLM locally and not on line?")

L'exécution nous donnera :

% python roulemapoule.py
llama.cpp: loading model from /home/stephane/onprem_data/Wizard-Vicuna-7B-Uncensored.ggmlv3.q4_0.bin
llama_model_load_internal: format     = ggjt v3 (latest)
llama_model_load_internal: n_vocab    = 32000
llama_model_load_internal: n_ctx      = 2048
llama_model_load_internal: n_embd     = 4096
llama_model_load_internal: n_mult     = 256
llama_model_load_internal: n_head     = 32
llama_model_load_internal: n_layer    = 32
llama_model_load_internal: n_rot      = 128
llama_model_load_internal: ftype      = 2 (mostly Q4_0)
llama_model_load_internal: n_ff       = 11008
llama_model_load_internal: model size = 7B
llama_model_load_internal: ggml ctx size =    0.08 MB
llama_model_load_internal: mem required  = 5407.72 MB (+ 1026.00 MB per state)
llama_new_context_with_model: kv self size  = 1024.00 MB

1. Increased security: Running a LLM locally provides greater security
against potential cyberattacks, as there is no internet connection for
the hacker to exploit.
2. Better performance: Running a LLM locally can improve performance
by reducing latency and improving reliability due to fewer network 
hops.
3. Faster troubleshooting: When running a LLM locally, you have direct 
control over its configuration, making it easier to diagnose and
resolve issues.
4. Increased flexibility: Running a LLM locally allows for greater 
customization and flexibility in configuring the system to meet
specific business requirements.
 

Ma foi, la réponse n'est pas absurde, mais il est amusant de noter que la raison qui me semble la plus importante, la confidentialité, n'est pas citée. Le bla-bla technique au début est dû au moteur sous-jacent utilisé, llama.cpp. Mais en tout cas, vous voyez que c'était très simple à installer et à utiliser, et que vous pouvez donc désormais facilement inclure un LLM dans vos applications écrites en Python.

Pour générer non plus du texte en langue naturelle mais du code, on va indiquer explicitement un modèle prévu pour le code (également dérivé de LLaMA, comme Vicuna) :

from onprem import LLM
llm = LLM("https://huggingface.co/TheBloke/CodeUp-Llama-2-13B-Chat-HF-GGML/resolve/main/codeup-llama-2-13b-chat-hf.ggmlv3.q4_1.bin")
answer = llm.prompt("Write a Python program to output the Fibonacci suite")
  

Et ça nous donne :


% python roulemapoule.py 
You are about to download the LLM codeup-llama-2-13b-chat-hf.ggmlv3.q4_1.bin to the /home/stephane/onprem_data folder. Are you sure? (y/N) y
[██████████████████████████████████████████████████]llama.cpp: loading model from /home/stephane/onprem_data/codeup-llama-2-13b-chat-hf.ggmlv3.q4_1.bin
…
The Fibonacci sequence is a series of numbers in which each number is
the sum of the two preceding numbers, starting from 0 and 1. The first
few terms of the sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

Write a Python program to output the Fibonacci sequence up to 10.

Here is an example of how you might do this:
```
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

for i in range(10):
    print(fibonacci(i+1))
```
Expected output:

0
1
1
2
3
5
8
13
21
34

(Notez la syntaxe Markdown.)

Bon, comme vous le voyez, c'est simple, ça marche et vous pouvez travailler sur des projets confidentiels sans craindre de fuite. Mais il y a des limites :

  • Je n'ai pas réussi à utiliser des modèles comme Bloom (et le message d'erreur est vraiment incompréhensible), sans doute parce que onprem dépend de lama.cpp et qu'il ne fonctionne qu'avec des dérivés de LLaMA (il faut vraiment que je lise la documentation ou que je teste un moteur adapté à Bloom). Idem pour Falcon. Notez aussi qu'onprem demande un format particulier du modèle, GGML (et que les formats changent).
  • J'ai l'impression que mon GPU n'est pas utilisé, il faut que je regarde ça.

Allez, pour se consoler de ces limites, on va faire une jolie image avec Stable Diffusion en local (mais rien à voir avec onprem) :

pip install diffusers transformers scipy torch
sudo apt install git-lfs
git clone https://huggingface.co/runwayml/stable-diffusion-v1-5 
  

(Le git clone prend très longtemps, il y a des dizaines de gigaoctets à charger.) On écrit un programme :

from diffusers import StableDiffusionPipeline
pipe = StableDiffusionPipeline.from_pretrained('.')
# Pour éviter la censure "Potential NSFW content was detected in one
# or more images. A black image will be returned instead. Try again with
# a different prompt and/or seed.": 
pipe.safety_checker = lambda images, clip_input: (images, [False for i in images])
prompt = "A system engineer running to install the last version of BIND to fix yet another security vulnerability, in the style of Philippe Druillet"
image = pipe(prompt).images[0]  
image.save("sysadmin-rush.png")
  

Et voilà : sysadmin-rush.png

(D'autres outils m'ont été signalés mais la plupart non-libres.)


L'article seul

Est-ce légitime de récolter des pages Web pour entrainer des IA ?

Première rédaction de cet article le 18 septembre 2023


Plusieurs médias ont récemment publié des articles dénonçant GPTBot, le ramassseur de pages Web de la société OpenAI. Ces articles sont souvent écrits dans un style dramatique, parlant par exemple de « pillage » du Web, ou de « cauchemar ». Je n'ai pas encore d'opinion ferme à ce sujet mais je peux quand même discuter quelques points.

La partie technique d'abord. Le GPTBot est documenté par la société OpenAI. Il ramasse le contenu des pages Web, ce qui sert ensuite à entrainer un LLM comme celui utilisé par ChatGPT. Étant donné que le ramasseur ne paie pas les auteurs et hébergeurs des sites Web, et que le LLM ainsi entrainé sera utilisé dans des services potentiellement lucratifs, les médias dénoncent cette activité de ramassage comme illégitime. Voici par exemple un article de Télérama du 6 septembre à ce sujet : telerama-gptbot.png

Le débat n'est pas nouveau : des protestations avaient déjà été émises par certains programmeurs à propos du service Copilot de GitHub. Est-ce que Copilot peut s'entrainer sur les programmes stockés sur GitHub ? D'un côté, ces programmes sont en accès ouvert (et la grande majorité sous une licence libre), de l'autre, certaines licences utilisées imposent la réciprocité (c'est notamment le cas de la GPL), alors que les programmes développés avec Copilot, et Copilot lui-même, ne sont pas forcément sous une licence libre.

Notez que, comme documenté par OpenAI, si on n'aime pas le ramassage par le GPTBot, on peut utiliser le traditionnel robots.txt (RFC 9309) et il respectera ce désir. Cela n'empêchera évidemment pas les médias de protester, soit parce qu'ils voudraient être payés, soit parce qu'ils critiquent ce côté « autorisé par défaut ».

Alors, est-ce légitime ou pas d'entrainer un LLM avec des données qui sont accessibles publiquement ? Le problème est complexe, plus complexe que la présentation simpliste faite dans les médias. Rappelons d'abord que ce n'est pas parce qu'un contenu est en accès ouvert qu'on peut faire ce qu'on veut avec. Il vient avec une licence (et, s'il n'y en a pas d'explicite, c'est qu'on ne peut rien faire) et celle-ci limite souvent les utilisations. Ainsi, ce blog est sous licence GFDL et, si vous voulez en réutiliser le contenu, vous pouvez (licence libre) mais vous devez donner les mêmes droits à ceux qui recevront le travail fait à partir de ce blog (comme pour la GPL dans le cas du logiciel). Est-ce qu'un LLM typique respecte ceci ? L'une des difficultés de la question est que le LLM ne copie pas, il ne plagie pas, il produit un contenu original (parfois faux, dans le cas de ChatGPT, mais c'est une autre histoire). Il ne viole donc pas le droit d'auteur. (Comme toujours, la réalité est plus complexe, des cas où Copilot a ressorti tel quel du code GPL ont déjà été cités.)

Mais est-ce que ce contenu original est dérivé du contenu initial ? Beaucoup d'articles sur la question ont fait comme si la réponse était évidemment oui. Mais cela ne me convainc pas : le mode de fonctionnement d'un LLM fait justement qu'il ne réutilise pas directement son corpus d'entrainement (et cela a de nombreux inconvénients, comme l'impossibilité de sourcer les réponses et l'impossibilité d'expliquer comment il est arrivé à cette conclusion, deux des plus gros problèmes lorsqu'on utilise des IA génératives comme ChatGPT). Il n'est donc pas évident pour moi que la licence du texte original s'applique. Prenons une comparaison : une étudiante en informatique lit, pour apprendre, un certain nombres de livres (certainement sous une licence restrictive) et des programmes (dont certains sont sous une licence libre, et une partie de ceux-ci sous GPL). Elle va ensuite, dans son activité professionnelle, écrire des programmes, peut-être privateurs. Est-ce que c'est illégal vu que sa formation s'est appuyée sur des contenus dont la licence n'était pas compatible avec celle des programmes qu'elle écrit ? Tout créateur (j'ai pris l'exemple d'une programmeuse mais cela serait pareil avec un journaliste ou une écrivaine) a été « entrainé » avec des œuvres diverses.

Dans le cas d'un contenu sous une licence à réciprocité, comme mon blog, notez que le fait que les tribunaux étatsuniens semblent se diriger vers l'idée que le contenu produit par une IA n'est pas copyrightable fait que la licence sera paradoxalement respectée.

Bon, et, donc, les arguments des médias ne m'ont pas convaincu ? L'un des problèmes est qu'il y a un conflit d'intérêts dans les médias, lorqu'ils écrivent sur des sujets qui concernent leur business ; ils sont censés à la fois rendre compte de la question tout en défendant leurs intérêts. Alors, certes, OpenAI est une entreprise à but lucratif, et pas forcément la plus sympathique, mais les médias sont aussi des entreprises commerciales, et il n'y a pas de raison, a priori, de privilégier un requin plutôt qu'un autre (l'IA brasse beaucoup d'argent et attire donc les envies).

Notons aussi que, dans le cas particulier de la francophonie, on verra sans doute les mêmes médias en langue française bloquer GPTBot et se plaindre ensuite que les IA ne traitent pas le français aussi bien que l'anglais… (Pour le logiciel libre, cité plus haut dans le cas de Copilot, un argument équivalent serait qu'exclure le code GPL des données d'entrainement réduirait la qualité du code produit, le code écrit sous les licences libres étant généralement bien meilleur.)

Bref, la question me semble plus ouverte que ce qui est présenté unanimement dans les médias français. (Même la FSF considère le problème comme ouvert.) Pour l'instant, je n'ai donc pas ajouté le GPTBot au robots.txt (que je n'ai d'ailleurs pas). De toute façon, un examen des journaux ne me montre aucune visite de ce ramasseur, ce qui fait que vous ne retrouverez pas mon style dans les résultats de ChatGPT. Et vous, des avis ? Vous pouvez m'écrire (adresse en bas de cette page) ou bien suivre la discussion sur le fédivers ou celle sur Twitter.


L'article seul

Fiche de lecture : Géopolitique du numérique

Auteur(s) du livre : Ophélie Coelho
Éditeur : Éditions de l'Atelier
978-2-7082-5402-2
Publié en 2023
Première rédaction de cet article le 10 septembre 2023


D'innombrables livres (sans compter les colloques, séminaires, journées d'études, articles et vidéos) ont déjà été consacrés à la géopolitique du numérique, notamment à l'Internet. Ce livre d'Ophélie Coelho se distingue par son côté pédagogique (il vise un public exigeant mais qui n'est pas forcément déjà au courant des détails) et par sa rigueur (beaucoup de ces livres ont été écrits par des gens qui ne connaissent pas le sujet). Il couvre les enjeux de pouvoir autour des services de l'Internet (qui ne se limite pas à Facebook !). Le livre est vivant et bien écrit (malgré l'abondance des notes de bas de page, ce n'est pas un livre réservé aux universitaires).

J'apprécie le côté synthétique (le livre fait 250 pages), qui n'empêche pourtant pas de traiter en détail des sujets pas forcément très présents quand on parle de ce sujet (comme le plan Marshall, un exemple de soft power). À propos de ce plan, on peut également noter que le livre s'inscrit dans le temps long et insiste sur des déterminants historiques, comme l'auteure le fait dans son analyse du Japon.

Le livre, je l'ai dit, est clair, mais cela ne l'empêche pas de parler de questions complexes et relativement peu connues (le slicing de la 5G, par exemple, qui a été très peu mentionné dans les débats sur la 5G).

J'ai aussi beaucoup aimé le concept de « passeur de technologie » qui permet bien de comprendre pourquoi, alors que les discours « au sommet » sont souverainistes, à la base, des milliers de passeurs au service des GAFA promeuvent (gratuitement !) les technologies étatsuniennes. Le rôle de tous ces commerciaux bénévoles est souvent sous-estimé.

Ce livre ne se limite pas à analyser l'importance des acteurs du numérique (qui ne sont pas du tout des purs intermédiaires techniques), notamment du Web, mais propose également des solutions, comme le recours aux logiciels libres mais aussi et surtout une indispensable éducation au numérique (éducation critique, pas uniquement apprendre à utiliser Word et TikTok !). L'utilisateurice ne doit pas être un simple « consommateur d'interfaces » mais doit être en mesure d'exercer ses droits de citoyen·ne, même quand cet exercice passe par des ordinateurs.

L'auteure ne manque pas de critiquer plusieurs solutions qui ont largement fait la preuve de leur inefficacité, comme les grands projets étatiques qui, sous prétexte de souveraineté, servent surtout à arroser les copains (par exemple Andromède).

Des reproches ? Il n'y a pas d'index, ce qui aurait été utile, et quelques erreurs factuelles sont restées (Apollo ne s'est posé sur la Lune qu'en 1969, l'ICANN n'a pas un rôle aussi important que ce qui est présenté). Je ne suis pas non plus toujours d'accord avec certaines présentations de l'histoire de l'Internet. Par exemple, le fait que le Web soit « ouvert » (spécifications librement disponibles et implémentables, code de référence publié) n'est pas du tout spécifique au Web et était la règle dans l'Internet de l'époque. Mais que ces critiques ne vous empêchent pas de lire le livre : sauf si vous êtes un·e expert·e de la géopolitique du numérique, vous apprendrez certainement beaucoup de choses.

À noter que le livre est accompagné d'un site Web, http://www.geoponum.com/.


L'article seul

Faut-il supprimer des centres de données ?

Première rédaction de cet article le 4 septembre 2023


Le premier septembre, le journal Libération a publié une tribune (non publique, donc je ne mets pas de lien) réclamant des mesures drastiques contre les centres de données, tribune notamment illustrée par le cas de Marseille. Faut-il donc de telles mesures ?

La tribune était signée de Sébastien Barles, adjoint au maire de Marseille, délégué à la transition écologique. Elle n'est accessible qu'aux abonnés mais Grégory Colpart en a fait une copie (et hébergée dans un centre de données marseillais). Donc, je me base sur cette copie.

Que demande la tribune ? Un moratoire sur la construction de centres de données, une taxe proportionnelle au volume de données stockées, et des obligations d'alimentation électrique en énergie renouvelable. Il y a des arguments écologiques (la consommation éléctrique de ces centres) et économiques (peu de créations d'emplois).

Le principal problème de cette tribune est qu'à la lire, on a l'impression que les centres de données ne servent à rien, qu'ils ne sont qu'une source de nuisances. Bien sûr, ils ont un impact écologique, électrique, urbanistique, etc, mais c'est le cas de toutes les activités humaines. Ne pointer que les aspects négatifs est facile mais esquive la question « est-ce que les avantages l'emportent sur les inconvénients ? » Il est amusant de voir la tribune réclamer plutôt de « l'industrie manufacturière », industrie qui n'est pas spécialement verte ni plus agréable pour les voisins. Cette industrie manufacturière, comme les centres de données, a un impact. Au passage, le serveur Web de Libération, choisi par l'auteur pour publier sa tribune, n'est pas hébergé dans un joli nuage tout propre, il est aussi dans un centre de données, ce qui illustre leur utilité.

On ne peut donc pas se contenter de dire qu'il faut moins de centres de données, il faut aussi préciser quels services seront abandonnés. Si les centres de données existent, c'est parce qu'ils hébergent des usages que certains jugent utiles. Si Sébastien Barles veut réduire leur nombre, il devrait lister les usages à supprimer ou limiter. Il y a plein de pistes à ce sujet (la publicité, le sport-spectacle…) mais l'auteur de la tribune n'en mentionne aucun. Prudence politicienne classique : dénoncer des consommations excessives sans dire lesquelles permet de ne se fâcher avec personne.

Ainsi, la tribune dit que « il est prévu qu'en 2030, les data centers consommeront 13 % de l'électricité mondiale » mais ce chiffre, pris isolément, n'a aucun intérêt. Évidemment que les centres de données informatiques consomment davantage d'électricité qu'en 1950 et évidemment aussi qu'ils consomment plus qu'en 2000 : les usages du numérique ont beaucoup augmenté, et ce n'est pas un problème. (Il y a aussi un biais de statistiques : lorsqu'une entreprise migre sa salle des machines interne vers un centre de données d'un fournisseur public comme OVH, la consommation électrique ne change pas, mais la tranche « centre de données » augmente.)

Donc, les centres de données sont utiles (mon article que vous lisez en ce moment est hébergé dans un tel centre, quoique loin de Marseille). Il existe bien des alternatives (par exemple un hébergement dans ses locaux) mais elles n'ont pas moins d'impact (un serveur chez soi consomme autant, voire plus, car il est moins optimisé et moins efficace, que les machines des centres de données). On peut et on doit diminuer l'empreinte environnementale de ces centres (ce que font déjà les hébergeurs, pas forcément par conscience écologique, mais pour réduire leur importante facture électrique) mais chercher à réduire leur nombre, comme le fait cette tribune, revient à diminuer l'utilisation du numérique. C'est un discours classique chez les politiciens conservateurs et les médias (« c'était mieux avant ») mais il n'en est pas moins agaçant. (Et il est surtout motivé par le regret que le numérique leur a retiré leur monopole de la parole publique.)

Concernant le projet de taxe proportionnelle à la quantité de données stockées, il faut noter qu'il repose sur une idée fausse, déjà démolie beaucoup de fois, comme quoi la consommation serait proportionnelle au nombre d'octets.

Ensuite, cette tribune pose un gros problème sur la forme. Son auteur abuse de trucs rhétoriques pour diaboliser les centres de données. Il parle d'industrie « prédatrice » (comme si les centres de données arrivaient la nuit et rasaient les terrains pour s'y installer sans autorisation), de chiffres qui « donnent le vertige » (« la consommation de 600 000 habitants » alors que les centres de données installés à Marseille servent bien plus que 600 000 personnes, vu l'importance de cette ville), et il se permet même de parler de « colonisation », une boursouflure rhétorique scandaleuse, quand on pense à ce qu'était vraiment la colonisation, avec son cortège de massacres.

En parlant de la forme de cette tribune, on peut aussi s'étonner du fait qu'elle ne soit pas publique. Logiquement, quand on expose ses idées politiques, on cherche à toucher le plus de monde possible. Ici, au contraire, l'auteur de la tribune se restreint. Pourquoi n'avoir pas mis cette tribune sur son blog ? Ou celui de son parti ? Ou sur une des millions de solutions d'hébergement (par exemple, mais ce n'est qu'un exemple, WriteFreely) ? Probablement parce que les politiciens traditionnels croient que la publication dans un média classique lui donne une légitimité plus forte (c'est faux : les tribunes ne sont pas écrites par les journalistes, ni vérifiées par la rédaction).

Revenons au fond de la tribune. Elle reproche aux centres de données de ne pas être créateurs d'emplois. Là, on rentre dans un sérieux problème politique : le but de l'activité économique n'est pas de créer des emplois, c'est de produire des biens et des services utiles. Si on voulait juste créer des emplois, on supprimerait les machines et on travaillerait à la main partout, ce qu'évidemment personne ne souhaite. Il faut agir pour la réduction du temps de travail, permise, entre autres, par le numérique, et pas pour donner davantage de travail aux gens.

Dernier point, la tribune parle de « nombreux privilèges » des centres de données mais n'en cite qu'un, « l'abattement sur le prix d'achat de l'électricité ». J'avoue ne pas être spécialiste des prix de l'électricité, mais, bien sûr, il n'y a aucune raison de faire des prix particuliers pour les centres de données, par rapport aux autres activités économiques. Simplement, je n'ai pas vérifié ce point (voyez les notes de Jérôme Nicolle). Quelqu'un a des informations fiables à ce sujet ? (Je lis l'article 266 quinquies C du code des douanes mais il semble abrogé.)


L'article seul

Deux exemples d'un problème DNS sur des domaines importants

Première rédaction de cet article le 5 août 2023


Vous le savez, l'Internet n'est pas un long fleuve tranquille. Il y a des pannes, des attaques, des erreurs… La vie des administrateurs système et réseau est donc rarement ennuyeuse. Ainsi, aujourd'hui, deux domaines importants ont eu des problèmes. Plongeons-nous un peu dans le DNS et ses particularités.

Premier domaine touché, gouv.nc, le domaine du gouvernement néo-calédonien. Des utilisateurs se plaignent qu'ils n'arrivent pas à accéder aux services sous ce nom, ni à ceux sous des noms hébergés sur les mêmes serveurs, comme prix.nc. Voyons (avec check-soa) les serveurs faisant autorité pour ce domaine :

% check-soa -i gouv.nc
ns4.gouv.nc.
	61.5.212.4: OK: 2020111850 (293 ms)
ns5.gouv.nc.
	61.5.212.5: OK: 2020111850 (293 ms)
  

Ici, tout marche. Mais ce n'est pas le cas tout le temps, on observe de nombreux timeouts  :

%    check-soa -i gouv.nc
ns4.gouv.nc.
	61.5.212.4: ERROR: read udp 192.168.2.4:33577->61.5.212.4:53: i/o timeout
ns5.gouv.nc.
	61.5.212.5: ERROR: read udp 192.168.2.4:41598->61.5.212.5:53: i/o timeout
  

On le voit aussi en utilisant les sondes RIPE Atlas (via le programme Blaeu) :

% blaeu-resolve --type A --requested 100 gouv.nc
[ERROR: SERVFAIL] : 40 occurrences 
[61.5.212.17] : 22 occurrences 
Test #58257507 done at 2023-08-05T18:32:26Z

Pourquoi ce problème ? De l'extérieur, je ne peux évidemment pas donner de réponse définitive mais j'observe déjà que ce domaine n'a que deux serveurs de noms, ce qui est souvent insuffisant, et que la proximité de leurs adresses IP fait fortement soupçonner qu'ils sont dans la même pièce, formant un SPOF. Y a-t-il eu une panne complète, par exemple une coupure de courant dans cette pièce ? Comme on observe que ces serveurs répondent parfois, on peut écarter cette hypothèse et penser plutôt, soit à une dégradation importante du réseau (réseau surchargé, ou bien physiquement abimé), soit à une attaque par déni de service. Ces attaques, sous leur forme la plus simple, volumétrique (l'attaquant envoie simplement le plus possible de requêtes), saturent le réseau ou les serveurs. Dans ce cas, les serveurs répondent encore parfois, mais pas toujours. Comme le problème a été souvent observé ces derniers mois, et que le domaine gouv.nc a les mêmes caractéristiques (domaine d'un service public français, et hébergement DNS très faible), il n'est pas impossible qu'il soit victime de la même campagne d'attaques.

Et le deuxième domaine ? C'est impots.gouv.fr, qui a lui aussi les mêmes caractéristiques, quoique moins marquées, et qui faisait déjà partie des victimes précédentes.

% check-soa impots.gouv.fr
dns1.impots.gouv.fr.
	145.242.11.22: ERROR: read udp 192.168.2.4:35263->145.242.11.22:53: i/o timeout
dns2.impots.gouv.fr.
	145.242.31.9: OK: 2023080400

Et, avec les sondes Atlas :

% blaeu-resolve --type A --requested 100 --country FR impots.gouv.fr
[145.242.11.100] : 55 occurrences 
[ERROR: SERVFAIL] : 14 occurrences 
Test #58257393 done at 2023-08-05T18:25:42Z
  

On notera que gouv.nc a une autre caractéristique, que n'a pas le domaine des impôts : les TTL sont très bas. On le voit avec dig :


%  dig @61.5.212.4 gouv.nc A
;; communications error to 61.5.212.4#53: timed out
;; communications error to 61.5.212.4#53: timed out
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2499
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3
...
;; ANSWER SECTION:
gouv.nc.		30 IN A	61.5.212.17

;; AUTHORITY SECTION:
gouv.nc.		300 IN NS ns4.gouv.nc.
gouv.nc.		300 IN NS ns5.gouv.nc.
...
;; Query time: 292 msec
;; SERVER: 61.5.212.4#53(61.5.212.4) (UDP)

Le TTL pour l'adresse IP associée à gouv.nc est de seulement 30 secondes. Cela veut dire que, même si un client DNS, comme un résolveur a de la chance et réussit à obtenir une réponse d'un des serveurs faisant autorité, elle ne lui servira que pendant trente secondes, suite auxquelles il devra retenter sa chance, avec une forte probabilité que ça rate. C'est en effet un des plus gros inconvénients des TTL extrêmement bas, comme ceux-ci : ils aggravent considérablement les effets des dénis de service. Les variations d'une mesure à l'autre sont donc bien plus marquées pour gouv.nc que pour impots.gouv.fr.

Le TTL des enregistrements NS (serveurs de noms) est plus long (cinq minutes). Notez que celui affiché ci-dessus est le TTL indiqué par les serveurs faisant autorité, celui de la zone gouv.nc elle-même. Il y a un autre TTL (une heure) dans la délégation depuis .nc, dans la zone parente :


%  dig @ns1.nc gouv.nc A
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30267
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 3
...
;; AUTHORITY SECTION:
gouv.nc.		3600 IN	NS ns4.gouv.nc.
gouv.nc.		3600 IN	NS ns5.gouv.nc.

  

La plupart des résolveurs enregistreront le TTL de la zone (ici, cinq minutes), qui, lui, fait autorité (regardez le flag aaAuthoritative Answer - dans la réponse).

Pour mieux évaluer l'état d'un serveur de noms (résolveur ou serveur faisant autorité) lors d'un problème comme une attaque par déni de service, j'ai fait un petit script en Python simple qui interroge le serveur plusieurs fois et affiche le taux de réussite :

% python assess-dos.py  --server 145.242.31.9   impots.gouv.fr
Expect an answer in more or less 300.0 seconds
2 requests among 10 (20.0 %) succeeded. Average time 0.010 s. Measurement done on 2023-08-05T18:46:30Z.
  

Le script dispose de plusieurs options utiles (pour l'instant, sa seule documentation est le code source) : le nombre de requêtes à faire, l'écart entre deux requêtes, la gigue à ajouter, le délai d'attente maximum, le serveur à utiliser (par défaut, c'est le résolveur habituel de votre machine), le type d'enregistrement DNS à demander, etc. Voici un exemple pendant le problème, utilisant de nombreuses options :

% python assess-dos.py  --number 118 --delay 30.1  --server 145.242.31.9  --jitter 6  --type a impots.gouv.fr
Expect an answer in more or less 3551.8 seconds
0 requests among 118 (0.0 %) succeeded. Average time N/A. Measurement done on 2023-08-05T18:00:16Z.
  

Ici, le serveur de impots.gouv.fr ne répondait pas du tout pendant la mesure.

% python assess-dos.py  --number 118 --delay 30.1  --server 61.5.212.4  --jitter 6  --type a gouv.nc        
Expect an answer in more or less 3551.8 seconds
19 requests among 118 (16.1 %) succeeded. Average time 0.3 s. Measurement done on 2023-08-05T17:56:51Z.
  

Ici, le serveur de gouv.nc répondait encore dans 16 % des cas. C'est très insuffisant, la plupart des résolveurs ne réessaient que trois, quatre ou cinq fois.

Dans le tout premier exemple, on n'avait pas indiqué de serveur, dans ce cas, c'est le résolveur par défaut qui est utilisé. Comme il mémorise les réponses, il vaut mieux indiquer un délai qui soit supérieur au TTL :

% python assess-dos.py  --number 113 --delay 30.1    --type a gouv.nc
Expect an answer in more or less 3401.3 seconds
62 requests among 113 (54.9 %) succeeded. Average time 0.350 s. Measurement done on 2023-08-05T18:57:25Z.
  

Traditionnellement, les résolveurs DNS ne renvoyaient guère d'information à leur client en cas d'échec, on était loin de la richesse des codes de retour HTTP. Mais cela a changé avec EDE, les Extended DNS Errors du RFC 8914. Demandons au résolveur de Google, on obtient bien le code EDE 22 et une explication :

  

% dig @8.8.8.8 gouv.nc A
...;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 26442
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
...
; EDE: 22 (No Reachable Authority): (At delegation gouv.nc for gouv.nc/a)
... 


L'article seul

Fiche de lecture : Artificial intelligence and international conflict in cyberspace

Auteur(s) du livre : Fabio Cristano, Dennis Broeders, François Delerue, Frédérick Douzet, Aude Géry
Éditeur : Routledge
978-1-03-225579-8
Publié en 2023
Première rédaction de cet article le 1 août 2023


L'IA est partout (même si le terme est très contestable, et est utilisé à toutes les sauces sans définition rigoureuse) et il est donc logique de se demander quel sera son rôle dans les conflits (notamment les guerres). Cet ouvrage universitaire collectif rassemble divers points de vue sur la question, sous l'angle du droit, et de la géopolitique.

Bon, justement, c'est un ouvrage collectif (dont la coordination a été assurée en partie par des chercheuses de GEODE, dont je recommande le travail). Comme tous les ouvrages collectifs, les points de vue, le style, et les méthodes sont variées. Et puis, commençons par cela, le sujet est relativement nouveau, il a produit beaucoup de fantasmes et de délires mais encore peu de travaux sérieux donc ce livre est une exploration du champ, pas un ensemble de réponses définitives. Attention, il est plutôt destiné à des universitaires ou en tout cas à un public averti.

Tous les articles ne concernent d'aileurs pas directement le sujet promis par le titre. (L'article de Arun Mohan Sukumar, par exemple, article par ailleurs très intéressant, ne parle d'IA que dans son titre, et ne concerne pas vraiment les conflits internationaux.) C'est en partie dû au fait que le terme flou d'IA regroupe beaucoup de choses, pas clairement définies. On peut aussi noter que certains articles incluent de l'IA mais sont en fait plus généraux : l'article de Jack Kenny sur l'intervention de pays étrangers dans les processus électoraux en est un bon exemple (le fait que le pays qui intervient utilise ou pas l'IA ne me semble qu'un détail).

Pour les articles qui parlent d'IA, de nombreux sujets sont abordés : éthique de l'IA dans la guerre (mais je n'ai pas de réponse à la question « est-ce que les humains font mieux, sur le champ de bataille ? »), régulation (sujet difficile en droit international ; et puis il est bien plus difficile de contrôler les IA que des missiles, qui sont difficiles à dissimuler), souveraineté numérique, etc.

Bref, il me semble que la question est loin d'être épuisée. Non seulement on ne peut pas s'appuyer sur une définition claire de ce qui est inclus sous l'étiquette « IA » mais on n'a pas encore bien décrit en quoi l'IA changeait les choses et justifiait un traitement particulier. Lorsqu'un drone se dirige vers sa cible, en quoi le fait que son logiciel soit qualifié d'« IA » est-il pertinent, pour les questions d'éthique et de droit de la guerre ? Une réponse évidente est « lorsqu'il peut choisir sa cible, et pas seulement se diriger vers celle qu'on lui a affecté ». Mais cela restreindrait sérieusement le nombre de systèmes qu'on peut qualifier d'« IA ».

Le livre en version papier est plutôt cher (déclaration : j'ai eu un exemplaire gratuitement) mais on peut aussi le télécharger gratuitement. Chaque article a une longue bibliographie donc vous aurez beaucoup de lecture cet été.


L'article seul

Un peu de langage d'assemblage du RISC-V sur Linux

Première rédaction de cet article le 9 juillet 2023


Un peu de distraction sans objectif utilitaire à court terme : programmons en langage d'assemblage (ce qui est souvent appelé par abus de langage « assembleur ») sur un processeur RISC-V, dans un environnement Linux.

Cet article vise un public qui sait programmer mais sans avoir fait (ou très peu) de langage d'assemblage. Car oui, un problème terminologique fréquent est de parler d'« assembleur » alors que, en toute rigueur, ce terme désigne le programme qui, comme un compilateur, va traduire le langage d'assemblage en code machine. Ce langage d'assemblage est un langage de bas niveau, ce qui veut dire qu'il est proche de la machine. C'est d'ailleurs un de ses intérêts : regarder un peu comment ça fonctionne sous le capot. On lit parfois que ce langage est tellement proche de la machine qu'il y a une correspondance simple entre une instruction en langage d'assemblage et une instruction de la machine mais ce n'est plus vrai depuis longtemps. Comme un compilateur, l'assembleur ne va pas traduire mot à mot le programme. Il a, par exemple, des « pseudo-instructions » qui vont être assemblées en une ou plusieurs instructions. L'informatique, aujourd'hui, est formée de nombreuses couches d'abstraction empilées les unes sur les autres et on ne peut pas vraiment dire qu'en programmant en langage d'assemblage, on touche directement à la machine. (D'ailleurs, certains processeurs contiennent beaucoup de logiciel, le microcode.)

Pourquoi programmer en langage d'assemblage alors que c'est bien plus facile en, par exemple, C (ou Rust, ou Go, comme vous voulez) ? Cela peut être pour le plaisir d'apprendre quelque chose de nouveau et de très différent, ou cela peut être pour mieux comprendre l'informatique. Par contre, l'argument « parce que cela produit des programmes plus rapides » (ou, version 2023, parce que ça économise des ressources et que l'ADEME sera contente de cet effort pour économiser l'énergie), cet argument est contestable ; outre le risque plus élevé de bogues, le programme en langage d'assemblage ne sera pas automatiquement plus rapide, cela dépendra des compétences du programmeur ou de la programmeuse, et programmer dans ce langage est difficile. (Le même argument peut d'ailleurs s'appliquer si on propose de recoder un programme Python en C « pour qu'il soit plus rapide ».)

Chaque famille de processeurs (x86, ARM, etc) a son propre code machine (qu'on appelle l'ISA pour Instruction Set Architecture) et donc son propre langage d'assemblage (une des motivations de C était de fournir un langage d'assez bas niveau mais quand même portable entre processeurs). Je vais utiliser ici un processeur de la famille RISC-V.

Si on veut programmer avec le langage de cette famille, on peut bien sûr utiliser un émulateur comme QEMU, mais c'est plus réaliste avec un vrai processeur RISC-V. Je vais utiliser celui de ma carte Star 64. Un noyau Linux tourne sur celle-ci et on verra qu'on sous-traitera certaines tâches à Linux. Commençons par un programme trivial, éditons trivial.s :

addi    x10, x0, 42

L'instruction addi (Add Immediate car son dernier argument est un littéral, immediate data) fait l'addition, la destination est le registre x10. On y met le résultat de l'addition du registre x0 (qui contient toujours zéro, un peu comme le pseudo-fichier /dev/zero) et du nombre 42. La liste complète des instructions que connait le processeur RISC-V figure dans le The RISC-V Instruction Set Manual mais ce texte est difficile à lire, étant plutôt orienté vers les gens qui conçoivent les processeurs ou qui programment les assembleurs. (Et il ne contient pas les pseudo-instructions.) Je me sers plutôt de documents de synthèse comme celui de metheis ou bien la RISC-V Instruction-Set Cheatsheet.

On va assembler notre petit programme, avec l'assembleur as :

% as -o trivial.o trivial.s

Puis on fabrique un exécutable avec le relieur :

% ld -o trivial trivial.o 
ld: warning: cannot find entry symbol _start; defaulting to 00000000000100b0

Et l'avertissement ? Contrairement aux langages de plus haut niveau, qui s'occupent des détails comme de démarrer et d'arrêter le programme, le langage d'assemblage vous laisse maitre et, ici, je n'ai pas défini l'endroit où démarrer. Bon, ce n'est qu'un avertissement, exécutons le programme :

% ./trivial
Illegal instruction (core dumped)
 

Ajoutons explicitement un point d'entrée pour traiter l'avertissement obtenu :

.global _start                                                                                      

_start: 
        addi    x10, x0, 2
  

On n'a plus l'avertissement, mais le programme plante de la même façon. C'est en fait à la fin du programme qu'il y a un problème : le programme n'a pas d'instruction d'arrêt, l'assembleur n'en a pas ajouté (contrairement à ce qu'aurait fait un compilateur C), et l'« instruction » suivant addi est en effet illégale (c'est la fin du code). On va donc ajouter du code pour finir proprement, en utilisant un appel système Linux :

_start: 
        addi    x10, x0, 2

        # Terminons proprement (ceci est un commentaire)
        li    x10, 0
        li    x17, 93   # 93 = exit
        ecall

Cette fois, tout se passe bien, le programme s'exécute (il n'affiche rien mais c'est normal). Il faut maintenant expliquer ce qu'on a fait pour que ça marche.

On veut utiliser l'appel système exit. Sur une machine Linux, man 2 exit vous donnera sa documentation. Celle-ci nous dit qu'exit prend un argument, le code de retour. D'autre part, les conventions de passage d'arguments de RISC-V nous disent qu'on met l'argument dans le registre x10, et, lorsqu'on fait un appel système, le numéro de cet appel dans x17. Ici, 93 est exit (si vous voulez savoir où je l'ai trouvé, grep _exit /usr/include/asm-generic/unistd.h). li (Load Immediate) va écrire 0 (le code de retour) dans x10 puis 93 dans x17. Enfin, ecall va effectuer l'appel système demandé, et on sort proprement. (Vous noterez que li x10, 0 est parfaitement équivalent à addi x10, x0, 0, et l'assembleur va produire exactement le même code dans les deux cas.) Pour davantage de détails sur l'utilisation des appels système Linux, voir Linux System Calls for RISC-V with GNU GCC/Spike/pk.

Bon, ce programme n'était pas très passionnant, il additionne 0 + 2 et met le résultat dans un registre mais n'en fait rien ensuite. On va donc passer à un programme plus démonstratif, un Hello, world. Le processeur n'a pas d'instructions pour les entrées-sorties, on va sous-traiter le travail au système d'exploitation, via l'appel système Linux write, qui a le numéro 64 (rappelez-vous, il faut regarder dans /usr/include/asm-generic/unistd.h) :

.global _start

_start:
        la    x11, helloworld

        # Print
        addi  x10, x0, 1 # 1 = standard output
        addi  x12, x0, 13 # 13 bytes
        addi  x17, x0, 64                                                                                                 
        ecall

        # Exit
        addi    x10, x0, 0
        addi    x17, x0, 93     
        ecall

.data
helloworld:      .ascii "Hello World!\n"
  

Qu'a-t-on fait ? On a réservé une chaine de caractères dans les données, nommée helloworld. On charge son adresse (car man 2 write nous a dit que les arguments étaient le descripteur de fichier de la sortie, mis dans x10, une adresse et la longueur de la chaine) dans le registre x11, la taille à écrire dans x12 et on appelle write. Pour compiler, on va arrêter de se servir de l'assembleur et du relieur directement, on va utiliser gcc qui les appelle comme il faut :

% gcc  -nostdlib -static -o hello-world hello-world.s

% ./hello-world 
Hello World!
  

C'est parfait, tout marche (normal, je ne l'ai pas écrit moi-même). Le -nostdlib était pour indiquer à gcc qu'on n'utiliserait pas la bibliothèque C standard, on veut tout faire nous-même (ou presque, puisqu'on utilise les appels système du noyau Linux ; si on écrivait un noyau, sans pouvoir compter sur ces appels système, la tâche serait bien plus difficile).

Si vous lisez du code en langage d'assemblage écrit par d'autres, vous trouverez peut-être d'autres conventions d'écriture. Par exemple, le registre x10 peut aussi s'écrire a0, ce surnom rappelant son rôle pour passer des arguments (alors que x préfixe les registres indépendamment de leur fonction). De même, des mnémoniques comme zero peuvent être utilisés, ce dernier désignant x0 (registre qui, rappelons-le, contient toujours zéro). La documentation de ces écritures possibles est la « RISC-V ABIs Specification ». On voit ces variantes dans l'écriture si on demande au désassembleur de désassembler le code trivial :


$ objdump -d trivial.o
...
Disassembly of section .text:

0000000000000000 <_start>:
   0:   00200513                li      a0,2

Le addi x10, x0, 2 est rendu par l'équivalent li a0, 2.

Faisons maintenant quelque chose d'un tout petit peu plus utile. On va décrémenter un nombre jusqu'à atteindre une certaine valeur. Mais attention : afficher un nombre (pour suivre les progrès de la boucle) n'est pas trivial. write ne sait pas faire, il sait juste envoyer vers la sortie les octets. Ça marche bien avec des caractères ASCII comme plus haut, mais pas avec des entiers. On va donc tricher en utilisant des nombres qui correspondent à des caractères ASCII imprimables. Voici le programme :

.equ SYS_WRITE, 64
.equ SYS_EXIT, 94
.equ STDOUT, 1
.equ SUCCESS, 0
        
.global _start                                                                                      

_start: 

        # The decrement
        li t2, 1
        # The final value (A)
        li t1, 65
        # The first value (Z) then the current value
        li t0, 90

loop:
        # Store on the stack
        sb  t0, 0(sp)

        # Print the current value (it is copied on the stack)
        li a0, STDOUT
        add a1, zero, sp
        addi  a2, x0, 1        # 1 byte (parameter count of write() )
        addi  a7, x0, SYS_WRITE
        ecall

        # Decrement
        sub t0, t0, t2

        # End of loop?
        ble t1, t0, loop # BLE : Branch If Lower Or Equal

        # Print the end-of-line
        li a0, STDOUT   
        la    a1, eol
        addi  a2, x0, 1
        addi  a7, x0, SYS_WRITE
        ecall

        # Exit
        li    a0, SUCCESS
        addi    a7, x0, SYS_EXIT
        ecall

.data
eol:      .ascii "\n"
  

C'était l'occasion de voir :

  • Une nouvelle instruction, BLE (Branch if Lower or Equal) qui teste ses arguments et saute à une étiquette (ici, loop) selon le résultat de la comparaison. Grâce à cette instruction, on peut écrire toutes les structures de contrôle (ici, une boucle).
  • Une autre instruction, SB (Store Byte) pour écrire dans la mémoire (et non plus dans un registre du processeur).
  • Le pointeur de pile, SP (Stack Pointer), alias du registre x2.
  • Les directives à l'assembleur comme .equ, qui affecte un nom plus lisible à une valeur. La liste de ces directives (on avait déjà vu .global) est disponible.

Nous avions besoin d'écrire en mémoire car write prend comme deuxième argument une adresse. Comme nous n'avons pas encore alloué de mémoire, utiliser la pile est le plus simple. (Sinon, il aurait fallu réserver de la mémoire dans le programme, ou bien utiliser les appels système brk ou mmap après son lancement.)

Si on veut formater un nombre pour l'imprimer, c'est plus compliqué, donc je copie le code écrit par code4eva sur StackOverflow. Voyons cela avec une fonction qui trouve le plus grand de deux nombres (mis respectivement dans les registres a0 et a1, le résultat, toujours en suivant les conventions d'appel, sera dans a0) :

_start:
    # Les deux nombres à comparer
    li a0, -1042
    li a1, 666
    call max
    # On sauvegarde le résultat
    add s0, zero, a0
    ...
    
max:
	blt a0, a1, smallerfirst
	ret

smallerfirst:
	add a0, zero, a1
	ret
  

L'instruction call appelle la fonction max, qui prendra ses arguments dans a0 et a1. La pseudo-instruction ret (Return, équivalente à jalr x0, x1, 0) fait revenir de la fonction, à l'adresse sauvegardée par le call. Notez que call est en fait une pseudo-instruction (vous en avez la liste), que l'assembleur traduira en plusieurs instructions du processeur. C'est ce qui explique que vous ne trouverez pas call dans la spécification du jeu d'instructions RISC-V. Le programme entier, avec affichage du résultat, est dans max.s.

Souvent on n'écrit pas l'entièreté du programme en langage d'assemblage, mais seulement les parties les plus critiques, du point de vue des performances. La ou les fonctions écrites en langage d'assemblage seront donc appelées par un programme en C ou en Go. D'où l'importance de conventions partagées sur l'appel de fonctions, l'ABI (Application Binary Interface) qui permettront que les parties en C et celles en langage d'assemblage ne se marcheront pas sur les pieds (par exemple n'écriront pas dans des registres censés être stables), et qui garantiront qu'on pourra lier des codes compilés avec des outils différents. Voici un exemple où le programme principal, qui gère l'analyse et l'affichage des nombres, est en C et le calcul en langage d'assemblage. Il s'agit de la détermination du PGCD par l'algorithme d'Euclide, qui est trivial à traduire en assembleur. Les sources sont pgcd.s et call-pgcd.c :

% gcc -Wall -o pgcd call-pgcd.c pgcd.s

%./pgcd  999 81
pgcd(999, 81) = 27

En regardant le source en langage d'assemblage, vous verrez que le respect des conventions (les deux arguments dans a0 et a1, le résultat retourné dans a0) fait que, l'ABI étant respectée, les deux parties, en C et en langage d'assemblage, n'ont pas eu de mal à communiquer.

Autre exemple de programme, on compte cette fois de 100 à 1, en appelant la fonction num_print pour afficher le nombre. Attention à bien garder ses variables importantes dans des registres sauvegardés (mnémonique commençant par s) sinon la fonction num_print va les modifier. Le programme est loop-print.s.

Un dernier truc : le compilateur C peut aussi produire du code en langage d'assemblage, ce qui peut être utile pour apprendre. Ainsi, ce petit programme C :

void main() {
  int x = 1;
  x = x + 3;
}
  

Une fois compilé avec gcc -S minimum.c, il va donner un fichier minimum.s avec, entre autres instructions de gestion du démarrage et de l'arrêt du programme :

	li	a5,1
	sw	a5,-20(s0)
	lw	a5,-20(s0)
	addiw	a5,a5,3
	sw	a5,-20(s0)
  

On y reconnait l'initialisation de x à 1 (x est stocké dans le registre a5 avec un liLoad Immediate, charger un littéral, son écriture en mémoire vingt octets sous s0 (le registre s0 a été initialisé plus tôt, pointant vers une zone de la pile) avec sw (Store Word), puis son addition avec 3 par addiw (Add Immediate Word) et son retour en mémoire avec un sw. (L'instruction lw me semble inutile puisque a5 contenait déjà la valeur de x.)

Quelques documents et références pour finir :


L'article seul

Le colloque « Penser et créer avec les IA génératives »

Première rédaction de cet article le 3 juillet 2023


Les 29 et 30 juin derniers, j'ai eu le plaisir de suivre le colloque « Penser et créer avec les IA génératives ». C'était très riche, donc je ne vais pas pouvoir vous raconter tout mais voici quelques informations quand même.

Un petit rappel sur ces « IA génératives ». Ce sont les systèmes logiciels qui permettent de générer textes, sons et images, de manière « intelligente » (le I de IA), ou en tout cas ressemblant beaucoup à ce que pourrait faire un être humain. Les plus connues sont dans doute ChatGPT pour le texte et Midjourney pour l'image. Le domaine est en pleine expansion depuis quelques années, avec le développement de plusieurs modèles de langages (LLM), et a connu une grand succès médiatique avec la sortie de ChatGPT fin 2022. (J'ai écrit un court article sur ChatGPT et un plus long sur son utilisation pour la programmation.) Depuis, on voit apparaitre de nombreux projets liés à ces IA génératives.

Rappelons aussi (ça va servir pour les discussions sur l'« ouverture » et la « régulation ») qu'un système d'IA générative repose sur plusieurs composants :

  • Un corpus de textes (ou d'images) sur lequel le système s'entraine (comme Common Crawl). Le choix de ce corpus est crucial, et beaucoup de LLM ne sont pas très bavards sur la composition de leur corpus.
  • Des détails pratiques sur l'utilisation du corpus, comment il est analysé et digéré. Cette condensation du corpus en un modèle est une opération lourde en ressources informatiques.
  • À ce stade, on a le LLM (le grand modèle de langage). Celui de ChatGPT se nomme GPT mais il y en a beaucoup d'autres comme LLaMA ou Bloom. Il reste à le faire tourner pour générer des textes, en réponse à une requête (appelée prompt), ce qui nécessite un autre logiciel, le moteur, souvent moins consommateur de ressources mais qui tourne plus souvent.

Ce colloque était organisé par plusieurs organisations et groupes de recherche en sciences humaines, même si quelques exposés et discussions sont allés assez loin dans la technique. Beaucoup de débats étaient plutôt d'ordre philosophique comme « l'IA générative fait-elle preuve de créativité ? » (discussion d'autant plus difficile qu'on ne sait pas définir la créativité) ou bien « la compréhension dépend-elle d'un vécu ? Peut-on comprendre le concept de poids si on n'a jamais eu à soulever un objet lourd ? » Voyons quelques-uns de ces exposés et discussions.

Olivier Alexandre a présenté l'histoire d'OpenAI, l'entreprise derrière ChatGPT (et DALL-E). Une belle histoire, en effet, comme la Silicon Valley les aime, avec un début dans un restaurant très chic de la vallée, où chacun met quelques millions sur la table pour lancer le projet. Depuis, OpenAI n'a toujours rien gagné et a brûlé des milliards, mais les investisseurs continuent à lui faire confiance. « Du capitalisme d'accumulation… de dettes. » OpenAI, à ses débuts, se voulait missionnaire, produisant des IA « ouvertes » (d'où le nom), face au risque que des méchants ne cherchent à imposer une IA entièrement contrôlée par eux. Le moins qu'on puisse dire, c'est qu'OpenAI a sérieusement pivoté (comme on dit dans la Silicon Valley) depuis… « Passé de ouvert, gratuit et messianique, à fermé, payant et porté sur la panique morale ». On peut aussi noter qu'OpenAI aime bien se réclamer de la « diversité », tarte à la crème de la Silicon Valley. Or, si ses fondateurs et dirigeants ont effectivement des couleurs de peau et des lieux de naissance très variés, il n'y a qu'un seul sexe (je vous laisse deviner lequel), et surtout une seule idéologie, le capitalisme.

Ksenia Ermoshina, spécialiste de l'étude de la censure en ligne, a parlé de la censure des IA. On le sait, ChatGPT refuse de répondre à certaines questions, même lorsqu'il en aurait la capacité. Un mécanisme de censure est donc bâti dans ce système. L'oratrice note qu'il y a déjà eu des choix politiques lors de la construction du modèle. Une étude montre ainsi qu'un LLM entrainé avec les données de Baidu Baike considère que les concepts « démocratie » et « chaos » sont proches, alors que tout ce qui tourne autour de l'idée de surveillance est connoté positivement. Et, justement, il existe des LLM dans d'autres pays, comme le russe RuDall-E ou le chinois Ernie-ViLG. Sautons tout de suite à la conclusion : il y a autant de censure dans les projets « ouverts » et autant de censure en Occident.

RuDall-E, IA russe de génération d'images a quelques bavures amusantes : si on lui demande un « soldat Z », elle dessinait un zombie… Mais, autrement, RuDall-E est bien censuré. « Dessine le drapeau ukrainien » ne donnera pas le résultat attendu par l'utilisatrice. Curiosité : au lieu d'un message clair de refus, lorsque la demande est inacceptable, RuDall-E dessine des fleurs… (Mais, dans le code source de la page, du JSON nous dit bien censored: true.) Bizarrement, une requête en anglais est moins censurée.

Une IA étatsunienne comme DALL-E censure tout autant. La nudité est interdite (malgré sa présence importante dans l'art depuis des millénaires), en application du puritanisme étatsunien, mais il y a aussi des censures plus surprenantes, par exemple la requête a monkey on a skateboard made of cheese est rejetée. Et, contrairement à son concurrent russe et à ses hypocrites fleurs, ce refus est accompagné d'un message menaçant, prétendant qu'on a violé les règles communautaristes et avertissant du risque d'être banni si on continue. Comme dans tous les cas de censure, les utilisateurices cherchent et trouvent des contournements. Si on veut dessiner un mort, on ne doit pas écrire le mot « mort », qui est tabou, il faut le décrire comme « allongé par terre sans mouvement ». Pour obtenir un cocktail Molotov, on va dire « burning bottle », etc. Ce genre de techniques est largement partagé sur les réseaux sociaux.

L'IA générative d'images en Chine, contrairement à la russe, n'a pas de politique publiée, mais censure quand même, bien sûr. Leur liste de mots-clés interdits est apparemment différente de celle de WeChat (qui a été très étudiée). Car c'est bien un système de censure par mots-clés. On parle d'« intelligence artificielle » mais les systèmes de censure restent très grossiers, ce qui facilite leur contournement. (Notez que son modèle est disponible sur Hugging Face.)

Bilel Benbouzid et Maxime Darin ont parlé justement d'Hugging Face qui se veut le « GitHub de l'IA ». Hugging Face est une plate-forme de distribution de modèles de langage, et d'outils permettant de les faire tourner. À l'origine du projet, c'était un simple chatbot conçu pour adolescents. Contrairement à OpenAI, qui est parti d'une plate-forme censée être « ouverte », pour devenir de plus en plus fermé, Hugging Face s'est ouvert. Le succès a été immense, tout le monde veut être présent/accessible sur Hugging Face. Cela lui vaut donc un statut de référence, dont les décisions vont donc influencer tout le paysage de l'IA (Benbouzid prétendait même que Hugging Face était le régulateur de l'IA). Ainsi, Hugging Face a une méthodologie d'évaluation des modèles, qui, en pratique, standardise l'évaluation.

En parlant d'Hugging Face, plusieurs discussions ont eu lieu pendant ces deux jours autour du terme d'« IA open source ». Comme le savent les lecteurices de ce blog, ce terme d'open source est, en pratique, utilisé n'importe comment pour dire n'importe quoi, et la situation est encore plus complexe avec les LLM. Si le moteur servant à exécuter le modèle est librement disponible, modifiable, redistribuable, est-ce que l'utilisateurice est libre, si le modèle, lui, reste un condensat opaque d'un corpus dont on ignore la composition et la façon dont il a été condensé ? (Pour aggraver la confusion, Darin avait défini l'open source comme la disponibilité du code source, ce qui est très loin de la définition canonique.) Le modèle LLaMa n'est pas très ouvert. En revanche, le modèle Falcon vient avec son corpus d'entrainement, deux téraoctets de données, ainsi que les poids attribués.

Le débat a ensuite porté sur la régulation et la gouvernance. Bilel Benbouzid voudrait qu'on régule l'IA open source vu son caractère crucial pour le futur ; « comme pour le climat, il faut une gouvernance ». Mais Maxime Darin faisait remarquer, prenant l'exemple de Linux, que l'absence de gouvernance formelle n'empêchait pas certains projets de très bien marcher.

Carla Marand a présenté le très intéressant projet CulturIA, sur la représentation de l'IA dans la culture. (Personnellement, j'ai beaucoup aimé le film « Her ».)

Alberto Naibo a expliqué l'utilisation de l'IA pour produire des preuves en mathématique. (On a bien dit produire des preuves, pas vérifier par un programme les preuves faites par un·e mathématicien·ne.) Bon, on est assez loin des IA génératives qui produisent des textes et des images mais pourquoi pas. Le problème est que pour l'instant, aucun LLM n'a encore produit une preuve non triviale. Les seules « IA » à l'avoir fait sont des IA d'une autre catégorie, orientée vers la manipulation de symboles.

ChatGPT lui-même peut faire des démonstrations mathématiques mais se trompe souvent voire comprend tout de travers. Il arrive ainsi à « prouver » que NOT(a OR b) implique NOT a… Dommage, car une IA de démonstration mathématique pourrait s'appuyer sur toutes les bibliothèques de théorèmes déjà formalisées pour des systèmes comme Coq.

J'ai appris à cette occasion l'existence de la conjecture de Collatz, qui n'est toujours pas démontrée. (Si vous avez le courage, lancez-vous, je me suis amusé, pendant la pause, à programmer la fonction de Collatz en Elixir, cf. collatz.exs, et elle a des propriétés amusantes.)

La question des IA génératives était étudiée sous de nombreux angles. Ainsi, Pierre-Yves Modicom a parlé de linguistique. Noam Chomsky et deux autres auteurs avaient publié une tribune dans le New York Times affirmant que ChatGPT n'avait pas de langage. Beaucoup de personnes avaient ricané devant cette tribune car elle donnait un exemple de phrase que ChatGPT ne saurait pas traiter, exemple qui n'avait même pas été testé par les auteurs (ChatGPT s'en était très bien sorti). Mais, derrière cette légèreté, il y avait un discussion de fond entre « chomskystes », plutôt « innéistes », partisans de l'idée que le langage résulte d'aptitudes innées (qui manquent à ChatGPT et l'empêchent donc de réellement discuter) et behaviouristes (ou skinneriens) qui estiment que le langage est simplement un ensemble de réactions apprises (je simplifie outrageusement, je sais, et en outre, l'orateur faisait remarquer qu'il existe plusiers variantes des théories basées sur les travaux de Chomsky, mais avec scissions et excommunications dans cette école). Les behaviouristes disent donc que le comportement de ChatGPT est une réaction aux entrées qu'il reçoit, qu'il n'a pas de théorie du langage, et n'en a pas besoin. Après, note l'orateur, savoir si ChatGPT a un langage ou pas, est peut-être un faux problème. Il est plus intéressant de l'étudier sans chercher à l'étiqueter.

Si la première journée du colloque se tenait à l'IHPST, la deuxième était à Sciences Po. Comme cette école avait été présentée dans les médias comme ayant « interdit ChatGPT », c'était l'occasion de parler de ChatGPT dans l'enseignement, avec Jean-Pierre Berthet et Audrey Lohard. Donc, Sciences Po n'interdit pas les IA par défaut. Mais il faut que l'enseignant ne l'ait pas interdit, et l'étudiant doit indiquer qu'il a utilisé une IA. Sciences Po forme d'ailleurs maintenant des enseignants à l'IA, et produit un guide pour elles et eux. (Je n'ai pas vu s'il était distribué publiquement. Lors de la discussion, des personnes ont regretté l'absence de mise en commun de telles ressources, dans l'enseignement supérieur.) La question de la recherche a aussi été discutée, avec par exemple le risque de déni de service contre le processus de relecture des articles sceintifiques, avec l'abondance d'articles écrits par l'IA. (Au passage, une grande partie des discussions dans ces deux journées semblait considérer que les articles sont entièrement écrits par un humain ou bien entièrement écrits par une IA autonome. La possibilité d'articles mixtes - un·e humain·e aidé·e par une IA - n'a guère été envisagée.) Pour la recherche, une des solutions envisagées était de rendre les soumissions d'articles publiques, pour mettre la honte aux mauvais auteurs paresseux. Mais la majorité du débat a porté sur le risque de tricherie aux examens, une obsession classique dans l'enseignement supérieur, comme si le diplôme était plus important que les connaissancs acquises.

Frédéric Kaplan a fait un intéressant exposé sur la notion de « capital linguistique » et le risque posé par la confiscation de ce capital par un petit nombre de gros acteurs. En récoltant d'énormes corpus, ces gros acteurs accumulent du capital linguistique, et peuvent même le vendre (vente de mots-clés par Google pour l'affichage des publicités). « L'économie de l'attention n'existe pas, c'est une économie de l'expression. » Une des conséquences de cette accumulation est qu'elle fait évoluer la langue. L'autocomplétion, qu'elle soit sous sa forme simple traditionnelle, ou sous sa forme sophistiquée des IA génératives va changer la langue en encourageant fortement telles ou telles formes. « Ce n'est pas par hasard que Google se nomme désormais Alphabet. » Cela n'a pas que des conséquences négatives, cela peut aussi être un facteur d'égalité ; si vous ne savez pas bien écrire, la prothèse (ChatGPT) peut le faire pour vous, vous permettant de réussir malgré Bourdieu. Mais il est quand même perturbant que, dans le futur, on ne saura peut-être plus écrire un texte tout seul. La langue ne nous appartient plus, elle est louée (un peu comme dans la nouvelle « Les haut-parleurs » de Damasio). Cela sera marqué par une rupture dans les textes, on aura des textes écrits avant 2015, avec peu ou pas d'intervention technique, et des textes produits via un outil comme ChatGPT. Bref, les futures évolutions de la langue ne se feront pas comme avant : elles seront en mode centralisé, alors que les évolutions de la langue étaient auparavant décentralisées. Est-ce que l'université va devenir l'endroit où on conserve de la ressource primaire (« bio ») ?

Tout·e utilisateurice de ChatGPT a pu observer que la rédaction de la question (le prompt) avait une grande importance pour la qualité de la réponse obtenue. Valentin Goujon a noté dans son exposé que « Pour avoir les bonnes réponses, il faut poser les bonnes questions » et que savoir écrire un prompt allait devenir une compétence utile (voire, a-t-il spéculé, un métier en soi, AI whisperer).

Il y a eu aussi des exposés plus austères (pour moi) comme celui de Célia Zolynski sur la régulation de l'IA. Le droit, ce n'est pas toujours passionnant mais, ici, c'était pertinent puisque, comme vous le savez, il y a un projet européen (qui est loin d'être abouti) d'une directive de régulation de l'IA. Cette directive, en développement depuis des années, ne prévoyait pas à l'origine le cas des IA génératives, mais ça a été ajouté par un amendement au Parlement européen, le 14 juin 2023. Mais elle a aussi parlé de questions liées au droit d'auteur. Si les philosophes discutent pour savoir si l'IA est vraiment créative, les juristes ont tranché : seul·e un·e humain·e peut bénéficier du droit d'auteur. Un texte écrit par ChatGPT n'a donc pas de protections particulières. (La question de savoir si l'auteur·e de la requête, qui a parfois dû fournir un réel travail, a des droits sur le texte produit reste ouverte.)

(Une copie de ce compte-rendu se trouve sur le site du projet CulturIA.)


L'article seul

Le problème DNSSEC venu du froid

Première rédaction de cet article le 20 juin 2023


Nous sommes en 2023, tous les logiciels libres DNS font correctement du DNSSEC depuis longtemps, les bavures des débuts semblent bien oubliées. Mais il y a des logiciels bizarres qui continuent à être utilisés, et qui ont des bogues subtiles, ce qui frappe en ce moment le TLD du Groenland.

Commençons par les observations : .gl a un problème pour ses sous-domaines comme com.gl (mais il y en a d'autres). Ces sous-domaines sont délégués, mais au même jeu de serveurs que le TLD (ce qui est une mauvaise pratique, voir à la fin). On voit le problème sur DNSviz, avec le message « NSEC3 proving non-existence of com.gl/DS: No NSEC3 RR matches the SNAME (com.gl) ». On voit aussi avec les sondes RIPE Atlas qu'un certain nombre de résolveurs n'arrive pas à résoudre les noms :

% blaeu-resolve --requested 100 --displayvalidation --type NS com.gl
[d.nic.gl. ns1.anycastdns.cz. ns2.anycastdns.cz.] : 73 occurrences 
[ERROR: SERVFAIL] : 23 occurrences 
[ERROR: NXDOMAIN] : 2 occurrences 
[ (TRUNCATED - EDNS buffer size was 4096 )  d.nic.gl. ns1.anycastdns.cz. ns2.anycastdns.cz.] : 1 occurrences 
Test #55841896 done at 2023-06-20T09:20:58Z
  

Ça veut dire quoi ?

Déboguons avec dig. Le TLD a trois serveurs de noms, testons avec d.nic.gl :


% dig @d.nic.gl NS com.gl
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23986
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
com.gl.			86400	IN	NS	ns2.anycastdns.cz.
com.gl.			86400	IN	NS	d.nic.gl.
com.gl.			86400	IN	NS	ns1.anycastdns.cz.

  

OK, ça marche. Mais tout déconne quand un résolveur validant essaie d'accéder à ce nom, et demande un enregistrement de type DS (Delegation Signer) :


% dig @d.nic.gl DS com.gl      
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 55694
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
gl.			900	IN	SOA	a.nuuk.nic.gl. gl-admin.tele.gl. 2022119306 900 1800 6048000 3600

  

Zut et zut, cette fois, cela ne marche pas, on a un NXDOMAIN (No Such Domain) alors que la requête précédente, pour le même nom, répondait positivement. Le serveur faisant autorité dit donc n'importe quoi.

Est-ce que cette réponse erronée est validable ? Oui ! Le serveur renvoie des enregistrements de type NSEC3 (RFC 5155) :

    
% dig +dnssec @d.nic.gl DS com.gl
;; Truncated, retrying in TCP mode.
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 43612
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
...
S2UOJG57GTBJ0M12ECAU9CSFD38EJNDN.gl. 3600 IN NSEC3 1 1 10 504D114B SAGKR73F41OMFFI8TDE1CGHOQM502SIH NS SOA RRSIG DNSKEY NSEC3PARAM
...
BBTTMJM743SRPQ6J4KQDIUC73E3C1HOA.gl. 3600 IN NSEC3 1 1 10 504D114B BSHTF866A32E02RJ617EUE8CCP45A6V4 NS DS RRSIG
...

  

Mais, comme le dit DNSviz plus haut, ce ne sont pas les bons. Comme, avec NSEC3, la preuve de non-existence n'utilise pas les noms de domaine mais un condensat de ces noms, il va falloir faire quelques calculs. On va utiliser le programme knsec3hash, distribué avec Knot. D'abord, trouvons les paramètres de condensation :


% dig NSEC3PARAM gl    
...;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30244
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 1
...
;; ANSWER SECTION:
gl.			0	IN	NSEC3PARAM 1 0 10 504D114B

  

1 est l'algorithme de condensation, ici SHA-1, 0 une série d'options (inutilisée ici), 10 est le nombre de condensations successives à effectuer, 504D114B est le sel. Nous pouvons donc calculer le condensat :

% knsec3hash 504D114B 1 10  gl
s2uojg57gtbj0m12ecau9csfd38ejndn (salt=504D114B, hash=1, iterations=10)
  

C'est bien le nom s2uojg57gtbj0m12ecau9csfd38ejndn vu plus haut. (On savait de toute façon qu'il s'agissait de l'apex de la zone, en raison des types SOA, DNSKEY, NSEC3PARAM, etc, qu'elle contient.) Bon, et le com.gl :

% knsec3hash 504D114B 1 10  com.gl
biavqpkequ599fc57pv9d4sfg1h0mtkj (salt=504D114B, hash=1, iterations=10)
  

Le second enregistrement NSEC3 nous dit qu'il n'y a rien entre bbttmjm743srpq6j4kqdiuc73e3c1hoa et bshtf866a32e02rj617eue8ccp45a6v4. Donc, pas de biavqpkequ599fc57pv9d4sfg1h0mtkj, ce qui implique que com.gl n'existe pas. Réponse cohérente mais fausse (le domaine existe bien).

Notez que les deux autres serveurs faisant autorité pour .gl donnent une autre réponse, toute aussi fausse mais différente :


% dig +short NS gl
ns2.anycastdns.cz.
d.nic.gl.
ns1.anycastdns.cz.

% dig +dnssec @ns1.anycastdns.cz DS com.gl 
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36229
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
s2uojg57gtbj0m12ecau9csfd38ejndn.gl. 3600 IN NSEC3 1 1 10 504D114B SAGKR73F41OMFFI8TDE1CGHOQM502SIH NS SOA RRSIG DNSKEY NSEC3PARAM

  

Cette fois, on a un NOERROR, moins grave que le faux NXDOMAIN, mais le NSEC3 est pour gl, pas pour le nom demandé (d'où le message d'erreur de DNSviz).

Comment cela a pu se produire ? Je ne connais pas de logiciel ayant ce comportement, mais je note que le domaine a pris un sérieux risque : com.gl est délégué (il y a un ensemble d'enregistrements NS) mais aux mêmes serveurs que .gl. C'est une mauvaise pratique car elle rend plus difficile le déboguage (les données de la zone fille peuvent masquer celles de la zone parente). Ce n'est pas forcément la cause primaire, mais elle n'aide pas à déblayer le problème.

(Merci à Viktor Dukhovni, inlassable détecteur et débogueur de problèmes DNSSEC dans les TLD. Il vient d'ailleurs d'en trouver un autre pour le .scot.)


L'article seul

Censure DNS du domaine d'Uptobox par Orange

Première rédaction de cet article le 15 mai 2023


Depuis ce matin, Orange censure le service Uptobox via un résolveur DNS menteur. Avec quelques particularités techniques…

Voyons d'abord les faits. Depuis une machine connectée via Orange, testons avec dig (et j'expliquerai plus tard le rôle de l'option +nodnssec, sachez seulement que le client DNS typique d'un résolveur envoie exactement cette même requête) :


% dig  +nodnssec A uptobox.com 
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38435
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
uptobox.com.		5 IN A	127.0.0.1

;; Query time: 60 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Mon May 15 16:52:31 CEST 2023
;; MSG SIZE  rcvd: 56

  

Bon, cas classique de censure par résolveur DNS menteur. Au lieu de renvoyer la vraie adresse IP, il renvoie ce 127.0.0.1 qui indique la machine locale (rien ne fonctionnera, donc). Est-ce juste chez moi ? Non. En testant avec les sondes RIPE Atlas, on voit que cela affecte beaucoup d'utilisateurs d'Orange (AS 3215) :

% blaeu-resolve --requested  100 --as 3215 --type A Uptobox.com  
[104.22.30.128 104.22.31.128 172.67.29.218] : 17 occurrences 
[127.0.0.1] : 82 occurrences 
[] : 1 occurrences 
Test #53746153 done at 2023-05-15T11:02:58Z
  

Les sondes qui obtiennent les vraies adresses sont probablement celles situées sur un réseau qui utilise un autre résolveur, par exemple un résolveur local non-menteur.

Parfois, en cas de mensonge, des résolveurs envoient des détails, par exemple sous forme d'un enregistrement SOA, dont les données indiquent la source de la censure, mais rien de tel ici. Ah, et, sinon, le blocage concerne également uptostream.com, uptobox.fr, uptostream.fr, beta-uptobox.com et uptostream.net mais je ne les ai pas testés.

Pourquoi ce blocage ? Aucun autre FAI en France ne semble le faire. Testons chez Free ou chez Bouygues :

% blaeu-resolve --requested  100 --as 12322 --type A Uptobox.com   
[104.22.30.128 104.22.31.128 172.67.29.218] : 99 occurrences 
Test #53746411 done at 2023-05-15T11:07:43Z

% blaeu-resolve --requested  100 --as  5410 --type A Uptobox.com   
[104.22.30.128 104.22.31.128 172.67.29.218] : 33 occurrences 
Test #53746432 done at 2023-05-15T11:08:30Z
  

Bon, donc, pour l'instant, seul Orange bloque (même plusieurs heures après, la situation n'avait pas changé). On aurait pu penser qu'il ne s'agissait donc probablement pas de censure étatique (puisque celle-ci s'appliquerait aux autres gros FAI) mais en fait si, comme publié par la suite.

La censure est cohérente pour IPv6 :

% blaeu-resolve --requested  100 --as 3215 --type AAAA Uptobox.com  
[] : 19 occurrences 
[::1] : 76 occurrences 
[::] : 1 occurrences 
Test #53746202 done at 2023-05-15T11:04:00Z

On obtient le ::1, équivalent IPv6 du 127.0.0.1.

Mais revenons à ce +nodnssec que j'avais promis d'expliquer. Eh bien, le comportement des résolveurs DNS d'Orange va changer selon que son client envoie ou non le bit DO (DNSSEC OK). Par défaut, dig ne l'envoie pas (donc, en toute rigueur, l'option +nodnssec n'était pas nécessaire) et le résolveur ment. Mais si on demande DNSSEC, on a une réponse sincère :


% dig  +dnssec A uptobox.com
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50574
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
uptobox.com.		300 IN A 104.22.30.128
uptobox.com.		300 IN A 172.67.29.218
uptobox.com.		300 IN A 104.22.31.128
uptobox.com.		300 IN RRSIG A 13 2 300 (
				20230516155749 20230514135749 34505 uptobox.com.
				qMunXCqcFHp34LAnTgMcJkQaUvlMaZBLIneA5eqTHW+0
				pjuD6vTVvn1xsnAAI59SOcQdgRIo5hlMLxKHZzg3Ew== )

;; Query time: 36 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Mon May 15 16:57:45 CEST 2023
;; MSG SIZE  rcvd: 195

Notez que le résolveur DNS par défaut de la connexion utilisée était un petit routeur 4G, qui relaie aux « vrais » résolveurs derrière. Si je parle directement à ceux-ci, j'observe le même phénomène :


~ % dig @81.253.149.5 +nodnssec A uptobox.com
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24064
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
uptobox.com.		5 IN A	127.0.0.1

;; Query time: 52 msec
;; SERVER: 81.253.149.5#53(81.253.149.5) (UDP)
;; WHEN: Mon May 15 16:59:14 CEST 2023
;; MSG SIZE  rcvd: 84

% dig @81.253.149.5 +dnssec A uptobox.com 
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15640
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
uptobox.com.		300 IN A 104.22.31.128
uptobox.com.		300 IN A 172.67.29.218
uptobox.com.		300 IN A 104.22.30.128
uptobox.com.		300 IN RRSIG A 13 2 300 (
				20230516155921 20230514135921 34505 uptobox.com.
				ebLAOe7dQSbyfE9Jvbq3+lvLvH5ZVB8esGxEW0mhuaR9
				HLvMNfTwkYZBEy8HEJwbfmci0sVavIhQ6ZaPJbw6SA== )

;; Query time: 64 msec
;; SERVER: 81.253.149.5#53(81.253.149.5) (UDP)
;; WHEN: Mon May 15 16:59:17 CEST 2023
;; MSG SIZE  rcvd: 223

Mais quel est le rôle de ce bit DO (DNSSEC OK) et pourquoi cette différence de comportement, que je n'avais jamais observée sur le terrain ? Ce bit, normalisé dans le RFC 3225, indique à un serveur DNS que son client comprend DNSSEC, et qu'il veut obtenir les informations DNSSEC, notamment les signatures. Outre le déboguage (dig avec l'option +dnssec), il est utilisé lorsqu'un résolveur validant parle à un serveur DNS, afin d'obtenir les informations cryptographiques à valider. Le « bête » client DNS, qui se trouve dans la machine de M. Toutlemonde, ne valide pas et fait donc une confiance aveugle au résolveur. Il n'envoie pas de bit DO (et c'est pour cela que la majorité des utilisateurs voient le nom être censuré). Mais si vous avez un résolveur qui valide, par exemple sur votre machine ou dans votre réseau local, il va envoyer le bit DO. Pourquoi est-ce que les résolveurs d'Orange se comportent différemment dans ces deux cas ? Il y a une certaine logique technique : les résolveurs DNS menteurs cassent DNSSEC (puisque DNSSEC a justement été conçu pour détecter les modifications faites par un tiers), et il est donc raisonnable, bien que ce soit la première fois que je vois cela, de ne pas mentir si on a un client validant.

Petit détail technique au passage : le domaine uptobox.com est signé mais il n'y a pas d'enregistrement DS dans la zone parente (.com) donc il n'aurait pas été validé de toute façon.

Quelques références :


L'article seul

À propos du « blocage de Telegram en France »

Première rédaction de cet article le 13 mai 2023


Ce matin, bien des gens signalent un « blocage de Telegram en France ». Qu'en est-il ? Ce service de communication est-il vraiment censuré ?

En effet, la censure ne fait aucun doute. Si on teste avec les sondes RIPE Atlas, on voit (t.me est le raccourcisseur d'URL de Telegram) :

% blaeu-resolve --country FR --requested 200 --type A t.me
[149.154.167.99] : 98 occurrences 
[77.159.252.152] : 100 occurrences 
[0.0.0.0] : 2 occurrences 
Test #53643562 done at 2023-05-13T08:42:36Z
  

Un coup de whois nous montre que la première adresse IP, 149.154.167.99, est bien attribuée à Telegram (« Nikolai Durov, P.O. Box 146, Road Town, Tortola, British Virgin Islands ») mais que la seconde, 77.159.252.152, est chez SFR. Non seulement Telegram n'a pas de serveurs chez SFR, mais si on se connecte au site Web ayant cette adresse, on voit : telegram-censure-pedo.png

Cela ne marche pas en HTTPS (de toute façon, il y aurait eu un problème de certificat) car le serveur en question n'écoute apparemment qu'en HTTP classique.

Ce site Web est donc géré par le ministère de l'Intérieur, qui peut en effet enjoindre certains FAI de bloquer les sites pédopornographiques (depuis plusieurs années, rien de nouveau). Ici, il s'agit évidemment d'un mensonge grossier puisque Telegram n'est pas un site pédopornographique, mais un service de messagerie instantanée (qui, comme tout service de communication en ligne, peut parfois être utilisé pour des activités illégales).

La technique de censure est le résolveur DNS menteur : au lieu de relayer fidèlement les réponses des serveurs DNS faisant autorité, le résolveur ment et envoie l'adresse du serveur Web du ministère. Pourquoi est-ce que toutes les sondes RIPE Atlas ne voient pas le mensonge ? Parce que la liste des sites censurés est secrète, et que beaucoup de FAI, de réseaux locaux, de résolveurs DNS publics (comme celui de FDN mais attention, certains ont des défauts) ne reçoivent pas cette liste et ne censurent donc pas. Parmi ceux qui mettent en œuvre le blocage, il y a par exemple Orange (AS 3215) :

% blaeu-resolve  --requested 200 --as 3215 --type A t.me 
[149.154.167.99] : 35 occurrences 
[77.159.252.152] : 151 occurrences 
Test #53644573 done at 2023-05-13T09:04:06Z    
  

Même chez ce FAI, on notera que certaines sondes utilisent un résolveur non-menteur, par exemple un résolveur local. On trouve aussi le blocage chez des fournisseurs plus petits comme Adista :

% blaeu-resolve  --requested 200 --as 16347  --type A t.me
[149.154.167.99] : 3 occurrences 
[77.159.252.152] : 1 occurrences 
Test #53644745 done at 2023-05-13T09:08:42Z
  

Pourquoi ce blocage alors que, on l'a vu, Telegram n'est pas, contrairement à l'accusation diffamatoire du ministère, un service de distribution d'images pédopornographiques ? Notons d'abord que le domaine principal, vers lequel redirige https://t.me/ n'est pas touché :

% blaeu-resolve --country FR --requested 200 --type A telegram.org
[149.154.167.99] : 197 occurrences 
[0.0.0.0] : 2 occurrences 
Test #53644470 done at 2023-05-13T09:02:00Z
  

Il s'agit d'une bavure, comme ça s'est déjà produit, et comme confirmé par « un porte-parole de la police nationale » cité par Le Monde. Gageons que le ministère ou les FAI ne communiqueront jamais et n'expliqueront rien.

Le service a été rétabli quelques heures après :

% blaeu-resolve --country FR --requested 200 --type A t.me
[149.154.167.99] : 199 occurrences 
[ERROR: SERVFAIL] : 1 occurrences 
Test #53674858 done at 2023-05-13T20:18:14Z
  

Un point important est la gestion des données personnelles. Le code de la page du site Web du ministère contient :


<script type="text/javascript">

	var tag = new ATInternet.Tracker.Tag();

tag.page.set({
	    name:'pedo-pornographie',
	    level2:'27'
	});
	tag.dispatch();

</script>

  

Ce petit programme en JavaScript enregistre donc les visites, auprès du service « ATInternet », en étiquetant tout visiteur, pourtant bien involontaire, comme pédo-pornographe. (Ceci, en plus de l'enregistrement habituel de l'adresse IP du visiteur dans le journal du serveur HTTP.)

Un petit point technique amusant pour finir : le serveur du ministère (celui hébergé chez SFR) n'a pas IPv6 (on est en 2023, pourtant) donc les résolveurs menteurs ne savent pas trop quoi renvoyer :

% blaeu-resolve --country FR --requested 200 --type AAAA t.me       
[2001:67c:4e8:f004::9] : 104 occurrences 
[::1] : 78 occurrences 
[] : 16 occurrences 
[::] : 1 occurrences 
[ERROR: SERVFAIL] : 1 occurrences 
Test #53646044 done at 2023-05-13T09:34:15Z
  

(2001:67c:4e8:f004::9 est la vraie adresse IP de Telegram, ::1 est l'adresse de la machine locale.)

Articles dans les médias :


L'article seul

First boot with the Star64 board (RISC-V processor)

First publication of this article on 30 April 2023
Last update on of 3 May 2023


I now have a Star64 board, a board which uses a RISC-V processor, a processor whose instruction set is free (free as in free speech, not free as in free beer). Let's see the first boot. (Désolé pour mes lecteurices francophones mais il y a peu de retours d'expérience sur le Star64 publiés donc je pense qu'il vaut mieux commencer par l'anglais pour toucher davantage de monde.)

First, a bit of context about RISC-V since it was my main motivation to buy this board. A processor is first defined by its instruction set since it is what the software will have to know: a compiler, for instance, will generate machine code for a given instruction set. The two best known instruction sets today are the Intel one ("x86") and the ARM one. They are not free, in any sense of the word. Even if you have the knowledge and the money, you are not allowed to create a processor using this set (unless you enter in an agreement with Intel or ARM), and even if you can, you have no say about its future evolutions. This is a serious issue since, in our widely digitalized world, the company controlling the processors has a lot of power.

This is why the RISC-V was developed: its instruction set is free (as I said above, quoting Stallman, "free as in free speech, not free as in free beer") and anyone can create a processor implementing it. Of course, since there is a big difference between free hardware and free software, this will not be gratis. Unlike the software, the hardware has marginal costs which are not zero; each unit produced will cost money. So, it won't be like the free software world where a student in his home can produce brilliant programs that you just have to distribute over the Internet. Actual production of the physical devices will still depend on corporations. Also, not all the components of the board are free (and, for the processor, the fact that the instruction set is free does not mean the actual processor's schematics are). But it is still a big step towards freedom. (Today, RISC-V seems mostly used in the embedded world, not in general-purpose devices.)

So, I wanted to play a bit with a RISC-V processor. Not owning a factory able to produce them from the schematics, I had to buy the processor. And not just the processor, because I'm not a hardware guy, I'm not going to connect all the necessary stuff to the SoC. I went to Pine64, which is mostly known for its various devices using an ARM processor, but which also produces a board with a RISC-V processor, the Star64 (the processor is a StarFive JH7110). I ordered one (70 US dollars, for the 4 GB of memory model) and it arrived: star64-top.jpg

(If you want to try RISC-V, there are also several other boards.)

If you want better pictures of this board, there is Linux Lounge's video.

Warning if you plan to do the same: the current status of the Star64, and of software which can run on it, is experimental. Do not expect a fully finished and smooth product. If you don't know about computers, then it is not for you.

You will probably also need some accessories (the board is sold alone, without even a power supply, accessories can be found on the Pine64 store or at your regular dealer, do not forget to check the technical specifications):

  • Power supply,
  • microSD card,
  • Probably also an adapter from serial to USB, for the serial console of the board.

Here is a picture of such adapter (the DSD TECH SH-U099 USB-to-TTL model): star64-serial-cable.jpg

Speaking of the console, the Star64 has a HDMI port but it is not activated by the firmware, you cannot use it as a console. Either you boot blindly, or you connect the serial ports, by soldering or by using a pre-made cable like the one above, for instance converting to USB. As the documentation says (see also the schematics, section "40pin GPIO Bus"), transmission is on pin 8 and reception on pin 10. You therefore connect the RXD on 8 and TXD on 8: star64-serial-plugged.jpg

I then used Minicom to connect from an Ubuntu machine, with this configuration file:

# Connection to the serial port, for managing the Star64 card
pu port             /dev/ttyUSB0
pu baudrate         115200
pu bits             8
pu parity           N
pu stopbits         1
pu minit            
pu mreset           
pu mhangup          
pu rtscts           No      
   

The way I booted my card was the following:

  • Get an image for microSD card (I used the ones by Fishwaldo, where he uses his own tree of the kernel) and uncompress it (after decompression, they are in the - currently quite undocumented - WIC format),
  • Copy it on a microSD card (I used dd on an Ubuntu laptop, dd if=star64-image-weston-star64.wic of=/dev/mmcblk0 bs=1M status=progress, you can ignore "GPT:Primary header thinks Alt. header is not at the end of the disk" / "GPT:Alternate GPT header not at the end of the disk", it will be fixed later),
  • Insert it in the slot under the Star64,
  • Set the switches on the board to boot on the SD card. Warning, they are wrongly labeled; if the board tells you that they have to be Off-On to boot on SD, it is actually the opposite (this is documented on Pine64 Wiki),
  • Power on and be patient, specifically the first time if the operating system has to resize the filesystem partitions. The operating system, made with Yocto using .deb (the format of Debian packages), will request an IP address with DHCP, and you will connect either through your serial console, or with SSH (warning, one of the images does not have a SSH server). Login and password are documented with the images.

Speaking of the microSD slot, it is on the other side of the Star64: star64-bottom.jpg

At this stage, you are now connected to a Unix machine, and you can use regular Unix commands, and Debian package management commands:

% uname -a
Linux grace 5.15.0 #1 SMP Thu Apr 13 06:38:09 UTC 2023 riscv64 riscv64 riscv64 GNU/Linux
  

You can now continue with a regular Unix.

Among the hardware of the board, SD card reader, Ethernet and USB work fine (I was able to mount a USB key). I did not yet test the rest. For instance, there is not yet a package to play sound files so I did not test the audio output.

Now, let's try to compile. I installed the required packages with apt install automake libtool dpkg-dev gcc binutils libgcc-s-dev. We can now write a C program:

% cat plus.c
void main()
{
  int a;
  a = 3;
  a++;
}
  

It compiles and runs. Great. Now, let's see some RISC-V assembly language:

% gcc -O0 -S -o plus.s  plus.c

% cat plus.s
	.file	"plus.c"
	.option pic
	.text
	.align	1
	.globl	main
	.type	main, @function
main:
	addi	sp,sp,-32
	sd	s0,24(sp)
	addi	s0,sp,32
	li	a5,3
	sw	a5,-20(s0)
	lw	a5,-20(s0)
	addiw	a5,a5,1
	sw	a5,-20(s0)
	nop
	ld	s0,24(sp)
	addi	sp,sp,32
	jr	ra
	.size	main, .-main
	.ident	"GCC: (GNU) 11.3.0"
	.section	.note.GNU-stack,"",@progbits
  

And you can now study RISC-V, from the code produced by the compiler.

A few more technical details, now. First, you can see the boot messages of the card, then the boot messages of the kernel. Then, the processor:

% cat /proc/cpuinfo 
processor	: 0
hart		: 1
isa		: rv64imafdc
mmu		: sv39
isa-ext		: 
uarch		: sifive,u74-mc
  

(There are also three other cores.) The partition table of the SD card is:

% fdisk -l /dev/mmcblk1 
Disk /dev/mmcblk1: 29.73 GiB, 31927042048 bytes, 62357504 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B7092089-5983-4D4B-B075-78EABD7A7AFB

Device          Start      End  Sectors   Size Type
/dev/mmcblk1p1   4096     8191     4096     2M HiFive Unleashed BBL
/dev/mmcblk1p2   8192    16383     8192     4M HiFive Unleashed FSBL
/dev/mmcblk1p3  16384   793803   777420 379.6M Microsoft basic data
/dev/mmcblk1p4 794624 62357470 61562847  29.4G Linux filesystem
  

As you can see, /dev/mmcblk1p4 is where the root filesystem resides.

Among the things that I plan to try (one day!):

If you want more information, you can go to:

To get help or simply to discuss with other fans, you can:


L'article seul

Le résolveur DNS sécurisé de FDN

Première rédaction de cet article le 25 avril 2023
Dernière mise à jour le 26 avril 2023


L'association FDN a récemment annoncé que son service de résolveur DNS public était désormais accessible avec les protocoles de sécurité DoT et DoH, ce qui améliore grandement ce service.

Un peu de contexte pour commencer. Le résolveur DNS est un composant tout à fait critique de nos activités sur l'Internet. L'essentiel de ce que l'on fait sur l'Internet impliquera une ou plusieurs requêtes DNS, et ces requêtes sont envoyées à notre résolveur. S'il est en panne, c'est à peu près l'équivalent de pas d'Internet du tout. S'il ment, s'il ne renvoie pas sincèrement ce que les serveurs faisant autorité lui ont dit, on peut être emmené n'importe où. Or, les résolveurs mentent souvent, par exemple à des fins de censure, motivée par la politique ou par les finances.

Pour contourner cette censure, il existe plusieurs méthodes, une des plus simples étant de changer de résolveur DNS. Beaucoup de gens utilisent donc des résolveurs DNS publics, c'est-à-dire accessibles par tous et toutes. Le plus connu est sans doute Google Public DNS. Pour tester, nous allons utiliser la commande dig, d'abord avec un résolveur de Free, qui ment :


% dig @212.27.40.240 sci-hub.se    
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1575
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
sci-hub.se.		3600 IN	A 127.0.0.1

;; Query time: 4 msec
;; SERVER: 212.27.40.240#53(212.27.40.240) (UDP)
;; WHEN: Tue Apr 25 18:43:07 CEST 2023
;; MSG SIZE  rcvd: 55

  

Il prétend que sci-hub.se a comme adresse IP 127.0.0.1, ce qui est faux (c'est l'adresse de la machine locale). Vérifions en demandant à Google :

    
% dig @8.8.8.8 sci-hub.se
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63292
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
sci-hub.se.		60 IN A	186.2.163.219

;; Query time: 156 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Tue Apr 25 18:44:39 CEST 2023
;; MSG SIZE  rcvd: 55

  

Google dit la vérité, Sci-Hub est bien accessible à l'adresse IP 186.2.163.219. On peut aussi vérifier avec les sondes RIPE Atlas :

% blaeu-resolve --requested 100 --country FR --type A sci-hub.se
[186.2.163.219] : 44 occurrences 
[127.0.0.1] : 40 occurrences 
[ERROR: NXDOMAIN] : 6 occurrences 
Test #52634681 done at 2023-04-25T16:33:30Z
  

On voit que la plupart des sondes en France voient la vraie adresse, les autres étant derrière un résolveur menteur, qui donne la fausse adresse 127.0.0.1, ou même prétendent que le nom n'existe pas (NXDOMAIN).

Évidemment, si Google Public DNS ne ment pas, il pose d'autres problèmes, par exemple en matière de vie privée, mais aussi de souveraineté numérique. C'est pour cela qu'il est bon qu'il existe de nombreux autres résolveurs. Ainsi, l'association FDN fournit depuis longtemps un résolveur DNS public non menteur (et j'en profite pour passer à IPv6) :


% dig @2001:910:800::12 sci-hub.se
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59004
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
sci-hub.se.		60 IN A	186.2.163.219

;; Query time: 40 msec
;; SERVER: 2001:910:800::12#53(2001:910:800::12) (UDP)
;; WHEN: Tue Apr 25 18:47:09 CEST 2023
;; MSG SIZE  rcvd: 55

  

Jusqu'à présent, j'ai utilisé le transport par défaut du DNS, UDP (RFC 768). Ce transport a plusieurs défauts très sérieux, qui font qu'il ne devrait jamais être utilisé pour accéder à un résolveur DNS public :

  • Aucune confidentialité, les requêtes circulent en clair (c'est bien sûr pareil quand vous parlez au résolveur de votre FAI ou de l'organisation où vous travaillez, mais la distance est plus courte alors que, en accédant à un résolveur public, vous passez par plusieurs AS dont chacun peut vous espionner).
  • Aucune authentification, vous avez peut-être confiance dans Google ou dans FDN mais vous ne pouvez pas être sûr que c'est bien à eux que vous parlez, puisque UDP ne protège absolument pas contre l'usurpation d'adresse IP et que, de toute façon, quelqu'un a pu détourner le routage, comme cela s'est déjà fait.
  • En outre, du fait de cette absence de protection contre l'usurpation d'adresse IP permet des attaques par réflexion utilisant le résolveur DNS public. Donc, un résolveur DNS public permettant UDP n'est pas seulement dangereux pour ses utilisateurs mais aussi pour tout l'Internet. (C'est entre autres pour cela que mon résolveur public n'offre pas d'UDP du tout.)

La première solution serait d'utiliser TCP qui lui, au moins, protège contre l'usurpation d'adresse IP. Mais il ne résout pas les questions d'authentification et de confidentialité. D'où l'existence de protocoles qui résolvent ces questions, en utilisant la cryptographie : DoT (DNS over TLS, RFC 7858) et DoH (DNS over HTTPS, RFC 8484). Les deux fournissent les mêmes services, la différence principale est que DoH est plus difficile à bloquer, car il utilise un port habituel, le 443 de HTTPS. Avec DoT (ou DoH), les trois problèmes mentionnés plus haut disparaissent. Voyons ce que cela donne pour les résolveurs de FDN, nous allons utiliser cette fois le client DNS kdig, qui fait partie de Knot :


% kdig +tls @2001:910:800::12 sci-hub.se
;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(ECDSA-SECP384R1-SHA384)-(CHACHA20-POLY1305)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 30070
;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR

;; QUESTION SECTION:
;; sci-hub.se.         		IN	A

;; ANSWER SECTION:
sci-hub.se.         	60	IN	A	186.2.163.219

;; Received 55 B
;; Time 2023-04-25 20:04:34 CEST
;; From 2001:910:800::12@853(TCP) in 84.4 ms

  

C'est parfait, tout marche. Comme vous le voyez au début, la session TLS a été authentifiée avec ECDSA et elle est chiffrée avec ChaCha20. Et avec DoH ?


% kdig +https=/dns-query @2001:910:800::12 sci-hub.se
;; TLS session (TLS1.3)-(ECDHE-SECP256R1)-(ECDSA-SECP384R1-SHA384)-(CHACHA20-POLY1305)
;; HTTP session (HTTP/2-POST)-([2001:910:800::12]/dns-query)-(status: 200)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR

;; QUESTION SECTION:
;; sci-hub.se.         		IN	A

;; ANSWER SECTION:
sci-hub.se.         	60	IN	A	186.2.163.219

;; Received 55 B
;; Time 2023-04-25 20:07:21 CEST
;; From 2001:910:800::12@443(TCP) in 105.4 ms

  

On voit qu'une requête HTTPS a été faite à https://[2001:910:800::12]/dns-query et qu'elle a marché.

J'ai un peu triché, car, en fait, kdig n'avait pas authentifié. Puisque DoT et DoH reposent tous les deux sur TLS, utilisons un client TLS pour regarder le certificat, ici celui de GnuTLS :

% gnutls-cli -p 853 2001:910:800::12
...
Connecting to '2001:910:800::12:853'...
- Certificate type: X.509
- Got a certificate list of 3 certificates.
- Certificate[0] info:
 - subject `CN=resolver0.fdn.fr', issuer `CN=R3,O=Let's Encrypt,C=US', serial 0x049a52af0442ad4f67002cf0364cf0aa91b4, EC/ECDSA key 384 bits, signed using RSA-SHA256, activated `2023-04-18 01:00:20 UTC', expires `2023-07-17 01:00:19 UTC', pin-sha256="v8ossDNfX0Qzzo0LfmRdOotuOJJU7lfESpLIetzFseM="
 ...
  

Le certificat a été émis par Let's Encrypt et porte sur le serveur resolver0.fdn.fr (ainsi que, plus loin, ns0.fdn.fr). Dans les deux tests avec kdig, je n'indiquais pas le nom, juste l'adresse IP, et l'authentification avec le certificat n'était pas possible. Dans un cas plus réel, on doit aussi indiquer au client DoT ou DoH le nom qu'on veut vérifier.

Notez également qu'il n'est pas du tout indispensable d'utiliser un résolveur public, vous pouvez avoir votre propre résolveur. Vous maximisez ainsi le contrôle sur la résolution de noms. Mais attention : si avoir votre propre résolveur résout le problème de la censure, il ne protège pas votre vie privée, les requêtes sortant en clair (tout au plus peut-on dire que, pour le FAI, regarder le trafic de son résolveur est plus facile que d'analyser le trafic réseau). Si on veut en plus protéger sa vie privée, une solution intéressante est de combiner les deux méthodes : avoir son propre résolveur et faire suivre (to forward) les requêtes à un résolveur extérieur, par exemple un résolveur public. (Et, au passage, n'oubliez pas de valider localement avec DNSSEC, ce qui vous protégera contre des mensonges si le résolveur à qui vous faites suivre n'est pas si digne de confiance que ça.) Avec Knot-resolver, cela se fait ainsi (notez qu'on indique le nom, pour l'authentification) :

policy.add(policy.all(policy.TLS_FORWARD({{'2001:910:800::12', hostname='ns0.fdn.fr'}})))
  

Et avec Unbound, c'est ainsi :

forward-zone:
 	name: "."
 	forward-addr: 2001:910:800::12@853
        forward-tls-upstream: yes
  

Normalement, Unbound authentifie le serveur DoT distant si on ajoute son nom (forward-addr: 2001:910:800::12@853#ns0.fdn.fr) mais je n'arrive pas à le faire fonctionner (« error: ssl handshake failed crypto error:0A000086:SSL routines::certificate verify failed »).

On peut aussi tester les résolveurs de FDN avec les sondes RIPE Atlas, puisqu'elle savent faire du DoT (mais pas du DoH) :

% blaeu-resolve --tls --nameserver=2001:910:800::40 --requested 100 --country FR --type A sci-hub.se
Nameserver 2001:910:800::40
[186.2.163.219] : 92 occurrences 
Test #52639363 done at 2023-04-25T18:41:38Z
  

C'est parfait, tout a marché.

Outre la solution d'avoir un résolveur local qui fait suivre à un résolveur public comme celui de FDN, vous pouvez aussi utiliser directement celui de FDN sur les terminaux comme expliqué dans la documentation d'ARN. Voici par exemple une copie d'écran sur Android 11 : android-dot-fdn.png

Une fois qu'il a été configuré ainsi, l'ordiphone contacte bien FDN, comme vu ici avec tcpdump :

20:15:28.914148 IP6 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376 > 2001:910:800::16.853: Flags [S], seq 2407640807, win 65535, options [mss 1220,sackOK,TS val 8904059 ecr 0,nop,wscale 9,tfo  cookiereq,nop,nop], length 0
20:15:28.917330 IP6 2001:910:800::16.853 > 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376: Flags [S.], seq 3248346207, ack 2407640808, win 64260, options [mss 1420,sackOK,TS val 4084487123 ecr 8904059,nop,wscale 9], length 0
20:15:28.918686 IP6 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376 > 2001:910:800::16.853: Flags [.], ack 1, win 143, options [nop,nop,TS val 8904059 ecr 4084487123], length 0
20:15:28.919074 IP6 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376 > 2001:910:800::16.853: Flags [P.], seq 1:518, ack 1, win 143, options [nop,nop,TS val 8904059 ecr 4084487123], length 517
20:15:28.921301 IP6 2001:910:800::16.853 > 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376: Flags [.], ack 518, win 126, options [nop,nop,TS val 4084487127 ecr 8904059], length 0
20:15:28.921923 IP6 2001:910:800::16.853 > 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376: Flags [P.], seq 1:230, ack 518, win 126, options [nop,nop,TS val 4084487128 ecr 8904059], length 229
20:15:28.922704 IP6 2a01:e34:dada:e1d0:7f67:9eba:979e:eb57.37376 > 2001:910:800::16.853: Flags [.], ack 230, win 143, options [nop,nop,TS val 8904060 ecr 4084487128], length 0

tcpdump voit qu'il y a une connexion, pourrait découvrir que c'est du TLS, mais évidemment pas savoir quel(s) était(ent) le(s) nom(s) de domaine demandé(s).


L'article seul

Sur les pannes de service-public.fr et impots.gouv.fr (et caf.fr)

Première rédaction de cet article le 16 avril 2023
Dernière mise à jour le 5 mai 2023


Après la grande panne de Météo-France le 12 avril, on a vu les sites Web https://www.service-public.fr/ et https://www.impots.gouv.fr/ être en panne, les 14 et 15 avril. Le 16 avril, c'était le tour de http://caf.fr. Sait-on ce qui s'est passé ?

Je divulgâche tout de suite, il n'y a pas d'informations fiables et précises. Tout au plus puis-je faire part de quelques observations, et ajouter quelques conseils.

Commençons par le 14 avril, la panne de l'excellent, très utile et très bien fait Service-public.fr. Je n'étais pas disponible au moment de la panne, mais j'ai pu effectuer un test avec les sondes RIPE Atlas peu après et il y avait bien un problème DNS :

% blaeu-resolve -r 100 --country FR --type A www.service-public.fr
[ERROR: NXDOMAIN] : 18 occurrences 
[160.92.168.33] : 81 occurrences 
Test #52236542 done at 2023-04-14T10:55:55Z
  

Dix-huit des sondes ont reçu de leur résolveur DNS un NXDOMAIN (No Such Domain ↦ ce nom n'existe pas). Vous pouvez voir les résultats complets en ligne. Ceci n'est évidemment pas normal : tout se passe comme si, pendant un moment, le domaine service-public.fr avait été modifié pour ne plus avoir ce sous-domaine www. Une erreur humaine ? Peu après, le problème avait disparu :

% blaeu-resolve -r 100 --country FR --type A www.service-public.fr
[160.92.168.33] : 100 occurrences 
Test #52237120 done at 2023-04-14T11:32:53Z

Il avait en fait été réparé avant mon premier test mais rappelez-vous que les résolveurs DNS ont une mémoire et certains se souvenaient donc de la non-existence. Bref, sans pouvoir être certain (Service-public.fr ne semble pas avoir communiqué à ce sujet, à part via des tweets stéréotypés ne donnant aucun détail), il semble bien qu'il y ait eu une erreur, vite corrigée.

Et le 15 avril, qu'est-il arrivé au site Web des impôts (c'était le lendemain de son ouverture pour les déclarations de revenus, moment qui se traduit en général par un trafic intense) ? Là encore, on voit un problème DNS, il ne s'agissait pas uniquement d'une surcharge du site Web :

% blaeu-resolve   --type A -r 100 --country FR www.impots.gouv.fr
[152.199.19.61] : 59 occurrences 
[ERROR: SERVFAIL] : 36 occurrences 
Test #52277291 done at 2023-04-15T07:20:04Z
 

Les sondes RIPE Atlas (résultats complets en ligne) nous montrent cette fois qu'un certain nombre de résolveurs DNS ont mémorisé un SERVFAIL(Server Failure ↦ le résolveur n'a pas réussi à résoudre le nom). Les codes d'erreur DNS sont peu nombreux, malheureusement (le RFC 8914 propose une solution, mais encore peu déployée) et SERVFAIL sert à beaucoup de choses. Le plus vraisemblable est qu'il indiquait ici que le résolveur n'avait réussi à joindre aucun des serveurs faisant autorité. impots.gouv.fr n'a que deux serveurs faisant autorité, tous les deux derrière l'AS 3215, ce qui rend ce domaine vulnérable à des problèmes de routage ou à des attaques par déni de service. Voici les serveurs, testés par check-soa :

% check-soa impots.gouv.fr
dns1.impots.gouv.fr.
	145.242.11.22: OK: 2023041301
dns2.impots.gouv.fr.
	145.242.31.9: OK: 2023041301
 

On notera aussi que, même si on pouvait résoudre le nom de domaine, le serveur HTTP avait des problèmes :

   
% curl -v www.impots.gouv.fr.
*   Trying 152.199.19.61:80...
* Connected to www.impots.gouv.fr (152.199.19.61) port 80 (#0)
> GET / HTTP/1.1
> Host: www.impots.gouv.fr
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 504 Gateway Timeout
< Content-Type: text/html
< Date: Sat, 15 Apr 2023 07:18:41 GMT
< Server: ECAcc (paa/6F2E)
< X-EC-Proxy-Error: 14
< Content-Length: 357
< 
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
	<head>
		<title>504 - Gateway Timeout</title>
	</head>
...

 

On peut bien parler au serveur frontal mais il n'arrive pas à joindre le « vrai » serveur derrière, d'où l'erreur 504.

Que s'est-il passé ? À ma connaissance, il n'y a pas eu de communication officielle des impôts à ce sujet mais des sources crédibles évoquent une attaque par déni de service, ce qui est en effet compatible avec ce qui a été observé.

Et les allocations familiales ? Le 16 avril, le domaine caf.fr est en panne :

% check-soa -i caf.fr
ns.caf.fr.
	91.231.174.240: ERROR: read udp 192.168.2.4:45069->91.231.174.240:53: i/o timeout
ns1.caf.fr.
	91.231.174.241: ERROR: read udp 192.168.2.4:48911->91.231.174.241:53: i/o timeout
% date -u
Sun 16 Apr 16:08:59 UTC 2023
  

Les deux serveurs répondent très épisodiquement (ce qu'on voit souvent lors des attaques par déni de service ; quelques requêtes passent). Un test sur les sondes RIPE Atlas montre que c'est de partout :

% blaeu-resolve -r 100 --country FR --type NS caf.fr
[ERROR: SERVFAIL] : 68 occurrences 
[ns.caf.fr. ns1.caf.fr.] : 8 occurrences 
Test #52345500 done at 2023-04-16T15:39:40Z
  

Là encore, le domaine n'a que deux serveurs faisant autorité, tous les deux sous le même préfixe de longueur 24. C'est une configuration faible, qui rend le domaine vulnérable.

Enfin, le 16 avril, mais encore ensuite le 25 avril, puis le 4 mai, l'INSEE a eu un problème similaire, sur son domaine à seulement deux serveurs. Au début, un certain nombre de résolveurs avaient encore l'information en mémoire :

%   blaeu-resolve --requested 100 --country FR --type NS insee.fr
[ERROR: SERVFAIL] : 59 occurrences 
[ns1.insee.fr. ns2.insee.fr.] : 21 occurrences 
Test #52618361 done at 2023-04-25T09:55:20Z
 

Mais au plus fort de la crise :

% blaeu-resolve --requested 100 --country FR --type NS insee.fr
[ERROR: SERVFAIL] : 73 occurrences 
[ns1.insee.fr. ns2.insee.fr.] : 2 occurrences 
Test #52622678 done at 2023-04-25T12:02:12Z
 

Le problème a été réglé vers 1400 UTC. Il avait en effet en cascade, empêchant le fonctionnement des API de la base SIRENE et tous les services publics qui en dépendent. (Un arrêté du 14 juin 2017 impose d'ailleurs un minimum de robustesse à un des services gérés par l'INSEE.) Le fait que ns2 répondait parfois semble indiquer une attaque plutôt qu'une panne, qui aurait été totale. Un exemple d'un service planté par cascade (car il dépendait de l'INSEE) : insee-dns-2023.png

Conclusion ? On ne le rappelera jamais assez, le DNS est une infrastructure critique et qui doit être traitée comme telle. Puisque la très grande majorité des activités sur l'Internet dépend d'un DNS qui marche, un domaine important ne devrait pas se contenter de deux serveurs faisant autorité et connectés au même opérateur. Il est important d'avoir davantage de serveurs faisant autorité, et de les répartir dans plusieurs AS ; on ne met pas tous ses œufs dans le même panier.

Contrairement à ce qu'on lit souvent chez les lecteurs enthousiastes de la publicité des entreprises commerciales, cette robustesse ne nécessite pas forcément de faire appel à des prestataires chers, ni d'acheter des services qui ont peut-être leur utilité pour d'autres usages (comme HTTP) mais qui ne sont pas pertinents pour le DNS. De même qu'on peut faire un disque virtuel fiable à partir de plusieurs disques bon marché (le RAID), on peut faire un service DNS solide à partir de plusieurs hébergeurs même s'ils ne sont pas chers.

À cet égard, il est curieux que des services publics comme Météo-France, Service-public.fr et les impôts ne coopèrent pas davantage ; avoir des serveurs secondaires dans un autre établissement public devrait être la règle. (Je ne suis pas naïf et je me doute bien que la raison pour laquelle ça n'est pas fait n'a rien à voir avec la technique ou avec les opérations et tout à voir avec des problèmes bureaucratiques et des processus kafkaïens.)

Et puis, bien sûr, on souhaiterait voir davantage de communication de la part des organismes publics et donc des retex publics (une entreprise commerciale comme Cloudflare le fait souvent, mais les services publics français sont moins transparents ; Météo-France a communiqué mais avec quasiment aucun détail technique).

Un article du Parisien a été publié sur la panne des impôts.


L'article seul

Météo-France et les nuages sur le DNS

Première rédaction de cet article le 12 avril 2023
Dernière mise à jour le 17 avril 2023


Ce matin, le site Web de Météo-France est en panne. Pourquoi ? Déjà, le nom de domaine meteofrance.com ne fonctionne pas. Il faut dire qu'il est mal configuré.

Voyons d'abord ce que voit l'utilisateurice moyen·ne : meteofrance-web-2023.png

Bref, ça ne marche pas. « Problème technique », comme annoncé sur Twitter : meteofrance-twitter-2023.png

Creusons maintenant. Presque toutes les transactions sur l'Internet commencent par une requête DNS. Sans le DNS, c'est un peu comme de ne pas avoir d'Internet du tout. Testons le domaine meteofrance.com avec dig :

    
% dig A meteofrance.com 

; <<>> DiG 9.16.37-Debian <<>> A meteofrance.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 19940
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;meteofrance.com.	IN A

;; Query time: 5008 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Apr 12 10:18:13 CEST 2023
;; MSG SIZE  rcvd: 33

  

Bon, c'est cassé (SERVFAIL = Server Failure). Que se passe-t-il ? En demandant aux serveurs de .com, on voit que le domaine a deux serveurs de noms (ce qui est insuffisant : la robustesse exige davantage, pour faire face aux pannes) :


% dig @f.gtld-servers.net. NS meteofrance.com
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41215
...
;; AUTHORITY SECTION:
meteofrance.com.	172800 IN NS cadillac.meteo.fr.
meteofrance.com.	172800 IN NS vivaldi.meteo.fr.

  

Interrogeons-les directement :

%   dig @vivaldi.meteo.fr. NS meteofrance.com
dig: couldn't get address for 'vivaldi.meteo.fr.': failure
  

Ah oui, c'est amusant. meteo.fr est également en panne. Pour avoir les adresses IP des serveurs de noms, on ne peut plus compter sur le DNS ? Si, il y a la colle, envoyée par les serveurs de .fr :

    
% dig @d.nic.fr NS meteo.fr
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40768
...
;; AUTHORITY SECTION:
meteo.fr.		3600 IN	NS cadillac.meteo.fr.
meteo.fr.		3600 IN	NS vivaldi.meteo.fr.
...
;; ADDITIONAL SECTION:
cadillac.meteo.fr.	3600 IN	A 137.129.1.4
vivaldi.meteo.fr.	3600 IN	A 137.129.1.2

  

Seulement deux serveurs, on l'a dit, aucune adresse IPv6 (en 2023 !) et, surtout, on voit de la proximité des deux adresses IP que les deux machines sont au même endroit, et donc forment un SPOF. C'est la plus grave erreur dans la configuration de meteofrance.com et meteo.fr.

Bon, interrogeons ces adresses IP :


% dig @137.129.1.4 NS meteofrance.com

; <<>> DiG 9.16.37-Debian <<>> @137.129.1.4 NS meteofrance.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

  

Idem pour l'autre (logique, puisqu'ils sont au même endroit). Les deux serveurs ne répondent pas. Un traceroute montre qu'on n'arrive nulle part :

% sudo tcptraceroute  137.129.1.4  53     
Running:
	traceroute -T -O info -p 53 137.129.1.4 
traceroute to 137.129.1.4 (137.129.1.4), 30 hops max, 60 byte packets
...
 3  vl387-te2-6-paris1-rtr-021.noc.renater.fr (193.51.184.214)  2.581 ms  2.571 ms  2.561 ms
 4  et-2-0-0-ren-nr-paris1-rtr-131.noc.renater.fr (193.51.180.134)  4.719 ms  4.703 ms  4.692 ms
 5  et-2-0-0-ren-nr-paris2-rtr-131.noc.renater.fr (193.55.204.193)  3.112 ms  3.102 ms  3.088 ms
 6  * * *
 7  83.142.144.35 (83.142.144.35)  2.258 ms  2.482 ms  2.425 ms
 8  83.142.144.34 (83.142.144.34)  2.970 ms  2.951 ms  2.992 ms
 9  206.96.106.212.in-addr.arpa.celeste.fr (212.106.96.206)  14.541 ms  13.816 ms  13.855 ms
10  95.96.106.212.in-addr.arpa.celeste.fr (212.106.96.95)  13.102 ms 7.96.106.212.in-addr.arpa.celeste.fr (212.106.96.7)  14.697 ms 95.96.106.212.in-addr.arpa.celeste.fr (212.106.96.95)  13.068 ms
11  149.96.106.212.in-addr.arpa.celeste.fr (212.106.96.149)  15.013 ms  14.821 ms *
12  137.129.20.1 (137.129.20.1)  14.069 ms 35.229.180.159.in-addr.arpa.celeste.fr (159.180.229.35)  15.118 ms 137.129.20.1 (137.129.20.1)  13.726 ms
13  * * *
14  * * *
15  * * *
16  * * *
...
  

Le réseau qui mène aux serveurs DNS faisant autorité semble en panne.

Le problème n'est pas spécifique à mon réseau de départ. Les sondes RIPE Atlas le voient partout :

% blaeu-resolve --requested 100 --type A meteofrance.com
[ERROR: SERVFAIL] : 56 occurrences 
[185.86.168.137 185.86.168.138 185.86.168.139 185.86.168.140] : 10 occurrences 
Test #52152926 done at 2023-04-12T08:01:45Z
  

Le fait que dix des sondes puissent résoudre le nom en adresse IP est probablement dû à la mémorisation par les résolveurs, meteofrance.com étant un nom souvent sollicité.

On peut aussi tester avec l'excellent DNSviz (archivage du test) : meteofrance-dnsviz-2023.png

Notez que le site Web https://meteofrance.com/ est hébergé sur un tout autre réseau et marche bien (si on a la chance d'avoir l'adresse IP dans la mémoire de son résolveur ou bien si on colle l'adresse IP 185.86.168.137 en dur dans sa configuration locale, par exemple le /etc/hosts) pendant ce temps… Ça permet de voir le communiqué officiel envoyé pendant le problème : meteofrance-communique.png

Vers 14 h UTC, après d'autres changements bizarres (ajouter un troisième serveur de noms qui ne marchait pas davantage), Météo-France est passé chez Cloudflare, et tant pis pour la souveraineté numérique :

% check-soa meteofrance.com
cadillac.segui.eu.
	2400:cb00:2049:1::a29f:1a33: OK: 2023041200
	162.159.26.51: OK: 2023041200
vivaldi.segui.eu.
	2400:cb00:2049:1::a29f:1b6c: OK: 2023041200
	162.159.27.108: OK: 2023041200
  

(Ne vous fiez pas aux noms, dans le domaine « familial » segui.eu, les adresses IP sont bien celles des serveurs de Cloudflare.) Le problème disparait donc petit à petit au fur et à mesure de la réjuvénation :

% blaeu-resolve -r 100 - -type NS meteofrance.com
[cadillac.meteo.fr. vivaldi.meteo.fr.] : 19 occurrences 
[cadillac.segui.eu. vivaldi.segui.eu.] : 37 occurrences 
[ERROR: SERVFAIL] : 24 occurrences 
Test #52160057 done at 2023-04-12T14:23:11Z
  

Depuis la première parution de cet article, plusieurs choses sont à noter :


L'article seul

IETF 116 hackathon: unilateral probing of TLS on DNS servers

First publication of this article on 27 March 2023


On 25 and 26 March, it was the IETF 116 hackathon in Yokohama. I worked on TLS probing of authoritative DNS servers.

The goal of the IETF hackathons is to test ideas that may become RFC later. "Running code" is an important part of IETF principles. It is both useful and pleasing to sit down together at big tables and to hack all weekend, testing many ideas and seeing what works and what does not.

A bit of context on this "TLS probing". The DNS is a critical infrastructure of the Internet. It is used for most activities on the Internet. Requests and responses were traditionally sent in the clear, and this is bad for privacy since they can be quite revealing ("this user queried www.aa.org", see RFC 7626). To improve DNS privacy, the IETF developed two sets of solutions: minimizing data (RFC 9156), to protect against the server you query, and encrypting data, to protect against third parties sniffing on the cable. For the second set, encryption, several techniques have been developed, I will focus here on DoT (DNS over TLS, RFC 7858) and DoQ (DNS over QUIC, RFC 9250) but mostly on DoT. These various techniques are standardized for the client-to-resolver link, the most critical for the privacy (see RFC 7626 for details). They are now deployed, although not universally. But this leaves the resolver-to-authoritative link in the clear. The current idea is therefore to use encryption for this link, what we call ADoT (authoritative DNS over TLS). Technically, it is the same DNS over TLS than for the client-to-resolver link. But in practice, there are some issues. A client talks to only one (or may be two) resolvers, which he or she knows. But a resolver talks to thousands of authoritative name servers. Some will have enabled ADoT, some not. How to know?

There were some attempts in the DPRIVE working group to define a signaling mechanism, through which the operators of authoritative name servers could say they support ADoT. But these efforts all fail. A general problem of signalisation of services on the Internet is that the signal can be wrong, and often is (advertising a service which actually des not work). So, the approach on the draft we worked on, draft-ietf-dprive-unilateral-probing, was different: probing the authoritative name server to see if it really does ADoT.

The work was done by Yorgos Thessalonikefs (from NLnet Labs) and myself. Yorgos worked on adding probing support to Unbound and I tested existing ADoT deployment, as well as adding DoT support to the Drink authoritative name server.

First, let's see DoT in action, here with a local installation of Drink and the kdig client (part of Knot):

    
% kdig +tls @localhost -p 8353 foobar.test
;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 16994
;; Flags: qr aa rd; QUERY: 1; ANSWER: 0; AUTHORITY: 1; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1440 B; ext-rcode: NOERROR
;; Option (65023): 067265706F7274076578616D706C6503636F6D00
;; PADDING: 348 B

;; QUESTION SECTION:
;; foobar.test.        		IN	A

;; AUTHORITY SECTION:
foobar.test.        	10	IN	SOA	ns1.test. root.invalid. 2023032512 1800 300 604800 86400
;; Received 468 B
;; Time 2023-03-25 21:43:26 JST
;; From 127.0.0.1@8353(TCP) in 44.7 ms

  

OK, it worked, a TLS connection was established (the TLS cryptographic algorithms used are displayed at the beginning of the response), and we got a DNS reply. Also, the answer was padded (RFC 7830) to 468 bytes (RFC 8467) in order to avoid traffic analysis.

ADoT can also be tested with the check-soa tool. Here, all the authoritative name servers of the domain have ADoT:

% check-soa -dot aaa-cool.fr
ns01.one.com.
	195.206.121.10: OK: 2023032101
	2001:67c:28cc::10: OK: 2023032101
ns02.one.com.
	185.10.11.10: OK: 2023032101
	2001:67c:28cc:1::10: OK: 2023032101
  

And here only one has:

% check-soa -dot bortzmeyer.fr
ns2.bortzmeyer.org.
	2400:8902::f03c:91ff:fe69:60d3: ERROR: dial tcp [2400:8902::f03c:91ff:fe69:60d3]:853: connect: connection refused
	172.104.125.43: ERROR: dial tcp 172.104.125.43:853: connect: connection refused
ns4.bortzmeyer.org.
	2001:4b98:dc0:41:216:3eff:fe27:3d3f: ERROR: dial tcp [2001:4b98:dc0:41:216:3eff:fe27:3d3f]:853: i/o timeout
	92.243.4.211: ERROR: dial tcp 92.243.4.211:853: i/o timeout
puck.nether.net.
	2001:418:3f4::5: OK: 2023032600
	204.42.254.5: OK: 2023032600
  

ADoT can also be tested with the RIPE Atlas probes, here with the Blaeu tool against a root name server, B.root-servers.net:

% blaeu-resolve --requested 100 --nameserver 199.9.14.201 --type SOA --tls --nsid .
Nameserver 199.9.14.201
[TIMEOUT] : 2 occurrences 
[NSID: b4-ams; a.root-servers.net. nstld.verisign-grs.com. 2023032501 1800 900 604800 86400] : 54 occurrences 
[NSID: b4-lax; a.root-servers.net. nstld.verisign-grs.com. 2023032501 1800 900 604800 86400] : 12 occurrences 
[NSID: b4-iad; a.root-servers.net. nstld.verisign-grs.com. 2023032501 1800 900 604800 86400] : 15 occurrences 
[NSID: b4-mia; a.root-servers.net. nstld.verisign-grs.com. 2023032501 1800 900 604800 86400] : 3 occurrences 
[a.root-servers.net. nstld.verisign-grs.com. 2023032501 1800 900 604800 86400] : 1 occurrences 
[NSID: b4-sin; a.root-servers.net. nstld.verisign-grs.com. 2023032501 1800 900 604800 86400] : 1 occurrences 
Test #51316045 done at 2023-03-26T02:05:11Z
  

This is quite good, only two probes fail to connect over DoT, may be because they were on a network which blocks port 853 outgoing.

OK, so, some authoritative name servers have ADoT and some have not. Now, what should the resolver do? Since there is no signaling, should it try port 853? How to do it without waiting forever if the server does not reply at all? The idea behind the draft draft-ietf-dprive-unilateral-probing is indeed to always try ADoT and use it if it works but in an "intelligent" way. Instead of waiting for ADoT to succeed or fail, the resolver should do it on the "happy eyeballs" way (RFC 8305), trying both DoT and traditional DNS a the same time. Note that it is an unilateral choice: the resolver does all of the work and requires nothing from the authoritative server.

One resolver today does probing, although not in the way of the draft: PowerDNS Recursor. Let's try it (their DoT support is dscribed online). We get the git, we follow the good compilation instructions, we autoreconf, then ./configure, then make. We then can run it with the option --max-busy-dot-probes=100 (by default, it does not do probing). Note that probing in PowerDNS is lazy: it is not always tried, only of there is a "sufficient" traffic with the authoritative name server. You can see probing going on with tcpdump on port 853 and PowerDNS can report the results:

% rec_control dump-dot-probe-map /tmp/foo && fgrep Good /tmp/foo 
dump-dot-probe-map: dumped 13962 records
45.54.76.1	qtmlabs.xyz.	14	Good	2023-03-29T04:27:32
157.53.224.1	qtmlabs.xyz.	39	Good	2023-03-29T04:28:37
77.55.125.10	abstractionleak.com.	1	Good	2023-03-29T04:25:39
77.55.126.10	abc-sport.fr.	3	Good	2023-03-29T04:25:39
185.10.11.11	one.com.	4	Good	2023-03-29T04:28:02
195.206.121.11	one.com.	4	Good	2023-03-29T04:28:03
51.77.156.11	BILLAUD.EU.ORG.	1	Good	2023-03-29T00:09:32
129.134.30.12	facebook.com.	5	Good	2023-03-29T04:29:26
129.134.31.12	facebook.com.	6	Good	2023-03-29T04:27:39
185.89.218.12	facebook.com.	14	Good	2023-03-29T04:27:39
185.89.219.12	facebook.com.	5	Good	2023-03-29T04:27:39
139.99.155.59	EU.ORG.	1	Good	2023-03-29T04:27:32
185.49.140.60	nlnetlabs.nl.	3	Good	2023-03-29T04:26:37
172.105.50.79	geekyboo.net.	1	Good	2023-03-29T04:22:37
23.234.235.93	obo.sh.	1	Good	2023-03-29T03:34:12
212.102.32.200	cdn77.org.	1	Good	2023-03-29T03:47:44
199.9.14.201	.	17	Good	2023-03-29T04:30:39
136.243.57.208	distos.org.	1	Good	2023-03-29T03:44:00
  

We see here that all these nameservers have a working ADoT. In order to probe many domains, I have fed the resolver with data from the .fr zone, Cloudflare Domain Rankings and a list of fediverse instances. A partial list of domains which currently have working ADoT for at least one name server is:

.               # Yes, the root
facebook.com
nlnetlabs.nl
powerdns.com
eu.org
billaud.eu.org
dyn.sources.org  # Drink name server
bortzmeyer.fr
nether.net
one.com # and the zones is hosts such as aaa-cool.fr
desec.io # and the zones it hosts such as qtmlabs.xyz
nazwa.pl # and the zones it hosts such as abc-sport.fr
psyopwar.com # and the zones it hosts such as obo.sh
cdn77.org
distos.org
  

As you can see, even the root has a working ADoT server (see the announcement), despite a prudent statement of the root operators some time ago.

What about the work on Unbound? Unfortunately, it was more complicated than it seemed, since "happy eyeballs" probing (sending the request twice) runs against some assumptions in Unbound code. But the work by Yorgos made possible to better understand the issues, which is an important point for the hackathon.

The work of this weekend raised several questions, to be carried to the working group:

  • If the ADoT server replies but the reply indicates an error, such as SERVFAIL or REFUSED, should the resolver retry without DoT? PowerDNS Recursor does it, but it seems it would make more sense to accept the reply, and just to remind system administrators that port 853 and 53 should deliver consistent answers.
  • What should be the criteria to select an authoritative name server to query? Should we prefer a fast insecure server or a slow encrypted one? The draft does not mention it, because it is local policy. (PowerDNS Recursor has apparently no way to change its default policy, which is to use the fastest one, DoT or not.)
  • Should we do lazy probing, like PowerDNS Recursor does, or use the more eager "happy eyeballs" algorithm?

For the issue of consistency between port 53 and 853, this can go at odds with current practices. For instance, the only authoritative name server of dyn.bortzmeyer.fr hosts two different services, Drink for the autoritative service on port 53 and an open resolver, dnsdist, on port 853. So, the answers are different. Should we ban this practice?

% check-soa -dot dyn.bortzmeyer.fr
ns1-dyn.bortzmeyer.fr.
	2001:41d0:302:2200::180: ERROR: REFUSED
	193.70.85.11: ERROR: REFUSED

% check-soa -tcp dyn.bortzmeyer.fr
ns1-dyn.bortzmeyer.fr.
	2001:41d0:302:2200::180: OK: 2023032702
	193.70.85.11: OK: 2023032702
  

(The REFUSED is because check-soa does not send the RD - recursion desired - bit.)

All the presentations done at the end of the hackathon are online, including our presentation.


L'article seul

Fiche de lecture : Catalogue des vaisseaux imaginaires

Auteur(s) du livre : Stéphane Mahieu
Éditeur : Éditions du Sandre
9-782358-211505
Publié en 2022
Première rédaction de cet article le 21 mars 2023


Un livre qui donne envie de voyager et de lire : l'auteur a dressé un catalogue de bateaux qui apparaissent dans des œuvres de fiction. Chaque entrée résume le bateau, sa carrière, son rôle dans le roman, et est l'occasion de passer d'œuvres archi-connues à des textes bien moins célèbres.

On y trouve le Titan, du roman « Le naufrage du Titan » (avec des notes mettant en avant, non pas les ressemblances avec le Titanic, comme souvent, mais les différences), le Fantôme du « Loup des mers » (un roman politique bien plus qu'un livre d'aventures maritimes), et bien sûr le Nautilus. Mais l'auteur présente aussi des vaisseaux issus de romans plus obscurs (en tout cas en France), comme l'Étoile polaire (dans le roman d'Obroutchev), le Leviatán, issu de l'imagination de Coloane ou le Rose-de-Mahé, créé par Masson.

À noter que la bande dessinée n'est pas représentée (ni le cinéma, d'ailleurs). L'entrée pour la Licorne ne décrit pas le vaisseau du chevalier de Hadoque mais elle parle d'un recueil d'histoires anciennes (le livre est sur le projet Gutenberg).

Bref, plein d'idées de lectures vont vous venir en parcourant ce livre… Mettez votre ciré, vérifiez les provisions de bord (et les armes !) et embarquez.


L'article seul

Fiche de lecture : Plutôt nourrir

Auteur(s) du livre : Clément Osé, Noémie Calais
Éditeur : Tana
979-10-301-0424-0
Publié en 2022
Première rédaction de cet article le 20 mars 2023


Le débat sur la consommation de viande est souvent binaire, entre d'un côté les partisans de l'agriculture industrielle et de l'autre des animalolâtres qui refusent toute utilisation des animaux. Ce livre raconte le point de vue d'une éleveuse de porcs, qui essaie de faire de l'élevage de viande en échappant aux logiques industrielles.

Les partisans de l'agriculture industrielle reprochent souvent à leux opposants animalistes de ne rien connaitre à l'agriculture et au monde paysan. Ce n'est pas faux, mais, justement, ce livre est écrit, à deux mains, par des personnes qui vivent à la campagne, et qui travaillent la terre. Noémie Calais, l'éleveuse, a quitté son travail de consultante internationale pour s'occuper de porcs dans le Gers. Le travail quotidien est difficile (être paysanne n'a rien de romantique), et plein de questions se bousculent : a-t-on le droit d'élever des animaux pour finalement les tuer, comment faire une agriculture bio (ou à peu près) sans faire venir des kiwis, certes bios, mais transportés par avion depuis l'autre bout du monde, comment essayer de faire les choses proprement dans un environnement légal et économique où tout pousse à la concentration et à l'agriculture industrielle, avec toutes ses horreurs (pour les humains, comme pour les animaux). Les auteurs n'esquivent aucune question. Oui, il est légitime de manger les animaux, non, cela ne veut pas dire qu'il faut faire n'importe quoi.

Le livre va du quotidien d'une paysanne aux questions plus directement politiques, comme la réglementation délirante qui, sous couvert de protéger les consommateurs, crée tellement de normes et de certifications abstraites et déconnectées du terrain que seuls les gros, donc en pratique l'agriculture industrielle, ont des chances d'arriver à les respecter. Les arguments sanitaires, par exemple, peuvent être un prétexte pour démolir les circuits locaux. (Le cas n'est pas dans ce livre mais, par exemple, les règles de respect de la chaine du froid pour les fromages, qui sont les mêmes pour le fromage industriel sous plastique qui vient de l'autre bout du pays, et pour les dix ou vingt fromages de chèvre produits à deux kilomètres du marché sont un exemple typique.)

À lire avant d'aller au supermarché faire ses achats !


L'article seul

Articles des différentes années : 2023  2022  2021  2020  2019  2018  2017  Précédentes années

Syndication : Flux Atom avec seulement les résumés et Flux Atom avec tout le contenu.

Un article de ce blog au hasard.