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.
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 :
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 :
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
n'est pas touché :
https://t.me/
% 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 :
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:
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):
Here is a picture of such adapter (the DSD TECH SH-U099 USB-to-TTL model):
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:
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:
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),.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:
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!):
/dev/mmcblk0p4
). May be populate it
with a "real" Debian? There is documentation
but apparently outdated. There are also instructions
for another RISC-V processor, which might be useful. There
is no official port of
Debian on RISC-V, and the Wiki seems quite
abandoned but the work goes
on.If you want more information, you can go to:
To get help or simply to discuss with other fans, you can:
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 :
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 :
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).
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
et
https://www.service-public.fr/
être
en panne, les 14 et 15 avril. Le 16 avril, c'était le tour de https://www.impots.gouv.fr/
. Sait-on ce qui s'est passé ?http://caf.fr
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) :
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.
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 :
Bref, ça ne marche pas. « Problème technique », comme annoncé
sur Twitter :
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) :
Notez que le site Web
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
https://meteofrance.com/
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 :
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 :
segui.eu
à
meteo.fr
.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:
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.
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.
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 !
Première rédaction de cet article le 17 mars 2023
Si vous avez déjà créé/géré une machine virtuelle chez OVH, vous avez sans doute noté la bizarrerie de la configuration IPv6. En fait, la configuration automatiquement installée lorsque vous créez votre machine est incorrecte. Voici pourquoi, et comment la réparer.
Créons d'abord un serveur (j'ai utilisé l'API OpenStack mais le problème existait déjà avant).
% ip -6 addr show ... 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000 inet6 2001:41d0:801:1000::233c/56 scope global valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe10:748f/64 scope link valid_lft forever preferred_lft forever
La machine a une adresse IPv6,
2001:41d0:801:1000::233c
, dans un préfixe de
longueur 56. Chic, je me dis, je vais pouvoir parler directement
(sans passer par le routeur) avec les autres
machines dans ce même préfixe.
La table de routage va d'ailleurs en ce sens :
% ip -6 route show ... 2001:41d0:801:1000::/56 dev ens3 proto kernel metric 256 pref medium default via 2001:41d0:801:1000::1 dev ens3 metric 1 pref medium
Elle nous dit que tout le /56 est joignable sans intermédiaire (pas
de via).
Essayons depuis la
2001:41d0:801:1000::23b2
:
% ping -c 3 2001:41d0:801:1000::233c PING 2001:41d0:801:1000::233c(2011:41d0:801:1000::233c) 56 data bytes From 2001:41d0:801:1000::23b2 icmp_seq=1 Destination unreachable: Address unreachable ... --- 2001:41d0:801:1000::233c ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2030ms
Aïe, c'est raté, alors que les deux machines sont bien dans le même préfixe de longueur 56. Pourquoi ? Parce que les machines ne sont pas réellement sur un réseau local dont le préfixe ferait 56 bits. Elles doivent en fait toujours passer par le routeur, comme si elles étaient sur une liaison point-à-point avec ce routeur. (Pour la même raison, un tcpdump ne montrera pas de trafic, à part avec le routeur, par exemple du trafic NTP.)
Pour que cela marche, il faut renoncer à parler directement avec
les machines proches, et corriger la configuration. Ce sont des
Debian, on va éditer le fichier
/etc/network/interfaces.d/50-cloud-init
et
remplacer la longueur incorrecte (56) par la bonne (128). Et on
n'oublie pas de rajouter une route vers le routeur avant de définir
la route par défaut. On
redémarre et ça marche :
% ping -c 3 2001:41d0:801:1000::233c PING 2001:41d0:801:1000::233c(2001:41d0:801:1000::233c) 56 data bytes 64 bytes from 2001:41d0:801:1000::233c: icmp_seq=1 ttl=57 time=0.810 ms 64 bytes from 2001:41d0:801:1000::233c: icmp_seq=2 ttl=57 time=0.746 ms 64 bytes from 2001:41d0:801:1000::233c: icmp_seq=3 ttl=57 time=0.764 ms --- 2001:41d0:801:1000::233c ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2037ms rtt min/avg/max/mdev = 0.746/0.773/0.810/0.026 ms
Et la table de routage nous montre que tout va passer par le routeur :
% ip -6 route show ... 2001:41d0:801:1000::1 dev ens3 metric 1 onlink pref medium 2001:41d0:801:1000::233c dev ens3 proto kernel metric 256 pref medium default via 2001:41d0:801:1000::1 dev ens3 metric 1 pref medium
Il est dommage qu'on ne puisse pas parler directement aux autres machines du même préfixe. Peut-être est-ce pour des raisons de sécurité, ces machines pouvant appartenir à des organisations différentes ? C'est en effet la même chose en IPv4 mais, cette fois, avec une configuration par défaut qui est correcte (un préfixe de longueur 32).
Si vous créez beaucoup de machines virtuelles et qu'on vous n'avez pas envie de tout corriger à la main, et que, comme moi, vous utilisez Ansible, voici un playbook qui fait les choses plus ou moins proprement :
--- - hosts: coursipv6 become: yes become_method: sudo tasks: - name: Broken IPv6 config at OVH lineinfile: path: /etc/network/interfaces.d/50-cloud-init regexp: 'address {{ ipv6_address }}/56$' line: 'address {{ ipv6_address }}/128' backrefs: yes - name: Broken IPv6 routing at OVH lineinfile: path: /etc/network/interfaces.d/50-cloud-init regexp: 'route add -A inet6 default gw {{ ipv6_gateway }} || true$' line: '\tpost-up ip -6 route add {{ ipv6_gateway }} dev ens3 && route add -A inet6 default gw {{ ipv6_gateway }} || true' backrefs: yes
Auteur(s) du livre : Audric Gueidan, Halfbob
Éditeur : Dunod
978-2-10-083732-1
Publié en 2023
Première rédaction de cet article le 15 mars 2023
La plupart des lecteurices de ce blog savent que, sur l'Internet, on laisse des traces partout et que nos données personnelles sont peu protégées. (Le discours policier « l'Internet, c'est l'anonymat » est de la pure propagande.) Mais bien que ce fait soit largement connu et documenté, même au-delà des lecteurices de ce blog, on ne constate pas de changement de comportement des utilisateurices. Ceux et celles-ci continuent à distribuer trop largement leurs données personnelles. Il y a de nombreuses raisons à cet état de fait et je ne vais pas toutes les discuter. Mais une des raisons, pensent les auteurs de ce livre, est le manque d'information ; les utilisateurices ont bien entendu dire qu'il y avait des problèmes avec les données personnelles mais ielles ne mesurent pas complètement l'ampleur de ces problèmes, ni les formes qu'ils prennent. Comment leur expliquer ? Les auteurs tentent une BD, « Datamania ».
Alors, une BD, c'est du texte et du dessin. Personnellement, je ne suis pas très enthousiaste pour ce style de dessin (vous pouvez voir certains de ces dessins dans l'article de GeekJunior) mais comme les goûts artistiques varient, je n'argumenterai pas sur ce point. Le texte est léger et amusant, et couvre bien les sujets. Aucune erreur technique, les auteurs font preuve de beaucoup de rigueur. L'idée est d'expliquer à des gens qui n'ont pas envie de lire tous les rapports de la CNIL. Est-ce réussi ? Bon, il est clair que je ne suis pas le cœur de cible, le livre vise des gens pas très informés. Mais, justement, je trouve que le livre n'explique pas assez et qu'il abuse des private jokes. Certaines de ces allusions sont expliquées dans l'annexe « Avez-vous remarqué ? » mais j'avoue que je me suis demandé si un·e lecteurice ordinaire ne va pas rester perplexe. (Les lecteurices qui connaissent le sujet peuvent s'amuser, sans lire cette annexe, à repérer toutes les allusions à des personnes ou organisations connues.)
Le sujet, il est vrai, est très riche et très complexe. Le livre parle de surveillance, de logiciel libre, de cookies, de chiffrement et de beaucoup d'autres choses, et ne peut évidemment pas tout traiter en détail. (Un gros plus pour avoir cité Exodus Privacy.) Je conseillerai de l'utiliser comme introduction, ou comme support à des ateliers mais je ne suis pas sûr qu'il puisse être utilisé en autonomie par des utilisateurices ordinaires. (Bon, après, c'est vrai que je suis exigeant ; qu'en pensent d'autres personnes ? Voyez l'article de GeekJunior ou celui de Médias-Cité.)
Note : j'ai reçu un exemplaire gratuit du livre de la part des auteurs.
First publication of this article on 13 February 2023
The great technical conference FOSDEM resumed physical activity after two years of purely online events. I had the pleasure to make a small talk at the DNS devroom about the Drink dynamic authoritative DNS server.
The slides are available on the official site. The recorded video is available at the same place, as well as links to the source code, etc.
Première rédaction de cet article le 23 janvier 2023
Le 20 janvier de cette année, à la conférence informatique Touraine Tech, j'ai fait un exposé sur la neutralité du code. Lorsque le ou la développeureuse dit « je ne fais pas de politique, ce programme pourra être utilisé pour différents buts », est-ce possible ?
Voici les supports de l'exposé et leur source (en LaTeX avec Beamer).
Il y avait à cet évènement de nombreuses autres conférences intéressantes(sans compter les fouées aux rillettes) :
Les vidéos de ces différentes conférences sont en ligne (la mienne aussi).
Un exposé d'Olivier Mertens portait sur le générateur d'images
DALL-E (fait par la même société que ChatGPT). J'ai donc demandé à DALL-E « Une
conférence à TouraineTech dans le style de François
Boucher [puisqu'il y avait une exposition de ce dernier
au Musée des Beaux-Arts] » et le résultat
est… pas terrible : .
Et merci mille fois aux organisateurices (une telle conférence crée beaucoup de travail), et à Florian Roulet pour m'avoir invité à y prendre la parole.
Ploum et moi dédicaçant nos livres :
Première rédaction de cet article le 3 janvier 2023
Si Ada Lovelace était la première programmeuse, les programmeuses et programmeurs actuel·les sont-ielles les dernièr·es ? Un programme « intelligent » comme ChatGPT va-t-il les condamner à la reconversion ou au chômage ? Je continue ici mon exploration de ChatGPT.
ChatGPT a beaucoup été utilisé pour la programmation. Voici une session où je lui demande des programmes (ce sera la seule image, dans le reste de l'article, je copierai le texte).
Exemple d'utilisation :
Le programme est écrit en Elixir car mes questions précédentes portaient sur ce langage et ChatGPT mémorise les conversations (et il s'en sert, est-on averti, pour s'améliorer donc ne lui donnez pas d'informations confidentielles). L'utilisation d'Elixir montre que ChatGPT connait beaucoup de choses, y compris des langages assez rarement utilisés. C'est logique : pour le quantitatif (la mémorisation et la restitution d'énormes quantités d'informations), les ordinateurs sont certainement meilleurs que les humains. D'autre part, celles et ceux qui ont lu mon précédent article noteront que j'ai maintenant un compte ChatGPT, ayant trouvé un numéro de téléphone sacrifiable.
Beaucoup de gens ont été impressionnés par les qualités de ChatGPT et, voyant la facilité avec laquelle il génère des programmes (et les explique !), se sont dit que les programmeuses et les programmeurs allaient disparaitre. Un tel discours fait rêver bien des patrons, qui apprécieraient de remplacer des développeurs et développeuses payés chers par une IA docile et obéissante. Ce discours est donc très ancien dans l'informatique, Cobol avait déjà été promu avec cet argument. Et c'était également le cas de Fortran (« FORTRAN should virtually eliminate coding and debugging »). Même si ces affirmations semblent techniquement ridicules aujourd'hui, à l'époque, le progrès par rapport au langage d'assemblage était tel que cela ne semblait pas absurde. Puis on a entendu à nouveau ce raisonnement du temps des L4G puis récemment du nocode. Le fait que les espérances des patrons aient été déçues à chaque fois ne les empêche pas de garder espoir.
Voyons donc ce que sait faire ChatGPT. D'abord, on l'a dit, il
connait beaucoup de choses. Je demande « Je dois trier une liste de
chaînes de caractères [un exercice banal de débutant]. Comment
faire ? » et ChatGPT répond « Pour trier une liste de
chaînes de caractères en Elixir, vous pouvez utiliser la fonction
Enum.sort/1
. Cette fonction prend en entrée une
liste et renvoie une liste triée de ses éléments. Voici un exemple
de code qui trie une liste de chaînes de caractères en ordre
croissant : »
strings = ["c", "b", "a", "d"] sorted_strings = Enum.sort(strings) IO.inspect(sorted_strings) # ["a", "b", "c", "d"]
Il connait la bibliothèque standard d'Elixir
(où il y a bien un Enum.sort
)
et aussi des idiosyncrasies d'Elixir comme le
fait de nommer une fonction en terminant par son
arité. Et il ajoute spontanément « Si vous
voulez trier la liste en ordre décroissant, vous pouvez utiliser la
fonction Enum.sort/2 et lui fournir une fonction de comparaison qui
renvoie :gt si le premier argument est plus grand que le second, :lt
si le premier argument est plus petit que le second, et :eq s'ils
sont égaux. Voici un exemple de code qui trie une liste de chaînes
de caractères en ordre décroissant : »
strings = ["c", "b", "a", "d"] sorted_strings = Enum.sort(strings, fn x, y -> if x > y do :gt else if x < y do :lt else :eq end end) IO.inspect(sorted_strings) # ["d", "c", "b", "a"]
(Les :gt
et :lt
sont
appelés atomes et sont une des particularités d'Elixir. Je vous ai
dit qu'il « connaissait » bien le langage.)
Mais ce second code pose déjà des problèmes. D'abord, il ne
compile même pas (il manque un end
). Mais,
surtout, ChatGPT n'a pas bien lu la
documentation : la fonction passée en argument à
sort
est censée renvoyer un booléen, pas ces
atomes. On voit là une première chose à garder en mémoire : on
ne peut pas en général utiliser les programmes produits par ChatGPT
tels quels, il faut les vérifier, et cette vérification doit
être faite par une personne compétente en programmation. Et il n'est
pas évident que l'entièreté du processus soit plus rapide et plus
sûr que si cette personne compétente avait tout fait
elle-même. (L'erreur de syntaxe est la moins grave, car elle est
détectée à la compilation. Le pire serait une erreur qui ne
planterait pas mais donnerait un résultat faux.)
Ceci dit, ChatGPT apprend et il est interactif. Voyons cela sur un autre exemple : « Comment décomposer un entier de grande taille en ses facteurs premiers ? ». ChatGPT répond « Pour décomposer un entier en ses facteurs premiers en Elixir, vous pouvez utiliser une approche récursive. Voici comment vous pouvez implémenter cette approche : »
defmodule PrimeFactors do def factors(n, divisor \\ 2) when divisor > n do [n] end def factors(n, divisor \\ 2) do if rem(n, divisor) == 0 do [divisor | factors(n / divisor, divisor)] else factors(n, divisor + 1) end end end
Cette fois, il n'y a pas d'erreur de syntaxe, mais cela ne compile quand même pas, en raison d'une erreur sémantique. Et il y a deux autres bogues (trouver l'une d'elles nécessite de connaitre Elixir). Mais comme ChatGPT est interactif, je lui explique : « Attention, on ne peut pas avoir deux définitions avec des valeurs par défaut. Il faut réécrire ton code. » Il me répond que j'ai raison (d'autres personnes ont vu ChatGPT nier des problèmes) et « Vous avez raison, il n'est pas possible d'avoir deux définitions avec des valeurs par défaut pour le même nom de fonction en Elixir. Pour résoudre ce problème, vous pouvez utiliser une seule définition de fonction avec une valeur par défaut pour le diviseur, et ajouter une condition pour gérer le cas où le diviseur est supérieur à n. Voici comment vous pouvez réécrire le code : »
defmodule PrimeFactors do def factors(n, divisor \\ 2) when divisor > n do [n] end def factors(n, divisor \\ 2) do if divisor > n do [n] else if rem(n, divisor) == 0 do [divisor | factors(n / divisor, divisor)] else factors(n, divisor + 1) end end end end
Et il ajoute spontanément « Je vous recommande également de changer
le nom de la fonction factors/2
en
factors/1
et de changer la condition de la
clause de cas factors/1
pour qu'elle vérifie si
n est inférieur ou égal à 1. Voici comment le code final devrait
ressembler [sic] : »
defmodule PrimeFactors do def factors(n, divisor \\ 2) when n <= 1 do [] end def factors(n, divisor \\ 2) do if rem(n, divisor) == 0 do [divisor | factors(n / divisor, divisor)] else factors(n, divisor + 1) end end end
C'est amusant, le code réécrit a toujours la même bogue sur la
définition de fonctions avec des valeurs par défaut. Par contre,
ChatGPT a « réfléchi » et a corrigé une des autres bogues (qui
faisait que le nombre 1 était listé comme facteur premier). Bon,
tant pis, je corrige manuellement et je lui signale la troisième
bogue (celle qui nécessite de connaitre Elixir) : « Et attention, le
/ fait une division de réels, il faudrait utiliser
div
. ». Il le reconnait : « Vous avez raison,
la fonction / en Elixir effectue une division de réels et non une
division entière. Pour effectuer une division entière, vous pouvez
utiliser la fonction div/2
. Voici comment vous
pouvez utiliser la fonction div/2
dans la
fonction factors/1
: »
defmodule PrimeFactors do def factors(n, divisor \\ 2) when n <= 1 do [] end def factors(n, divisor \\ 2) do if rem(n, divisor) == 0 do [divisor | factors(div(n, divisor), divisor)] else factors(n, divisor + 1) end end end
À noter que ChatGPT avait montré qu'il connaissait l'éco-système Elixir, en expliquant comment tester avec l'interpréteur iex :
iex> PrimeFactors.factors(12) [2, 2, 3] iex> PrimeFactors.factors(2310) [2, 3, 5, 7, 11] iex> PrimeFactors.factors(7829) [7829]
Prenons un autre exemple qui illustre la question du cahier des charges. En programmation dans le monde réel, c'est souvent la principale difficulté ; le·a programmeur·se passe souvent davantage de temps à comprendre un cahier des charges incomplet, contradictoire et irréaliste qu'à programmer. Commençons simplement : « Écris un programme en Python qui donne la liste des nombres allant jusqu'à N. ». ChatGPT répond :
# Demande à l'utilisateur de saisir un entier N n = int(input("Entrez un entier N : ")) # Initialise une liste vide l = [] # Pour chaque entier i allant de 1 à N for i in range(1, n+1): # Ajoute i à la liste l.append(i) # Affiche la liste print(l)
Et explique « Ce programme demande à l'utilisateur de saisir un entier N, initialise une liste vide, puis utilise une boucle for pour ajouter chaque entier allant de 1 à N à la liste. Enfin, il affiche la liste. ». Modifions le cahier des charges (ce qui est courant) : « Il faut que cela marche avec des entiers relatifs. » ChatGPT ne se démonte pas pour si peu « Pas de problème, voici une version modifiée du programme qui prend en compte les entiers relatifs : »
# Demande à l'utilisateur de saisir un entier N n = int(input("Entrez un entier N : ")) # Initialise une liste vide l = [] # Si N est positif if n > 0: # Pour chaque entier i allant de 1 à N for i in range(1, n+1): # Ajoute i à la liste l.append(i) # Si N est négatif elif n < 0: # Pour chaque entier i allant de N à -1 (inclus) for i in range(n, 0): # Ajoute i à la liste l.append(i) # Si N est égal à 0 else: # Ajoute 0 à la liste l.append(0) # Affiche la liste print(l)
Et explique « Cette version vérifie si N est positif, négatif ou égal à 0 et utilise une boucle for appropriée pour ajouter les entiers à la liste. Si N est égal à 0, 0 est simplement ajouté à la liste. » On voit que ChatGPT est parfaitement capable de faire des exercices de programmation pour grands débutants, par exemple au lycée. Mais comme je suis méchant, je lui demande ensuite un programme qui marche avec les nombres réels, ce qui est impossible. Il me fait alors une variante qui énumère, mais avec un pas (qu'il a choisi arbitrairement) de 0,1. Dois-je le considérer comme très bête ou comme très intelligent d'avoir interprété de manière créative un cahier des charges absurde ? En tout cas, cet exemple montre à quoi ressemble souvent le travail de programmation : il faut de nombreuses itérations avant d'avoir une idée claire de ce qui est demandé et un programme comme ChatGPT n'est pas forcément le mieux placé pour cela. (Mes lecteurices qui connaissent la programmation auront déjà fait remarquer in petto que si on ne peut pas énumérer les réels - qui sont en nombre infini dans tout intervalle, quelle que soit sa taille, on pourrait par contre énumérer les nombres en virgule flottante représentables sur la machine. Mais ChatGPT n'y a pas pensé.)
Mais, bref, on est encore loin d'un système qui pourrait permettre de se passer complètement des développeurs et développeuses. Il peut aider, c'est certain, faisant gagner du temps lorsqu'on a oublié comment faire une requête HTTP dans tel ou tel langage de programmation, il peut servir d'« auto-complétion améliorée » mais cela ne permet pas de lui confier tout le travail. Alors, certes, il s'agit d'Elixir, mais est-ce que cela marcherait mieux avec des langages de programmation plus répandus ? J'en doute. Mémoriser une grande quantité d'informations et pouvoir en ressortir à volonté est justement le point fort des ordinateurs. Contrairement à un humain, apprendre un langage de plus ne nécessite guère d'effort. Les différents messages lus sur les réseaux sociaux semblent indiquer que des langages bien plus communs qu'Elixir ont le même problème (pareil pour la simple algèbre).
Parmi les autres faiblesses de ChatGPT qui font obstacle à une utilisation en totale autonomie, notons aussi :
En conclusion, oui, ChatGPT et les logiciels similaires vont changer la programmation (comme Cobol et Fortran l'avaient fait) mais croire qu'ils vont permettre de se passer de programmeur-ses est illusoire. Les développeur·euses qui produisent du code de basse qualité à la chaîne ont du souci à se faire pour leur avenir professionnel mais cela ne concerne pas celles et ceux qui font du code créatif, difficile, novateur, ou simplement bien adapté à leur problème. ChatGPT est très fort pour des tests simplistes, comme ceux souvent faits à l'embauche mais pour de vrais programmes ? C'est un point souvent oublié par les personnes qui ne connaissent pas la programmation : écrire un petit script qui fait une tâche simple n'est pas la même chose que de programmer Apache, Louvois, ou un logiciel de calcul scientifique comme Blast.
Quelques réflexions et éléments sur ce sujet :
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.