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.


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

IPv6 chez OVH, c'est bizarre

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


L'article seul

Fiche de lecture : Datamania - le grand pillage de nos données personnelles

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.


L'article seul

The Drink DNS server at FOSDEM

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.


L'article seul

Mon exposé sur la neutralité du code à Touraine Tech

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 ?

Il y avait à cet évènement de nombreuses autres conférences intéressantes(sans compter les fouées aux rillettes) :

  • L'introduction de Ploum, très drôle et très vivante,
  • la conférence d'Amélie Abdallah « Féminisation dans la tech : la communication, ou l'échec de tout un secteur » sur le sexisme dans l'informatique et comment le combattre (supports ici),
  • celle de Jimmy Kasprzak, « Développer et enseigner, une bonne idée ? » sur l'importance et la difficulté de l'enseignement,
  • la conférence dessinée (très bons dessins) de Victor Lambret sur les méthodes de développement logiciel, où comment des études scientifiques montrent que les conseils de bon sens des consultants, même appuyés sur un sigle à la mode (comme TDD) ne produisent pas de meilleur code,
  • celle de Cécile Freyd-Foucault et Iris Naudin le jeudi soir, sur des thèmes classiques (accessibilité et fracture numérique) mais très bien traités (à faire suivre par les gens qui ignorent encore le problème) ; les références utilisées pour leur exposé sont en ligne, j'ai beaucoup aimé l'article d'Anne-Sophie Tranchet sur les formulaires odieux,
  • l'amusant « Développer publiquement un site en milieu hostile : retour d'expérience », d'Alexis Lozano, où il détaille les étapes sucessives d'un petit projet Web avec contenu fourni par les utilisateurices, et les problèmes successifs dûs aux abrutis, exposé très bien fait, très intéressant et concret,
  • comme aujourd'hui on fait de l'IA partout, la conférence « Si on aidait le capitaine Némo à classifier les monstres marins ? » de Eléa Petton et Stéphane Philippart, est recommandée, un tutoriel nous guidant pas à pas dans la construction d'une application de reconnaissance de sons, très pédagogique. Plusieurs démonstrations concrètes avec Python et Jupyter (et les bibliothèques librosa, pandas, sklearn, tensorflow, etc).
  • et enfin la conférence très détaillée de Fabien Trégan et Olivier Poncet sur la représentation des nombres dans les ordinateurs (même si vous savez déjà que (1/3)*3 ne fait pas 1, vous y apprendrez des choses), avec des supports écrits à la main sur un fond évoquant un cahier d'écolier.

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 : touraine-tech-2023-dall-e.jpg.

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 : touraine-tech-2023-dedicaces.jpg


L'article seul

ChatGPT remplacera t-il les programmeuses et programmeurs ?

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 :chatgpt-http-elixir.png

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 :

  • ChatGPT n'est pas réflexif, il ne s'analyse pas lui-même et n'est pas capable de donner un degré de certitude sur ses « solutions ». Il affirme souvent des choses fausses avec le même niveau de confiance que les choses les plus indiscutables. Et il invente souvent des choses qui n'existent pas (articles scientifiques, options de logiciel, etc).
  • Certains promoteurs de ChatGPT disent ne pas s'inquiéter de la mauvaise qualité (parfois) du code en considérant que, du moment que « ça marche », c'est suffisant. Mais cet argument ne vaut pas pour la sécurité. Si un programmme a une faille de sécurité, il va marcher, mais être néanmoins dangereux.

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 :


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.