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.


Des services de DNS secondaires gratuits

Première rédaction de cet article le 30 août 2024
Dernière mise à jour le 3 septembre 2024


Pour des raisons de robustesse, il est fortement recommandé d'avoir plusieurs serveurs faisant autorité pour une zone DNS. Mais ce n'est pas tout : il faut aussi de la diversité, pour éviter que la même cause ne rende plusieurs serveurs injoignables. Il est donc très souhaitable d'avoir des serveurs secondaires en dehors de son réseau habituel. Si on est une grosse organisation, il existe des offres commerciales pour cela. Et si on est une petite organisation, avec peu de moyens ? Des solutions existent quand même.

Un nombre important de serveurs faisant autorité est certes souhaitable (la résolution doit toujours fonctionner même si un serveur est en panne) mais il vaut encore mieux qu'ils soient divers. Si on a quatre serveurs (un bon nombre) mais qu'ils sont dans la même armoire, ou alimentés par le même système électrique, ou routés ensemble par le même AS, ces quatre serveurs vivent sous la menace d'un SPOF : une panne peut les planter tous les quatre.

La solution est donc d'avoir des serveurs secondaires, qui iront récupérer les données sur le serveur primaire (d'où le terme de serveurs esclaves, que l'on trouve par exemple dans les fichiers de configuration de certains logiciels). Mais pour avoir le maximum de diversité, il vaut mieux qu'ils soient routés via des AS différents, et même qu'ils soient gérés par des organisations différentes. On peut toujours demander à des copains ou copines d'héberger de tels secondaires (le DNS fonctionnait souvent comme cela au début). Mais si on n'a pas de copines ou copains qui fournissent ce service ? Alors, il y a plusieurs solutions gratuites :

Pour tous ces services, quelques points à garder en tête :

  • Cela va de soi mais je le répète quand même : il faut avoir un serveur primaire que vous gérez vous-même. Cet article ne parle que de trouver des secondaires.
  • Il s'agit à chaque fois de services gratuits, qui font au mieux, mais qui ne peuvent pas fournir une fiabilité de 100 % (mais, comme souvent avec les services créés par des passionné·es, cela marche souvent mieux que les services commerciaux et le support répond plus vite et plus sérieusement). Soyez gentil·les avec leurs administrateurices.
  • Si vous vous inquiétez pour l'intégrité de vos données DNS (qui nous dit que ces administrateurices ne vont pas subrepticement modifier les enregistrements ?), signez avec DNSSEC. De toute façon, signez avec DNSSEC.
  • Tous ces services fournissent ce qu'il faut pour DNSSEC mais vérifiez quand même. Et, bien sûr, c'est vous qui êtes responsable de la supervision.
  • Si vous vous inquiétez pour la confidentialité des requêtes (pas des données, qui sont publiques, mais des requêtes), vous avez raison de vous inquiéter. Si vous ne vous inquiétez pas, lisez le RFC 7626. DNSSEC ne traite pas ce problème.

Outre les copains et copines, outre les services gratuits comme ceux cités ici, on peut aussi recourir aux services de gens de son écosystème professionnel ou associatif. Ainsi, les services publics ne devraient pas hésiter à échanger des services de DNS secondaire (ils ne sont pas concurrents, après tout), mais on constate que ce n'est pas le cas, les rendant vulnérables aux pannes et aux attaques par déni de service.


L'article seul

Pour se protéger de l'étranger, bloquons les accès de l'extérieur

Première rédaction de cet article le 29 août 2024
Dernière mise à jour le 31 août 2024


On le sait, les attaques par déni de service sont une des plaies de l'Internet, très difficiles à contrer. Quand elles sont motivés géopolitiquement, on peut souvent les lier à des pays étrangers (pas toujours à juste titre). Il est donc tentant de bloquer les attaques en bloquant l'étranger, ce que vient de faire la Cour de Cassation. Intéressant cas de géopolitique Internet.

Tout a commencé par une remarque d'une internaute vivant à l'étranger et qui s'étonnait de ne pas pouvoir accéder au site Web de la Cour de Cassation, https://www.courdecassation.fr/ (Timeout). Ma première réaction a été « Chez Moi, Ça Marche ». Mais je sais que l'Internet est plus compliqué que cela, je teste donc davantage, notamment avec les sondes RIPE Atlas, qui montrent une fois de plus leur caractère indispensable, et avec Globalping. Et l'on voit que tout dépend du pays.

D'abord, voyons comment tester. Depuis une machine qui peut joindre le site Web de la Cour, on teste ping :

% ping -c 3 www.courdecassation.fr
PING www.courdecassation.fr.direct.cdn.anycast.me (80.87.226.23) 56(84) bytes of data.
--- www.courdecassation.fr.direct.cdn.anycast.me ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2055ms

Raté, l'hébergeur bloque ICMP echo. C'est bête mais c'est fréquent. Il va donc falloir tester uniquement en HTTPS. Sur ma machine, curl est content :

    
% curl -v https://www.courdecassation.fr/ |& more
…
* Connected to www.courdecassation.fr (80.87.226.23) port 443 (#0)
…
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN: server accepted http/1.1
…
> GET / HTTP/1.1
> Host: www.courdecassation.fr
> User-Agent: curl/7.88.1
…
< HTTP/1.1 200 OK
< Server: nginx
…
<!DOCTYPE html>
<html lang="fr" dir="ltr" prefix="og: https://ogp.me/ns#">
  <head>
    <meta charset="utf-8" />
<script>var _paq = _paq || [];(function(){var u …

  

Mais depuis une machine aux États-Unis, ça échoue :

%  curl -v https://www.courdecassation.fr/
*   Trying 80.87.226.23:443...
* connect to 80.87.226.23 port 443 failed: Connection timed out
* Failed to connect to www.courdecassation.fr port 443 after 131838 ms: Couldn't connect to server
* Closing connection 0
curl: (28) Failed to connect to www.courdecassation.fr port 443 after 131838 ms: Couldn't connect to server

  

Sachant que les institutions françaises (et la Cour de Cassation avait été explicitement citée sur certains réseaux sociaux) ont été victimes dans les jours précédents d'attaques par déni de service politiquement motivées (apparemment en lien avec l'arrestation de Pavel Durov), on peut commencer à se douter que le résultat va dépendre du pays.

Il faudrait tester depuis davantage de points : l'Internet est vaste. Utilisons les sondes RIPE Atlas, via le logiciel Blaeu. Comme les sondes Atlas ne permettent de l'HTTP que dans des conditions très limitées, on va juste attaquer en TLS :

% blaeu-cert -r 100 -4 www.courdecassation.fr
73 probes reported
[/CN=www.courdecassation.fr] : 5 occurrences 
[FAILED TO GET A CERT: connect: timeout] : 68 occurrences 
Test #78156324 done at 2024-08-29T08:35:23Z   
  

OK, certaines sondes peuvent récupérer le certificat, d'autres pas. On soupçonne déjà que ça dépend du pays donc utilisons la possibilité d'Atlas de sélectionner le pays :

% blaeu-cert --requested 100 -4 --country FR  www.courdecassation.fr
93 probes reported
[FAILED TO GET A CERT: connect: timeout] : 1 occurrences 
[/CN=www.courdecassation.fr] : 92 occurrences 
Test #78157154 done at 2024-08-29T09:18:36Z

% blaeu-cert --requested 100 -4 --country IT  www.courdecassation.fr
94 probes reported
[FAILED TO GET A CERT: timeout reading hello] : 3 occurrences 
[FAILED TO GET A CERT: connect: timeout] : 91 occurrences 
Test #78157186 done at 2024-08-29T09:19:28Z

Bref, pas de problème pour les résidents français, c'est juste l'étranger qui est bloqué. Notons toutefois que les DROM semblent exclus de la France :

% blaeu-cert -4 --requested 10 --country GP www.courdecassation.fr
2 probes reported
[FAILED TO GET A CERT: connect: timeout] : 2 occurrences 
Test #78167255 done at 2024-08-29T11:41:39Z

% blaeu-cert -4 --requested 10 --country NC www.courdecassation.fr
5 probes reported
[FAILED TO GET A CERT: connect: timeout] : 5 occurrences 
Test #78167664 done at 2024-08-29T11:50:46Z

Globalping permet des requêtes HTTP. Si on lui envoie ce code JSON :

{
    "limit": 100,
    "locations": [{"country": "FR"}],
    "target": "www.courdecassation.fr",
    "type": "http",
    "measurementOptions": {
       "protocol": "HTTPS",
       "request": {
          "path": "/"
         }
    }
}

On teste en France et cela confirme le résultat des sondes Atlas ; tout marche (ou presque : la géolocalisation n'est jamais parfaite). En demandant un autre pays, tout échoue.

L'accès depuis, apparemment, le monde entier a été rétabli le 30 ou le 31 août. Tout remarche désormais.

En conclusion, il est clair que l'hébergeur de la Cour a choisi de se retrancher derrière les frontières nationales, suite aux attaques subies. Un intéressant exemple de géopolitique. Mais, par delà la question de bloquer l'accès aux gens situés à l'étranger, il n'est pas sûr que cela soit efficace du point de vue opérationnel : les attaquants professionnels n'attaquent pas depuis la machine qui est sur le bureau, ils utilisent un botnet, dont certaines machines sont en France… En outre, le blocage est fait en couche 3 (IP), contrairement aux sites de vidéo à la demande ou de commerce en ligne, qui, pour des raisons juridiques, le font en couche 7. Cela a pour conséquence l'absence de message d'erreur clair pour l'utilisateurice.

Merci à Marie-Odile Morandi pour le signalement de ce cas intéressant.


L'article seul

Essais du système de déboguage des réseaux Globalping

Première rédaction de cet article le 28 août 2024


Si vous lisez ce blog régulièrement, vous savez que j'insiste souvent pour que, lorsqu'on teste un service réseau, on ne le fasse pas que depuis un seul point de mesure. L'Internet est vaste, et varié ! Il faut donc utiliser plusieurs points de mesure. Si on ne travaille pas chez Google, on n'a probablement à sa disposition qu'un petit nombre de points à sa disposition et on utilise donc un système réparti de mesure. Vous le savez, je suis un grand fan des sondes RIPE Atlas mais il est toujours bon de regarder les alternatives comme Globalping, qui fait l'objet de cet article.

Alors, je ne vais pas arrêter d'utiliser le système des sondes RIPE Atlas, qui a bien plus de points de mesure et, surtout, qui est géré par une organisation sans but lucratif, contrôlée par ses membres. Mais la diversité sur l'Internet est une bonne chose, et il faut connaitre les autres possibilités. Donc, Globalping est un réseau de points de mesures actives, utilisant l'infrastructure du CDN jsDelivr, mesures qu'on peut déclencher soi-même. Je vous laisse regarder le site Web pour en savoir plus, je vais juste tester un peu.

Les mesures peuvent être déclenchées par l'interface Web, par un programme qu'on installe localement (n'étant pas fan de curl install.sh | sudo bash, je ne l'ai pas testé) ou par une API. Celle-ci semble bien fichue et bien documentée donc je vais faire les essais avec elle. Dans tous les cas, c'est gratuit et il n'y a pas besoin de se créer un compte, ce qui est très rafraichissant dans un monde où les marketeux insistent pour que vous laissiez vos données personnelles pour tout et n'importe quoi. Je suppose que ces accès « anonymes » ont des limites, par exemple en nombre de mesures déclenchées, mais je n'ai pas étudié la question en profondeur.

Donc, commençons avec l'API. On fait une requête HTTP à api.globalping.io et la requête est évidemment un petit bout de JSON. Voici un exemple d'un script shell qui appelle curl pour demander une mesure IPv6 vers ce blog :

    
#!/bin/sh

curl --compressed --write-out '\nReturn code: %{http_code}\n' \
     --data-binary @- \
     --header "Content-Type: application/json" \
   https://api.globalping.io/v1/measurements \
<<EOF
{
    "limit": 5,
    "locations": [],
    "target": "www.bortzmeyer.org",
    "type": "ping",
    "measurementOptions": {
        "packets": 3,
        "ipVersion": 6 
    }
}
EOF

  

Le script va vous afficher l'identificateur de cette mesure, vous pouvez la récupérer en ajoutant https://api.globalping.io/v1/measurements/ devant. Ce sera du JSON, qu'on peut traiter avec les moyens classiques, par exemple jq, comme avec les sondes Atlas :

% jq '"Average: " + (.results[].result.stats.avg | tostring) + " ms"' chDqJ8xB9HxCrpCe.json  
"Average: 225.948 ms"
"Average: 223.1 ms"
"Average: 139.932 ms"
"Average: 35.985 ms"
"Average: 2.802 ms"
  

Ici, on affiche le temps d'aller-retour moyen pour chaque sonde. Je ne crois pas que le JSON produit soit documenté mais il est assez clair comme cela.

J'aime bien les éventuels messages d'erreur, très précis :


{
  "error": {
    "type": "validation_error",
    "message": "Parameter validation failed.",
    "params": {
      "measurementOptions.protocole": "\"measurementOptions.protocole\" is not allowed"
    }
  },
  "links": {
    "documentation": "https://www.jsdelivr.com/docs/api.globalping.io#post-/v1/measurements"
  }
}
  

On peut aussi faire des mesures DNS, par exemple avec cette demande en JSON :

{
    "limit": 5,
    "locations": [],
    "target": "qwant.com",
    "type": "dns",
    "measurementOptions": {
    }
}  
  

Et si on demande dans le fichier résultant les données obtenues :

% jq '.results[].result.answers[].value' eghOnwP7HffbmGVa.json
"54.38.0.163"
"141.95.150.143"
"141.94.211.182"
"54.38.0.163"
"141.94.211.182"
…
  

Mais, apparemment, on ne peut pas récupérer la réponse DNS complète, seulement les parties analysées par leur logiciel.

Et avec HTTP ? Demandons :

{
    "limit": 5,
    "locations": [],
    "target": "www.aemarielle.com",
    "type": "http",
    "measurementOptions": {
       "protocol": "HTTPS",
       "request": {
         "path": "/"
       }
    }
}
  

Et on obtient un beau fichier JSON dont on peut extraire, par exemple :

% jq '"Total time: " + (.results[].result.timings.total | tostring) + " ms"' iLBZu1TOiyqXzQF1.json
"Total time: 1481 ms"
"Total time: 1157 ms"
"Total time: 421 ms"
"Total time: 1512 ms"
"Total time: 888 ms"
  

Et si on veut participer et avoir sa propre sonde ? (J'ai oublié de dire que tout est apparemment en logiciel libre.) La solution suggérée est d'installer une sonde logicielle via Docker ou Podman. Bon, pour être franc, avec la commande indiquée, je n'ai pas réussi à le faire avec Podman :

WARN[0000] Using cgroups-v1 which is deprecated in favor of cgroups-v2 with Podman v5 and will be removed in a future version. Set environment variable `PODMAN_IGNORE_CGROUPSV1_WARNING` to hide this warning. 
Error: failed to get new shm lock manager: failed to create 2048 locks in /libpod_lock: no such file or directory

Ou bien, sur une autre machine :

Error: short-name "globalping/globalping-probe" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

On peut aussi demander une sonde matérielle mais il faut payer dix dollars par mois ce qui m'a semblé excessif.


L'article seul

RFC 9637: Expanding the IPv6 Documentation Space

Date de publication du RFC : Août 2024
Auteur(s) du RFC : G. Huston (APNIC), N. Buraglio (Energy Sciences Network)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 28 août 2024


Le préfixe IPv6 normalisé pour les documentations, 2001:db8::/32 était trop petit pour vous ? Vous aviez du mal à exprimer des architectures réseau complexes, avec beaucoup de préfixes ? Ne pleurez plus, un nouveau préfixe a été alloué, c'est désormais un /20, le 3fff::/20.

Ce RFC modifie légèrement le RFC 3849, qui normalisait ce préfixe de documentation. Le but d'un préfixe IP de documentation est d'éviter que les auteur·es de ces documentations ne prennent des adresses IP qui existent par ailleurs, au risque que des administrateurices réseaux maladroit·es ne copient ces adresses IP (songez au nombre d'articles qui parlent d'IPv4 en utilisant des exemples comme les adresses 1.1.1.1 ou 1.2.3.4, qui existent réellement). On doit donc utiliser les noms de domaine du RFC 2606, les adresses IPv4 du RFC 5737, et les numéros d'AS du RFC 5398. Pour IPv6, l'espace de documentation est désormais 3fff::/20 (l'ancien préfixe 2001:db8::/32 reste réservé et valable donc pas besoin de modifier les documentations existantes).

Cette nouvelle taille permet de documenter des réseaux réalistes, par exemple où deux /32 se parlent.

Si ce préfixe est désormais dans le registre des adresses spéciales, il ne semble pas (encore ?) décrit dans la base d'un RIR, contrairement à son prédécesseur.


Téléchargez le RFC 9637


L'article seul

RFC 9276: Guidance for NSEC3 Parameter Settings

Date de publication du RFC : Août 2022
Auteur(s) du RFC : W. Hardaker (USC/ISI), V. Dukhovni (Bloomberg)
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 26 août 2024


Si vous êtes responsable d'une zone DNS, et que vous la testez régulièrement avec des outils comme Zonemaster ou DNSviz (ce que font tous les responsables sérieux), vous avez peut-être eu des avertissements comme quoi vos « paramètres NSEC3 » n'étaient pas ceux conseillés. C'est parce que les recommandations en ce sens ont changé avec ce RFC. Lisez-le donc si vous voulez comprendre les recommandations actuelles.

D'abord, un peu de contexte. Ce RFC concerne les zones qui sont signées avec DNSSEC et qui utilisent les enregistrements NSEC3 du RFC 5155. Aujourd'hui, par exemple, c'est le cas de .fr, .com mais aussi de bortzmeyer.org grâce à qui vous êtes arrivés sur cet article. Mais ce n'est pas le cas de la racine des noms de domaine, qui utilise NSEC (RFC 4035). Pour comprendre la dfifférence entre les deux, je vous renvoie à mon article sur le RFC 5155.

Un exemple où Zonemaster proteste, sur icann.org : zonemaster-icann-nsec3.png

Ce RFC 5155 donnait des conseils de sécurité cryptographiques qui, avec le recul et l'expérience se sont avérés sous-optimaux. Ce nouveau RFC 9276 les modifie donc et suggère fortement de ne plus utiliser de sel, ni d'itérations successives, dans le calcul des condensats pour NSEC3.

Lorsqu'une zone est signée avec utilisation de NSEC3, elle comprend un enregistrement de type NSEC3PARAM qui indique quatre choses :

  • L'algorithme de condensation utilisé (presque toujours SHA-1, aujourd'hui, c'est le seul normalisé). Il n'est pas discuté ici (voir le RFC 8624 sur le choix des algorithmes).
  • Les options, notamment celle nommée opt-out et qui est un avantage souvent oublié de NSEC3 par rapport à NSEC : la possibilité de ne pas avoir un enregistrement NSEC3 par nom mais seulement par nom signé. C'est un peu moins sûr (les noms non signés, typiquement les délégations DNS, ne sont pas protégés) mais ça fait une grosse économie de mémoire pour les zones qui comprennent beaucoup de délégations non signées (et cela évite de passer trop de temps à modifier les chaines NSEC3 dans des zones qui changent souvent). C'est typiquement la cas des gros TLD et cela explique pourquoi .fr ou .com utilisent NSEC3, même s'il n'y a pas de problème avec l'énumération des noms (.fr distribue la liste). (Notez que si l'option est à 0 dans le NSEC3PARAM, cela ne signifie pas qu'il n'y a pas d'opt-out, celui-ci est typiquement indiqué uniquement dans les enregistrements NSEC3.)
  • Le nombre d'itérations supplémentaires (RFC 5155, sections 3.1.3 et 4.1.3) faites lorsqu'on condense un nom.
  • Le sel utilisé.

Voici par exemple l'enregistrement de icann.org en août 2024 :

% dig +short icann.org NSEC3PARAM
1 0 5 A4196F45E2097176
  

Utilisation de SHA-1 (le 1 est le code de SHA-1), pas d'opt-out (mais prudence, son utilisation n'est pas obligatoirement signalée dans les options, voir plus haut), cinq itérations supplémentaires (donc six au total) et un sel apparemment aléatoire, A4196F45E2097176.

La première recommandation du RFC concerne le nombre d'itérations. Comme le sel, le but est de rendre plus difficile l'utilisation de tables calculées à l'avance par un attaquant. Sans sel et avec une seule itération, un attaquant qui a à l'avance calculé tout un dictionnaire et sait donc que le condensat de foobar est 8843d7f92416211de9ebb963ff4ce28125932878 pourra donc facilement inverser le condensat dans un enregistrement NSEC3. C'est pour cela que le RFC 5155 recommandait un nombre variable d'itérations, indiqué par l'enregistrement NSEC3PARAM. Mais, en pratique, la protection contre l'énumération n'est pas si solide que ça. Bien des noms peuvent être devinés (www étant le plus évident mais il y a aussi les mots d'un dictionnaire de la langue), d'autant plus qu'on choisit en général un nom de domaine pour être simple et facilement mémorisable. Et que ces noms se retrouvent à plein d'endroits comme les journaux Certificate Transparency (RFC 9162). L'opinion d'aujourd'hui est que le jeu (la protection contre l'énumération) n'en vaut pas la chandelle (le coût de signature et de validation). Notez aussi une externalité négative : les résolveurs aussi devront effectuer ces itérations et sont donc concernés. Bon, en prime, les techniques modernes rendent la protection peu efficace de toute façon (cf. « GPU-Based NSEC3 Hash Breaking »). La recommandation du RFC est donc de ne pas avoir d'itérations supplémentaires, donc de mettre ce nombre à zéro.

Et la deuxième recommandation concerne le sel. Il y a dans NSEC3 un sel implicite, c'est le nom de domaine (RFC 5155, section 5). D'ailleurs, mon exemple de condensat de foobar était faux, puisque j'avais omis cette étape. Si on l'inclut, le sel supplémentaire indiqué dans l'enregistrement NSEC3PARAM perd de son intérêt. En outre, en pratique, on change rarement le sel (cela nécessite de modifier toute la chaine NSEC3) ce qui diminue la protection qu'il offre. La recommandation actuelle est donc de ne pas utiliser de sel (ce qui se note avec un tiret, pas avec une chaine vide).

Si on suit les recommandations du RFC, le NSEC3PARAM aura cette allure :


% dig +short fr NSEC3PARAM
1 0 0 -

  

Et un des NSEC3 sera du genre :


% dig nexistesurementpas.fr 
qu7kmgn3e….fr. 594 IN NSEC3 1 1 0 - (
                                QU7MMK1…
                                NS DS RRSIG )


  

Notez aussi que le RFC recommande (section 3), avant de réfléchir aux paramètres de NSEC3, de réfléchir à NSEC3 lui-même. Sur une grosse zone de délégation, changeant souvent, comme .fr, NSEC3 est tout à fait justifié en raison des avantages de l'opt-out. Mais sur la zone DNS typique d'une petite organisation, qui ne compte souvent que des noms prévisibles (l'apex, www et mail), NSEC3 peut avantageusement être remplacé par NSEC, qui consomme moins de ressources. (NSEC3, ou d'ailleurs les couvertures minimales du RFC 4470, peut, dans le pire des cas, faciliter certaines attaques par déni de service.)

Les recommandations précédentes s'appliquaient aux signeurs de zone (côté serveurs faisant autorité, donc). Mais la section 3 a aussi des recommandations pour les résolveurs : compte-tenu du coût que représente pour eux les itérations NSEC3, ils ont le droit d'imposer un maximum, et de le diminuer petit à petit. Ces résolveurs peuvent refuser de répondre (réponse SERVFAIL) ou bien traiter la zone come n'étant pas signée (cf. section 6). Un nouveau code d'erreur étendu (RFC 8914), le numéro 27, Unsupported NSEC3 iterations value, a été réservé pour qu'ils puissent informer leurs clients.

Revenons aux serveurs faisant autorité : le RFC précise aussi qu'un hébergeur DNS devrait informer clairement ses utilisateurs des paramètres NSEC3 qu'il accepte. Il ne faudrait pas qu'on choisisse N itérations et qu'on s'aperçoive au déploiement qu'un des secondaires n'accepte pas d'en faire autant.

Aujourd'hui, la grande majorité des zones utilisant NSEC3 est passée aux recommandations de ce RFC (comme par exemple .fr en 2022). Notons que .org a un sel mais pas d'itérations supplémentaires.

 % dig +short org NSEC3PARAM
1 0 0 332539EE7F95C32A
  

Si vous utilisez OpenDNSSEC pour automatiser les opérations DNSSEC sur vos zones, voici la configuration conforme au RFC que j'utilise :


<Denial>
        <NSEC3>
                <!-- <OptOut/> -->
                <Resalt>P100D</Resalt> 
                <Hash>
                        <Algorithm>1</Algorithm>
                        <Iterations>0</Iterations>
                        <Salt length="0"/>
                </Hash>
        </NSEC3>
</Denial>

  

Téléchargez le RFC 9276


L'article seul

Fiche de lecture : Le triomphe et le règne des mammifères

Auteur(s) du livre : Steve Brusatte
Éditeur : Quanto
978-288915-554-5
Publié en 2023
Première rédaction de cet article le 26 août 2024


Vous qui me lisez, vous êtes probablement un mammifère. Sans une météorite complaisante, vous seriez toujours un genre de petite souris qui n'a même pas inventé l'Internet et vous ne pourriez pas lire ce blog. Heureusement pour vous et malheureusement pour les dinosaures, la météorite a frappé, dégageant le terrain pour « le triomphe et le règne des mammifères », que raconte ce livre.

L'auteur avait justement écrit avant sur les dinosaures mais je n'ai pas lu ce précédent livre. Ici, il décrit en détail toute l'histoire de ces bestioles à poils et à mamelles dont nous faisons partie. C'est un livre de vulgarisation mais il faut s'accrocher quand même, l'auteur ne se contente pas d'images d'animaux mignons, il rentre bien dans les détails techniques, mais c'est très vivant, très bien écrit, une lecture recommandée si vous voulez vous tenir au courant du passé.

L'auteur ne parle pas que des bestioles, une part importante du livre est consacrée aux paléontologues, à leur parcours personnel et professionnel souvent surprenant, à leur travail et à leurs découvertes. (Vous y lirez, par exemple, une rencontre avec Zofia Kielan-Jaworowska.)

(J'ai lu la traduction en français, l'original en anglais avait été publié en 2022.)


L'article seul

RFC 9301: Locator/ID Separation Protocol (LISP) Control-Plane

Date de publication du RFC : Octobre 2022
Auteur(s) du RFC : D. Farinacci (lispers.net), F. Maino (Cisco Systems), V. Fuller (vaf.net Internet Consulting), A. Cabellos (UPC/BarcelonaTech)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF lisp
Première rédaction de cet article le 23 août 2024


Comme pour tous les protocoles de séparation de l'identificateur et du localisateur, le protocole LISP, normalisé dans le RFC 9300, doit faire face au problème de la correspondance (mapping) entre les deux informations. Comment trouver un localisateur, en ne connaissant que l'identificateur ? LISP n'a pas de solution unique et plusieurs protocoles de correspondance peuvent être utilisés. La stabilité du logiciel des routeurs imposait une interface stable avec le système de résolution des identificateurs en localisateurs. C'est ce que fournit notre RFC 9301, qui spécifie l'interface, vue du routeur, et qui ne devrait pas changer, même si de nouveaux systèmes de correspondance/résolution apparaissent. Ce RFC remplace le RFC 6833. L'interface change assez peu mais le texte est sérieusement réorganisé, et la spécification a désormais le statut de norme et plus simplement d'expérimentation.

LISP prévoit deux sortes de machines impliquées dans la résolution d'identificateurs (les EID, Endpoint ID) en localisateurs (les RLOC, Routing Locator). Ces deux machines sont les Map-Resolver et les Map-Server. Pour ceux qui connaissent le DNS, on peut dire que le Map-Server est à peu près l'équivalent du serveur faisant autorité et le Map-Resolver joue quasiment le même rôle que celui du résolveur. Toutefois, il ne faut pas pousser la comparaison trop loin, LISP a ses propres règles. Pour résumer en deux phrases, un routeur LISP d'entrée de tunnel (un ITR, Ingress Tunnel Router), ayant reçu un paquet à destination d'une machine dont il connait l'identificateur (l'EID), va interroger un Map-Resolver pour connaître le localisateur (le RLOC, auquel l'ITR enverra le paquet). Pour accomplir sa tâche, le Map-Resolver fera suivre les requêtes au Map-Server, qui la transmettra finalement au routeur de sortie du tunnel (l'ETR, Egress Tunnel Router), qui est la vraie source faisant autorité.

C'est entre le Map-Resolver et le Map-Server que se trouvent les détails du système de correspondance. Ils peuvent être connectés par ALT (RFC 6836), par CONS (RFC jamais publié), par NERD (RFC 6837), par DDT (RFC 8111) ou bien par tout autre système de résolution, existant ou encore à créer (ils ne peuvent pas être connectés avec simplement LISP, puisqu'on aurait alors un problème d'œuf et de poule, LISP ayant besoin de ALT qui aurait besoin de LISP… cf. section 8.1). Rappelez-vous que notre RFC 9301 ne décrit qu'une interface, celle des ITR et ETR avec les Map-Resolver et Map-Server. Il est donc relativement court.

Comme avec toute technique nouvelle, il est prudent d'apprendre le vocabulaire (section 3, puis section 4 pour un survol général du système). Il y a deux types d'acteurs, les Map-Server et les Map-Resolver que nous avons déjà vu, et trois types importants de messages, Map-Register (un ETR l'envoie au Map-Server pour indiquer les RLOC des EID dont il est responsable), Map-Request (un ITR l'envoie à un Map-Resolver pour obtenir les RLOC ; le Map-Resolver fait suivre jusqu'au Map-Server, puis à l'ETR) et enfin Map-Reply, la réponse au précédent. Notons que ces types de messages ont leur description complète (avec leur format) dans le RFC 9300. Notez aussi que Map-Resolver et Map-Server sont des fonctions, et que les deux peuvent être assurés par la même machine, qui serait à la fois Map-Resolver et Map-Server (dans le DNS, un tel mélange est déconseillé).

Schéma général du système de correspondance LISP : lisp-mapping

La section 8 de notre RFC plonge dans les détails. Accrochez-vous. Voyons d'abord le premier routeur LISP que rencontrera le paquet. On le nomme ITR pour Ingress Tunnel Router. Les routeurs précédents traitaient l'adresse de destination du paquet comme une adresse IP ordinaire. L'ITR, lui, va la traiter comme un identificateur (EID pour Endpoint IDentification). L'EID n'est pas routable sur l'Internet. Il faut donc encapsuler le paquet en LISP pour l'envoyer dans le tunnel. La nouvelle adresse IP de destination est le localisateur (RLOC pour Routing LOCator). Pour trouver le localisateur, l'ITR va demander à un ou plusieurs Map-Resolver. Il a été configuré (typiquement, à la main) avec leurs adresses IP (qui doivent être des localisateurs, pour éviter un amusant problème d'œuf et de poule; notez que plusieurs Map-Resolver peuvent avoir la même adresse, grâce à l'anycast). L'ITR ne connait que le protocole de résolution, envoi d'une Map-Request et récupération d'une Map-Reply (en termes DNS, l'ITR est un stub resolver). L'ITR ne connait donc pas les protocoles utilisés en interne par le système de correspondance, il ne connait pas ALT (ou ses concurrents). Cette communication avec le Map-Resolver peut être testée et déboguée avec l'outil lig (RFC 6835).

La réponse du Map-Resolver ne sera pas forcément positive. L'ITR recevra peut-être une negative Map-Reply, envoyée en réponse si un Map-Resolver ne trouve pas de localisateur pour l'identificateur qu'on lui a passé. Cela veut dire que le site final n'utilise pas LISP, et qu'il faut alors router le paquet avec les méthodes habituelles d'IP. (Il n'est évidemment pas prévu que tout l'Internet passe à LISP du jour au lendemain, le routeur LISP doit donc aussi pouvoir joindre les sites non-LISP.)

Si la réponse est positive, l'ITR peut alors encapsuler le paquet et le transmettre. Comment le Map-Resolver a-t-il trouvé la réponse qu'il a envoyé ? Contrairement aux routeurs LISP comme l'ITR, le Map-Resolver et le Map-Server connaissent le système de correspondance utilisé (si c'est ALT, ils sont tous les deux routeurs ALT) et c'est celui-ci (non traité dans ce RFC) qu'ils utilisent pour savoir s'il y a une réponse et laquelle.

Et, à l'autre bout du tunnel, que s'était-il passé ? Le routeur de fin de tunnel (l'ETR, pour Egress Tunnel Router), avait été configuré par un administrateur réseaux avec une liste d'EID dont il est responsable. Pour que le reste du monde connaisse ces EID, il les publie auprès d'un Map-Server en envoyant à ce dernier des messages Map-Register. Pour d'évidentes raisons de sécurité, ces messages doivent être authentifiés (champ Authentication Data du message Map-Register, avec clés gérées à la main pour l'instant, avec SHA-256 au minimum), alors que les Map-Request ne l'étaient pas (la base de données consultée par les routeurs LISP est publique, pas besoin d'authentification pour la lire, seulement pour y écrire). Ces Map-Request sont renvoyés périodiquement (le RFC suggère toutes les minutes) pour que le Map-Server sache si l'information est toujours à jour. Ainsi, si un ETR est éteint, l'information obsolète dans les Map-Server disparaîtra en trois minutes maximum (des messages peuvent être perdus, le RFC demande donc de patienter un peu en cas de non-réception). Cela veut aussi dire que LISP ne convient pas forcément tel quel pour les situations où on exige une mobilité très rapide.

Notez que je ne décris pas tous les détails (comme la possibilité pour un ETR de demander un accusé de réception au Map-Server, chose que ce dernier ne fait pas par défaut), voyez le RFC si vous êtes curieux.

Arrivés là, nous avons un Map-Server qui connait les EID que gère l'ETR. Désormais, si ce Map-Server reçoit une demande Map-Request, il peut la faire suivre à l'ETR (si vous connaissez le DNS, vous avez vu que le Map-Register n'est pas tout à fait l'équivalent des mises à jour dynamiques du RFC 2136 : avec ces dernières, le serveur de noms qui a reçu la mise à jour répondra ensuite lui-même aux requêtes). Le Map-Server ne sert donc que de relais, il ne modifie pas la requête Map-Request, il la transmet telle quelle à l'ETR. Le rôle des Map-Resolver et des Map-Server est donc simplement de trouver l'ETR responsable et de lui faire suivre (sans utiliser l'encapsulation LISP) les requêtes, pas de répondre à sa place. Cela se fera peut-être dans le futur lorsque des mécanismes de cache seront ajoutés. Pour le moment, les Map-Resolver n'ont pas de cache, de mémoire (section 4), une grosse différence avec le DNS (section 1).

La section 9 fait le tour des questions de sécurité liées au service de résolution. Comme les requêtes sont faites avec le format de paquets de LISP, elles héritent des services de sécurité de LISP comme le nonce qui permet de limiter les risques d'usurpation ou comme la sécurité LISP du RFC 9303. Par contre, comme pour les protocoles utilisés dans l'Internet actuel, il n'y a pas de vraie protection contre les annonces faites à tort (un Map-Server qui annoncerait un EID qui n'est pas à lui). C'est un problème très proche de celui de la sécurité de BGP et qui utilisera peut-être le même genre de solutions.

Notez qu'en théorie, l'interface spécifiée dans ce RFC pourrait servir à d'autres protocoles que celui du RFC 9300, comme par exemple GRE (RFC 2890) ou VXLAN (RFC 7348). Mais, pour l'instant, ce n'est pas le cas.

Il y a apparemment trois mises en œuvre. Outre l'outil de débogage lig (RFC 6835), il y a celle de Cisco pour ses routeurs, mais je ne connais pas les autres, sans doute dans des Unix.

Et les changements depuis le précédent RFC ? Ils sont résumés dans la section 11 :

  • Ajout du type de message Map-Notify-Ack, un accusé de réception,
  • Plein de bits supplémentaires dans les en-têtes des messages,
  • Dans les actions qu'un routeur peut prendre lorsqu'un paquet arrive, ajout de possibilités de rejet du paquet (section 5.4).

Téléchargez le RFC 9301


L'article seul

Fiche de lecture : La souveraineté numérique

Auteur(s) du livre : Brunessen Bertrand, Guillaume Le Floch
Éditeur : Bruylant
978-2-8027-7134-0
Publié en 2024
Première rédaction de cet article le 19 août 2024


Cet ouvrage collectif rassemble les articles liés aux interventions lors d'un intéressant colloque sur la souveraineté numérique tenu à la fac de droit de Rennes en 2022.

(Curieusement, le livre ne mentionne apparemment pas du tout le colloque.)

Comme tous les ouvrages collectifs, personne ne sera d'accord avec tout. Personnellement, j'ai trouvé qu'il y avait une variété de positions qui permet de bien se rendre compte de la difficulté de cerner le concept de souveraineté numérique et ses conséquences. Je trouve quand même que plusieurs articles sont excessivement pro-État, considérant que l'État agit forcément dans l'intérêt des citoyens, que la loi de l'État est toujours parfaite et que le remède à tous les problèmes de l'Internet est davantage de lois formelles (rappelez-vous que ce colloque est organisé par des juristes). Heureusement, certaines interventions comme celle de Pauline Türk (« L'exercice des fonctions de l'État à l'ère numérique ») sont plus critiques vis-à-vis de cette conception.

Une section particulièrement riche et originale est celle consacrée aux différentes conceptions nationales de la souveraineté numérique. Elle permet d'échapper à une vision étroite de la souveraineté et essayant de se placer à la place des autres. Ainsi, Paul-Alain Zibi Fama (qui n'avait pas pu être présent au colloque) parle de la souveraineté numérique, vue d'Afrique, continent régulièrement oublié dans les débats sur l'Internet. L'idée est très bonne mais gâchée par des erreurs comme de parler de blockchain « chiffrée », alors que justement la chaîne de blocs repose sur la transparence, pas sur la confidentialité. D'autre part, il met l'accent sur le manque de cadre juridique en Afrique, comme si c'était le principal problème (encore un biais de juriste). J'ai par contre apprécié l'analyse détaillé de l'état actuel de dépendance de l'Afrique, et l'accent mis sur l'importance de l'éducation.

J'ai aussi noté l'article de Mathilde Velliet sur « La conception américaine [sic] de la souveraineté numérique » à propos de l'extrême hypocrisie de la position de Washington (aussi bien le gouvernement que les influenceurs) pour qui « souveraineté numérique » est un gros mot, uniquement utilisé pour critiquer les efforts d'indépendance technologique des autres pays, notamment l'Europe, alors que les nombreuses interventions de l'État pour aider les entreprises étatsuniennes, qui ont exactement les mêmes objectifs, ne sont jamais critiquées.

Mais lisez le reste du livre : vous y trouverez plein de choses, sur ce thème souvent abordé de manière simpliste dans les médias et les réseaux sociaux. (Oui, je sais, il est cher. Demandez à votre employeur.)

Des vidéos du colloque sont disponibles en ligne.


L'article seul

RFC 9606: DNS Resolver Information

Date de publication du RFC : Juin 2024
Auteur(s) du RFC : T. Reddy.K (Nokia), M. Boucadair (Orange)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF add
Première rédaction de cet article le 18 août 2024


Traditionnellement, tous les résolveurs DNS fournissaient un service équivalent. Le client avait un résolveur configuré, soit statiquement, soit via DHCP, et ne se souciait pas vraiment du résolveur ainsi désigné, tous étaient pareils. Aujourd'hui, ce n'est plus vraiment le cas : les résolveurs fournissent des services très différents, par exemple en matière de chiffrement, ou de blocage de certains noms. Il est donc utile que le client puisse se renseigner sur son résolveur, ce que permet cette nouvelle technique, le type de données RESINFO, que le client va récupérer dans le DNS.

Voici une liste (non-limitative !) des caractéristiques d'un résolveur et qui peuvent être présentes ou pas :

  • Chiffrement des requêtes, avec DoT, DoH ou DoQ.
  • Blocage de certains noms, par exemple la publicité, ou le porno, ou bien les noms qui gênent le gouvernement, ou encore les noms des services qui osent enfreindre la propriété intellectuelle sacrée.
  • Protection de la vie privée via la minimisation des requêtes (RFC 9156) et/ou l'absence de stockage de l'historique des requêtes.

Avant la solution de ce RFC, la seule manière pour le client DNS de savoir ce que son résolveur proposait était manuelle, en lisant des documentations (cf. par exemple celle de mon résolveur). Ce n'est pas pratique quand la configuration du résolveur est automatique ou semi-automatique, via DHCP, ou avec les solutions des RFC 9462 et RFC 9463.

Ce nouveau RFC propose donc un mécanisme qui permet au client de découvrir les caractéristiques d'un résolveur et de les analyser, avant de décider quel résolveur choisir. (Un point important est que ce RFC se veut neutre : il ne dit pas quelles sont les bonnes caractéristiques d'un résolveur, le client reçoit une information, il est libre de l'utiliser comme il veut.)

Place à la technique (section 3 du RFC) : un nouveau type de données DNS est défini, RESINFO (code 261). Son contenu est l'information recherchée, sous forme de couples clé=valeur. Le nom de domaine auquel il est rattaché est le nom du résolveur, récupéré par les méthodes des RFC 9462 et RFC 9463, ou manuellement configuré. Ce nom est désigné par le sigle ADN, pour Authentication Domain Name (RFC 9463, section 3.1.1). Si on a utilisé le nom spécial resolver.arpa (RFC 9462, section 4), on peut lui demander son RESINFO.

Le format du RESINFO (section 4 du RFC) est copié sur celui des enregistrements TXT. Chaque chaine de caractères suit le modèle clé=valeur du RFC 6763, section 6.3. Les clés inconnues doivent être ignorées, ce qui permettra dans le futur d'ajouter de nouvelles clés au registre des clés. Un exemple d'enregistrement RESINFO :

resolver IN RESINFO "qnamemin" "exterr=15,17" "infourl=https://resolver.example.com/guide"
  

Il indique (section 5, sur la signification des clés) que ce résolveur fait de la minimisation des requêtes (RFC 9156), et notez que cette clé n'a pas de valeur, c'est juste un booléen dont la présence indique la QNAME minimisation. L'enregistrement continue en donnant les codes EDE (Extended DNS Errors, RFC 8914) que peut renvoyer le résolveur. C'est surtout utile pour indiquer ce qu'il bloque (15 = bloqué par décision de l'administrateurice du résolveur, 17 = bloqué par demande de l'utilisateurice). Et enfin il donne un URL où on peut aller chercher davantage d'information en langue naturelle.

La section 7 du RFC donne quelques conseils de sécurité : avoir un lien sécurisé avec le résolveur qu'on interroge (par exemple avec DoT), pour éviter qu'un méchant ne modifie le RESINFO, et valider la réponse avec DNSSEC (sauf pour resolver.arpa, qui est un cas spécial).

La section 8 précise le registre des clés disponibles. Pour ajouter des clés (on note qu'à l'heure actuelle, il n'y en a pas pour indiquer la disponibilité de DoT ou DoH, ou pour la politique de conservation des requêtes), la procédure est « spécification nécessaire » (RFC 8126). Si on veut des clés non normalisées, on doit les préfixer par temp-.

RESINFO est récent et donc pas forcément mis en œuvre dans tous les logiciels DNS que vous utilisez. Un dig récent fonctionne :


% dig dot.bortzmeyer.fr RESINFO
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34836
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
dot.bortzmeyer.fr.	86369	IN	CNAME	radia.bortzmeyer.org.
radia.bortzmeyer.org.	86369	IN	RESINFO	"qnamemin" "infourl=https://doh.bortzmeyer.fr/policy"

;; Query time: 0 msec
;; SERVER: 192.168.2.254#53(192.168.2.254) (UDP)
;; WHEN: Sun Aug 18 08:15:55 UTC 2024
;; MSG SIZE  rcvd: 142

Si vous avez un dig plus ancien, il faudra demander TYPE261 et pas RESINFO. Notez que, physiquement, un RESINFO est juste un TXT, ce qui facilite sa mise en œuvre (dans le futur dnspython, la classe RESINFO hérite simplement de TXT).

Trouve-t-on beaucoup de RESINFO dans la nature ? Aucun des grands résolveurs DNS publics ne semble en avoir. Mais, comme vous le voyez plus haut, j'en ai mis un dans mon résolveur. Le logiciel du serveur primaire ne connaissant pas encore ce type, j'ai utilisé la technique des types inconnus du RFC 3597 :

; Pour le résolveur public :
; Type RESINFO (RFC 9606), enregistré à l'IANA mais pas encore connu des logiciels
radia IN TYPE261 \# 50 08716e616d656d696e 28696e666f75726c3d68747470733a2f2f646f682e626f72747a6d657965722e66722f706f6c696379
  

Cette série de chiffres hexadécimaux ayant été produite à partir de la version texte et du programme text-to-unknown-txt-type.py. On note que, comme ce résolveur public n'est pas menteur, je n'indique pas d'EDE (Extended DNS Errors, RFC 8914).


Téléchargez le RFC 9606


L'article seul

RFC 9581: Concise Binary Object Representation (CBOR) Tags for Time, Duration, and Period

Date de publication du RFC : Août 2024
Auteur(s) du RFC : C. Bormann (Universität Bremen TZI), B. Gamari (Well-Typed), H. Birkholz (Fraunhofer SIT)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF cbor
Première rédaction de cet article le 17 août 2024


Ce RFC ajoute au format de données binaire CBOR la possibilité de stocker des données temporelles plus détaillées, incluant par exemple l'échelle utilisée (UTC ou TAI), ou bien ayant une précision supérieure.

Petit rappel : CBOR est normalisé dans le RFC 8949, il incluait deux étiquettes pour les données temporelles, permettant d'indiquer date et heure en format lisible par un humain, et sous forme d'un nombre de secondes depuis l'epoch, avec une résolution d'une seconde. Le RFC 8943 y ajoute les dates (sans indication de l'heure). Au passage, le concept d'étiquette en CBOR est normalisé dans la section 3.4 du RFC 8949.

Notre nouveau RFC 9581 ajoute :

  • Une étiquette, 1001, pour un temps étendu, sous forme d'un dictionnaire CBOR. La clé 1 doit être présente, pour indiquer le temps de base, des clés négatives servent pour indiquer des fractions de seconde, la clé -1 sert pour l'échelle (UTC ou TAI, notamment).
  • Une étiquette, 1002, pour indiquer une durée. C'est également un dictionnaire CBOR.
  • Une étiquette, 1003, pour indiquer une période, représentée par une date de début et une date de fin.

Ces nouvelles étiquettes ont été ajoutées au registre des étiquettes CBOR. Les clés possibles pour les dictionnaires indiquant les temps étendus sont dans un nouveau registre à l'IANA. Ajouter une entrée à ce registre nécessite un RFC et un examen par un expert.

Un service sur ce blog, https://www.bortzmeyer.org/apps/date-in-cbor permet d'obtenir plusieurs valeurs utilisant ces formats. Si nous utilisons le gem Ruby cbor-diag, nous voyons :


% curl -s https://www.bortzmeyer.org/apps/date-in-cbor | cbor2diag.rb  
["Current date in CBOR, done with Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] and the flunn library <https://github.com/funny-falcon/flunn>", 
  0("2024-04-17T14:21:07Z"), 
  1(1713363667), 
  100(19830), 
  1004("2024-04-17"), 
  1001({1: 1713363667, -1: 0, -9: 193986759}), 
  1001({1: 1713363704, -1: 1}), 
  "Duration since boot: ", 
  1002({1: 1742903})]

On voit alors successivement :

  • Les deux valeurs étiquetées 0 et 1 du RFC 8949 et les deux valeurs étiquetées 100 et 1004 du RFC 8943.
  • Puis les nouveautés de notre RFC.
  • D'abord, un temps étendu étiqueté 1001. Le dictionnaire a trois éléments, celui de clé 1 est la date et heure, celui de clé -1 indique qu'il s'agit d'un temps UTC, celui de clé -9 indique qu'il s'agit de nanosecondes (-3 : millisecondes, -6 : microsecondes, etc). On a ainsi une meilleure résolution.
  • Un autre temps étendu est en TAI (la clé -1 a la valeur 1) et vous voyez qu'il est situé 37 secondes dans le futur (l'actuel décalage entre UTC et TAI).
  • Une durée, qui est le temps écoulé (en secondes) depuis le démarrage de la machine.
  • On n'indique pas des informations comme la qualité de l'horloge car, franchement, je n'ai pas vraiment compris comment elle était représentée.

Question programmation, le service a été écrit en Python. Ce langage a une fonction time_ns, qui permet d'obtenir les nanosecondes. Pour le TAI, cela a été un peu plus difficile, la machine doit être configurée spécialement.


Téléchargez le RFC 9581


L'article seul

Fiche de lecture : De l'écran à l'émotion

Auteur(s) du livre : Emmanuelle Bermès
Éditeur : École nationale des chartes
978-2-35723-187-0
Publié en 2024
Première rédaction de cet article le 5 août 2024


« Quand le numérique devient patrimoine » est le sous-titre de ce livre consacré à un tour d'horizon complet de la question de la gestion patrimoniale des documents numériques. L'auteure s'appuie notamment sur son importance expérience à la BnF. Aucune nostalgie du papier dans ce livre tourné vers l'avenir.

Le patrimoine, pour une bibliothèque du début du XXe siècle, c'était facile à définir. C'étaient des objets physiques, notamment des livres, qu'il fallait cataloguer, stocker, préserver du feu ou de l'eau, et mettre à la disposition des lecteurices. Mais le numérique a bouleversé le travail des bibliothèques. Il faut récolter et stocker ces « objets » numériques, les préserver des changements technologiques qui risquent de les rendre illisibles, les cataloguer, les mettre à disposition. Leur nombre, à lui seul, pose un sacré défi. Et la définition même d'objet est difficile. Par exemple, archiver cet article que vous êtes en train de lire, c'est quoi ? Archiver le code HTML (c'est assez loin du vécu de la lectrice ou du lecteur de ce blog) ? L'image que montre le navigateur (non structurée et difficile à analyser, par exemple à des fins de cataloguage) ? Et si je modifie cet article, faut-il garder toutes les versions, même quand je n'ai changé qu'une virgule ? Emmanuelle Bermès, l'auteure du fameux Figoblog, expose toutes ces questions et les choix à faire.

Si on a pu s'agacer au début du « retard à l'allumage » de certains institutions, notamment en France, face au numérique, si on a pu ricaner des déclarations enflammées d'intellectuels médiatiques proclamant, par exemple, qu'on ne pouvait pas ressentir d'émotion en lisant sur écran, cela fait quand même longtemps que les bibliothèques nationales, spécialistes de la conservation à très long terme de toute sorte de documents, ont pris à bras-le-corps la question du patrimoine numérique. C'est cette prise de conscience, ces débats, et les actions qui ont suivi, que raconte Emmanuelle Bermès dans ce passionnant livre. Si vous vous souvenez de la diatribe de Jean-Noël Jeanneney dans Le Monde contre le projet de numérisation des livres par Google, vous retrouverez avec intérêt les débats de l'époque. Et, si vous ne les avez pas vécu, vous aurez un excellent résumé des étapes par lesquelles la BnF est passée (par exemple au sujet de Gallica ou du dépôt légal). L'actuelle BnF est assez loin de certains projets qui avaient été conçus à l'époque du Minitel !

Bref, contrairement à ce qu'on lit parfois sous le clavier de gens qui ne se sont pas renseignés, le patrimoine numérique existe, et de nombreuses personnes travaillent à le gérer et à le préserver. C'est bien sûr le cas de l'excellent service Internet Archive (l'auteure mentionne les attaques d'éditeurs comme Hachette contre ce service). Mais c'est aussi le cas du dépôt légal en France et dans de nombreux autres pays. En parlant de dépôt légal, ce blog est archivé de longue date par la BnF, et on voit ici dans le journal du serveur HTTP, une des visites du ramasseur de la BnF :

194.199.7.22:10401 - - [03/Jul/2024:14:36:57 +0000] "GET /opendns-quitte-france.html HTTP/1.0" 200 18036 \
      "https://next.ink/wp-json/wp/v2/posts/142507" \
      "Mozilla/5.0 (compatible; bnf.fr_bot; +https://www.bnf.fr/fr/capture-de-votre-site-web-par-le-robot-de-la-bnf)" \
      www.bortzmeyer.org TLS
  

On notera le suivi des liens (à partir d'un article de Next), et le fait que le ramasseur se présente, et indique où obtenir tous les détails sur l'activité du robot. Bref, toutes les bêtises que je peux écrire ici sont archivées, sinon pour l'éternité, du moins pour longtemps. (Après tout, les historiens actuels sont ravis quand ils trouvent une tablette sumérienne avec une liste de commissions à faire.)

L'auteure se penche également sur les émotions que suscite le patrimoine (avec hommage à Aaron Swartz) et sur les techniques futures. L'IA aidera t-elle à cataloguer tous les documents sauvegardés ? Pas tant qu'un logiciel classera un tableau comme « femme ayant un bébé dans les bras » (exact, mais sans intérêt) au lieu de « Vierge à l'enfant »…


L'article seul

Le résolveur DNS public de Wikimédia

Première rédaction de cet article le 2 août 2024


Encore un résolveur DNS public ? Oui, mais c'est une bonne chose, il en faut le plus possible, pour éviter de dépendre d'un petit nombre d'acteurs. Et celui-ci est géré par la fondation Wikimédia.

Rien n'est plus agaçant que les gens qui croient s'y connaitre et qui, à chaque panne, censure ou autre problème mettant en jeu (croient-ils) le DNS, répondent tout de suite qu'il faut utiliser 8.8.8.8 (Google) ou parfois un autre résolveur étatsunien comme 1.1.1.1 ou 9.9.9.9. Non seulement il est mauvais, pour la vie privée, d'envoyer toutes ses requêtes DNS aux USA mais il y a aussi un problème plus stratégique. Si tout le monde dépend d'un petit nombre d'acteurs, nous devenons tous vulnérables à des changements de politique, de tarification, ou à une offensivce de la censure (qui a d'ailleurs commencé à frapper les résolveurs publics). Il faut au contraire une grande diversité de résolveurs DNS. Saluons donc le travail de la fondation Wikimédia, qui a un résolveur public, « Wikimedia DNS ».

Je vous recommande la documentation très claire et très détaillée de ce service. Ce résolveur est bien noté comme expérimental et sans garantie, mais, si vous lisez les petites lettres des CGU, c'est pareil pour tous les autres. Au moins, il est géré par une association et pas par une personne unique (comme l'est le mien) donc il est moins dépendant d'un individu.

Notez aussi qu'il n'est accessible qu'en DoT et DoH, ce qui est raisonnable techniquement, et normal pour un service surtout destiné à contourner la censure (qui aurait beau jeu de tripoter des réponses envoyés en clair). En traditionnel UDP en clair, on n'aura donc pas de réponse :


% dig @185.71.138.138 ratzeburg.de
;; communications error to 185.71.138.138#53: timed out
;; communications error to 185.71.138.138#53: timed out
;; communications error to 185.71.138.138#53: timed out

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> @185.71.138.138 ratzeburg.de
; (1 server found)
;; global options: +cmd
;; no servers could be reached

  

Mais le serveur marche bien, ici en DoT :


% dig +tls @185.71.138.138 ratzeburg.de

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> +tls @185.71.138.138 ratzeburg.de
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16221
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;ratzeburg.de.		IN A

;; ANSWER SECTION:
ratzeburg.de.		3600 IN	A 213.178.85.153

;; Query time: 56 msec
;; SERVER: 185.71.138.138#853(185.71.138.138) (TLS)
;; WHEN: Fri Aug 02 13:29:26 CEST 2024
;; MSG SIZE  rcvd: 57

  

On peut donc l'utiliser directement depuis les systèmes qui peuvent utiliser DoT (Android, par exemple) ou indirectement via un résolveur local comme Unbound qui fera suivre à Wikimédia DNS. Voici un exemple de configuration de Unbound pour cela :

forward-zone:
 	name: "."

	# Wikimedia DNS. On authentifie le nom dans le certificat
	# (émis par Let's Encrypt) donc, sur Debian/Ubuntu, ne pas
	# oublier le "tls-system-cert: yes" dans le bloc "server:".
	forward-addr: 185.71.138.138#wikimedia-dns.org
	
        forward-tls-upstream: yes
  

On notera que, comme tous les résolveurs sérieux, il valide avec DNSSEC :


% dig +tls @185.71.138.138 denic.de
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30888
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
                   ^^
                   Authentic Data
…
;; ANSWER SECTION:
denic.de.		3578	IN	A	81.91.170.12
…

  

Et la répartition des instances de ce serveur dans le monde ? Regardons avec les sondes RIPE Atlas :

% blaeu-resolve --nameserver 2001:67c:930::1 --nsid --type A --tls \
     --requested 200 ratzeburg.de
Nameserver 2001:67c:930::1
[213.178.85.153 NSID: doh3004;] : 45 occurrences 
[213.178.85.153 NSID: doh1001;] : 10 occurrences 
[213.178.85.153 NSID: doh3003;] : 52 occurrences 
[213.178.85.153 NSID: doh2001;] : 6 occurrences 
[TIMEOUT] : 7 occurrences 
[213.178.85.153 NSID: doh6001;] : 14 occurrences 
[213.178.85.153 NSID: doh1002;] : 11 occurrences 
[213.178.85.153 NSID: doh6002;] : 16 occurrences 
[213.178.85.153 NSID: doh5002;] : 12 occurrences 
[213.178.85.153 NSID: doh5001;] : 8 occurrences 
[213.178.85.153 NSID: doh7002;] : 2 occurrences 
[213.178.85.153 NSID: doh4002;] : 5 occurrences 
[213.178.85.153 NSID: doh4001;] : 6 occurrences 
[213.178.85.153 NSID: doh7001;] : 1 occurrences 
[TUCONNECT (may be a TLS negotiation error or a TCP connection issue)] : 1 occurrences 
Test #76486532 done at 2024-08-02T11:40:00Z

On voit qu'on a plusieurs NSID (RFC 5001), ce qui indique que le résolveur est anycasté, sur l'infrastructure de la fondation (qui héberge notamment Wikipédia). Une meilleure preuve est donnée en regardant la latence depuis divers pays : qu'on soit en Europe ou en Amérique, on obtient des RTT très courts, ce qui n'arriverait pas s'il existait une seule instance physique du serveur.


L'article seul

RFC 9580: OpenPGP

Date de publication du RFC : Juillet 2024
Auteur(s) du RFC : P. Wouters (Aiven), D. Huigens (Proton AG), J. Winter (Sequoia-PGP), Y. Niibe (FSIJ)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF openpgp
Première rédaction de cet article le 1 août 2024
Dernière mise à jour le 2 août 2024


Le logiciel PGP est synonyme de cryptographie pour beaucoup de gens. Un des plus anciens et des plus utilisés pour les fonctions de confidentialité mais aussi d'authentification. Le format de PGP, OpenPGP, est normalisé dans ce RFC, qui remplace le RFC 4880 (il n'y a pas de changement crucial, juste une mise à jour longtemps attendue).

PGP a vu son format de données normalisé pour la première fois en août 1996, dans le RFC 1991. Cette norme a été révisée par la suite, dans le RFC 2440, puis le RFC 4880, puis par des RFC ponctuels (comme les RFC 5581 et RFC 6637, désormais inclus) et notre RFC est la dernière version, qui synthétise tout. Sa gestation a été longue et douloureuse et a suscité des controverses, menant à un projet concurrent, LibrePGP (qui prévoit son propre RFC, actuellement draft-koch-librepgp, que j'avoue n'avoir pas lu).

Cette normalisation permet à diverses mises en œuvre de PGP d'interopérer. La plus connue aujourd'hui est la seule libre, GNU Privacy Guard (qui n'existait pas encore au moment de la publication du premier RFC). Il ne faut donc pas confondre le logiciel PGP, écrit à l'origine par Phil Zimmermann, et qui est non-libre, avec le format OpenPGP que décrit notre RFC (cf. section 1.1) et que des logiciels autres que PGP peuvent lire et écrire.

Le principe du chiffrement avec PGP est simple. Une clé de session (le terme est impropre puisqu'il n'y a pas de session au sens de TLS mais c'est celui utilisé par le RFC) est créée pour chaque destinataire, elle sert à chiffrer le message et cette clé est chiffrée avec la clé publique du destinataire (section 2.1 du RFC).

Pour l'authentification, c'est aussi simple conceptuellement. Le message est condensé et le condensé est chiffré avec la clé privée de l'émetteur (section 2.2 du RFC).

Le format OpenPGP permet également la compression (qui améliore la sécurité en supprimant les redondances) et l'encodage en Base64 (RFC 4648), baptisé ASCII armor, pour passer à travers des logiciels qui n'aiment pas le binaire (la section 6 détaille cet encodage).

La section 3 explique les éléments de base utilisés par le format PGP. L'un des plus importants est le concept d'entier de grande précision (MPI pour Multi-Precision Integers), qui permet de représenter des entiers de très grande taille, indispensables à la cryptographie, sous forme d'un doublet longueur + valeur.

Enfin les sections 4 et 5 expliquent le format lui-même. Un message PGP est constitué de paquets (rien à voir avec les paquets réseau). Chaque paquet a un type, une longueur et un contenu. Par exemple, un paquet de type 1 est une clé de session chiffrée, un paquet de type 2 une signature, un paquet de type 9 du contenu chiffré, etc.

La section 7 du RFC décrit un type de message un peu particulier, qui n'obéit pas à la syntaxe ci-dessus, les messages en clair mais signés. Ces messages ont l'avantage de pouvoir être lus sans avoir de logiciel PGP. Ils nécessitent donc des règles spéciales.

On notera que gpg permet d'afficher les paquets présents dans un message PGP, ce qui est pratique pour l'apprentissage ou le débogage. Voyons un exemple avec un fichier test.txt de 17 octets, signé mais non chiffré (j'ai un peu simplifié la sortie du logiciel) :

% gpg --list-packets test.gpg 
:compressed packet: algo=2
:onepass_sig packet: keyid 3FA836C996A4A254
	version 3, sigclass 0x00, digest 10, pubkey 1, last=1
:literal data packet:
	mode b (62), created 1721800388, name="test.txt",
	raw data: 17 bytes
:signature packet: algo 1, keyid 3FA836C996A4A254
	version 4, created 1721800388, md5len 0, sigclass 0x00
	digest algo 10, begin of digest 2b d9
	hashed subpkt 33 len 21 (issuer fpr v4 C760CAFC6387B0E8886C823B3FA836C996A4A254)
	hashed subpkt 2 len 4 (sig created 2024-07-24)
	subpkt 16 len 8 (issuer key ID 3FA836C996A4A254)
	data: [4096 bits]

Malheureusement, gpg n'affiche pas les valeurs numériques des types, telles que listées par le RFC. Mais les noms qu'il utilise sont les mêmes que dans le RFC, on peut donc facilement trouver la section qui explique ce qu'est un "onepass_sig packet" (section 5.4).

Avec un message chiffré, on obtient :


% gpg --list-packets test.txt.gpg
gpg: encrypted with 4096-bit RSA key, ID 9045E02757F02AA1, created 2014-02-09
      "Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>"
gpg: encrypted with 2048-bit RSA key, ID 516CB37B336525BB, created 2009-12-15
      "ISC Security Officer <security-officer@isc.org>"
gpg: decryption failed: No secret key
:pubkey enc packet: version 3, algo 1, keyid 516CB37B336525BB
	data: [2046 bits]
:pubkey enc packet: version 3, algo 1, keyid 9045E02757F02AA1
	data: [4096 bits]
:encrypted data packet:
	length: 78
	mdc_method: 2

Conformément au principe d'agilité cryptographique (RFC 7696), le format OpenPGP n'est pas lié à un algorithme cryptographique particulier, et permet d'en ajouter de nouveaux. La section 15 détaille comment demander à l'IANA d'ajouter de nouveaux paramètres dans les registres PGP.

L'annexe B, quant à elle, énumère les principaux changements depuis le RFC 4880. Ce dernier RFC a été publié il y a plus de seize ans mais son remplacement par notre nouveau RFC 9580 a été une opération longue et difficile, et les changements se sont accumulés (Daniel Huigens en a fait un bon résumé). Ceci dit, le format OpenPGP ne change pas radicalement, et l'interopérabilité avec les anciens programmes est maintenue. Parmi les principales modifications :

  • des nouveaux algorithmes cryptographiques de signature comme Ed25519, ou bien ECDSA avec les courbes Brainpool (RFC 5639),
  • des nouveaux algorithmes cryptographiques de chiffrement, comme X25519 ; comme pour ceux de signature, ils étaient parfois mentionnés dans le RFC 4880 sans que leur utilisation dans OpenPGP soit complètement spécifiée, et parfois avaient été intégrés via un RFC spécifique, comme le RFC 6637, sur certains algorithmes à courbe elliptique,
  • des nouveaux modes pour le chiffrement intègre, comme GCM (nouveaux pour OpenPGP, mais anciens en cryptographie),
  • des nouvelles fonctions de dérivation de clé comme Argon2 (RFC 9106) ou de condensation comme SHA-3,
  • au contraire, certains algorithmes sont désormais marqués comme dépassés et ne devant plus être utilisés pour de nouveaux messages ; c'est le cas de DSA, ElGamal, MD5, SHA-1… (rappelez-vous que PGP peut avoir à lire des messages anciens et qu'on ne peut donc pas retirer purement et simplement ces algorithmes, d'autant plus qu'autrefois ils étaient parfois les seuls obligatoires pour une mise en œuvre standard d'OpenPGP),
  • nouvelle version (version 6) pour plusieurs types de paquets,
  • réduction de l'en-tête de la protection ASCII des messages (OpenPGP est du binaire mais peut être transcrit en ASCII armor, par exemple pour le courrier électronique) ; vous ne verrez plus le « Version: » dans cet en-tête,
  • redressement de la terminologie, qui était parfois trop floue.

Enfin, un grand nombre d'errata ont été traités (la liste complète est dans l'annexe D).


Téléchargez le RFC 9580


L'article seul

Fiche de lecture : Des Martiens au Sahara

Auteur(s) du livre : Jean-Loïc Le Quellec
Éditeur : Édition du Détour
979-10-97079-23-9
Publié en 2023
Première rédaction de cet article le 31 juillet 2024


Des Martiens sont venus au Sahara pour se faire dessiner sur des parois rocheuses, tout le monde sait cela. Et des squelettes de géants ont été trouvés en Arabie saoudite, confirmant le Coran. De l'autre côté du globe, des astronautes extra-terrestres chassaient le dinosaure avec des haches au Pérou, en prenant le temps de construire des monuments, les peuples indigènes étant jugés incapables d'avoir réalisé de telles constructions. Vous y croyez ? Alors, c'est peut-être une bonne idée de lire ce livre, recueil d'articles sur les plus beaux mensonges et illusions en archéologie.

Il s'agit d'une réédition de l'ouvrage, avec mise à jour (lorsque l'auteur parle du scientifique-génial-qui-trouve-tout-seul-le-remède-mais-les-méchants-ne-veulent-pas-en-entendre-parler, les exemples du sida et du cancer ont été rejoints par la covid …). Il signale aussi le récent et scandaleux « documentaire » Netflix « À l'aube de notre histoire », que Netflix ose présenter comme un vrai documentaire alors qu'il s'agit du délire complotiste et raciste d'un menteur connu (la moitié du documentaire, que j'ai regardé, est faite de scènes où ce menteur se met en scène sur des sites archéologiques, alors qu'il n'a fait aucune recherche et rien découvert). La « thèse » de l'escroc est que tous les monuments antiques du monde ont été construits par une civilisation avancée et disparue. Si le documentaire reste prudent sur cette civilisation, dans ses livres, l'escroc n'hésite pas à dire qu'il s'agissait de Blancs, et insiste que ces monuments n'ont pas pu être construits par les indigènes. (Netflix a fait d'autres « documentaires » mensongers et complotistes comme celui sur le MH370.)

J'avais découvert Le Quellec avec son excellent livre détaillant la façon dont ignorance et racisme s'étaient conjugués pour produire une analyse erronée de la Dame Blanche (livre très recommandé !). Ici, il donne de nombreux autres exemples.

Il y a des escroqueries délibérées, faites pour des raisons monétaires ou politiques. Mais il y a aussi de nombreux cas où on se demande si le découvreur n'était pas sincère, s'auto-illusionnant, à la fois par manque de connaissances scientifiques et par désir d'arriver à tout prix au résultat voulu (confirmer ses préjugés, par exemple). On retrouvera donc dans ce livre les crânes de cristal, les pierres d'Ica, le livre de Mormon ou les interprétations délirantes sur les bâtisseurs de tertres (ces bâtisseurs sont bien réels, mais ils ne sont ni atlantes, ni extra-terrestres). Mais on n'aura pas les momies tridactyles, on ne peut pas tout traiter. Chaque cas est analysé en détail, son histoire, le contexte, le rôle des différentes personnes impliquées, chacune abordant la question avec son passé et ses préjugés.

Bref, un livre à lire pour creuser la variété des tromperies, mensonges, et dérapages. Je suis quand même un peu triste de découvrir qu'il y a peu d'innovation dans le pipeautage, les faux archéologues reprennent très souvent des légendes qui avaient déjà été analysées et démenties au XIXe siècle…


L'article seul

RFC 9619: In the DNS, QDCOUNT is (usually) One

Date de publication du RFC : Juillet 2024
Auteur(s) du RFC : R. Bellis (ISC), J. Abley (Cloudflare)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 25 juillet 2024


Dans un message DNS, il y a quatre sections qui peuvent prendre un nombre variable d'enregistrements (resource records). Chaque section est précédée d'un chiffre qui indique ce nombre d'enregistrements. L'une de ces sections indique la question posée. Est-ce que cela a un sens de mettre plusieurs questions dans un message ? Non, répond, ce très court RFC, qui clarifie le RFC 1035 sur ce point.

Regardons une requête DNS avec tshark :


% tshark -V -r  dns.pcap
…
Domain Name System (query)
    Transaction ID: 0x0dfd
    Flags: 0x0120 Standard query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Standard query (0)
…
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 1
    Queries
        wylag.de: type A, class IN
            Name: wylag.de
            [Name Length: 8]
            [Label Count: 2]
            Type: A (Host Address) (1)
            Class: IN (0x0001)
    Additional records
        <Root>: type OPT
            Name: <Root>
            Type: OPT (41)
            UDP payload size: 4096
            Higher bits in extended RCODE: 0x00
            EDNS0 version: 0
            Z: 0x8000
                1... .... .... .... = DO bit: Accepts DNSSEC security RRs
                .000 0000 0000 0000 = Reserved: 0x0000
            Data length: 12
            Option: COOKIE
                Option Code: COOKIE (10)
                Option Length: 8
                Option Data: 93c545f2aaf3f12c
                Client Cookie: 93c545f2aaf3f12c
                Server Cookie: <MISSING>

  

Il s'agit d'une requête, pas d'une réponse, donc il est normal que les sections Answer et Authority soient vides (taille à zéro). La section Additional n'est pas vide car elle contient l'enregistrement EDNS. Et la section Question contient un seul enregistrement, la question (« quelle est l'adresse IPv4 de wylag.de ? »).

Tout le problème traitée par ce RFC est : que se passe t-il si la section Question d'une requête contient plus d'un enregistrement ? Je divulgâche tout de suite : c'est interdit, il ne faut pas. (Pour le cas des requêtes/réponses ordinaires, avec l'opcode 0 ; d'autres messages DNS peuvent avoir des règles différentes.) La principale raison pour cette interdiction est que, dans la réponse, certains champs sont globaux à toute la réponse (comme le code de réponse, le rcode) et on ne peut donc pas se permettre d'accepter des questions qui risqueraient de nécessiter des réponses différentes. Désormais, un serveur DNS qui voit passer une requête avec un nombre de questions supérieur à 1 doit répondre avec le code de retour FORMERR (format error).

Le RFC 1035, la norme originelle, traitait ce point mais restait flou.

Il y avait une autre façon de régler le problème, en imposant que, s'il y a plusieurs questions, toutes portent sur le même nom de domaine. Cela aurait réglé le doute sur le code de retour et aurait pu être pratique pour des cas comme la demande simultanée de l'adresse IPv4 et IPv6. Mais cette solution a été écartée au profit de la solution plus simple qui était d'interdire les questions multiples. (Et, de toute façon, on ne peut pas garantir que le code de retour sera le même pour tous les types, même si le nom est le même. Pensez aux serveurs DNS générant dynamiquement les données.)


Téléchargez le RFC 9619


L'article seul

Le nouveau type de données DNS WALLET

Première rédaction de cet article le 19 juillet 2024


Contrairement au cliché mille fois répété (mais faux), le DNS ne sert pas qu'à « traduire des noms de domaine en adresses IP ». Il est d'un usage général et permet de récupérer, indexées par un nom de domaine, diverses informations. Un nouveau type d'information vient d'être officiellement enregistré, WALLET, pour indiquer l'adresse d'un portefeuille de cryptomonnaie.

La capacité du DNS à résoudre un nom de domaine en divers types d'informations vient d'un champ des requêtes et réponses DNS, le type (ou, en plus long, le RR type, pour Resource Record type). Décrit dans la section 3.2.2 du RFC 1035, ce type peut prendre des valeurs diverses : AAAA pour les adresses IP, SVCB pour les serveurs d'un service donné, LOC pour une position, TXT pour du texte libre, etc.

Il est important de noter que cette liste des types possibles n'est pas figée. Elle est enregistrée dans un registre IANA et on peut ajouter des types à ce registre, en suivant la procédure décrite dans le RFC 6895. Cette procédure est délibérement très légère : le demandeur documente le nouveau type, envoie la demande à l'IANA, celle-ci la fait examiner par un expert (actuellement Ólafur Guðmundsson) et s'il n'y a pas de problèmes, le nouveau type est enregistré. Bien que la procédure soit libérale, on ne peut pas dire qu'il y ait eu une bousculade depuis la sortie du RFC 6895, la plupart des types enregistrés ayant suivi un chemin plus classique de normalisation.

Mais le nouveau WALLET, désormais ajouté au registre IANA, a utilisé le chemin simple ; une documentation, un examen par l'expert et hop, c'est enregistré. Comme les types ont un numéro en plus de leur nom (c'est ce numéro qui figure dans les paquets DNS), le 262 a été alloué. Que contient un enregistrement DNS de type WALLET ? Deux champs, une chaine de caractères qui identifie la cryptomonnaie utilisée (BTC pour Bitcoin, ETH pour Ethereum, etc) et une autre chaine de caractères qui contient l'adresse d'un compte.

L'encodage dans les paquets est identique à celui des enregistrements de type TXT : une suite de chaines de caractères est encodée en un octet qui indique la longueur de la chaine puis la suite d'octets de la chaine. Ainsi, "BTC" (pour Bitcoin) sera encodé {3, 66, 84, 67}, les trois derniers octets étant les codes ASCII.

J'ai ainsi ajouté au DNS mon adresse Bitcoin, sous bortzmeyer.fr. Mais attention, comme le type WALLET est récent (créé le 21 juin 2024), la plupart des logiciels ne le connaissent pas. Pour le mettre dans le fichier de zone du serveur primaire, j'ai dû utiliser la méthode des « types inconnus » du RFC 3597 :

@ IN	TYPE262	\# 39 03425443 223148744E4A365A465563397975397532714177423474476447775051617351476178
  

(39 octets, le premier groupe fait trois octets, les trois lettres de "BTC", regardez la table ASCII. Vous pouvez utiliser le script Python text-to-unknown-txt-type.py pour produire cet encodage.) Et c'est également ainsi que dig l'affichera (le type WALLET n'étant pas connu, il a fallu donner son numéro, 262) :


% dig bortzmeyer.fr TYPE262
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26302
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
bortzmeyer.fr.		86400 IN TYPE262 \# 39 ( 03425443223148744E4A365A46556339797539753271
				4177423474476447775051617351476178 )
…

  

Pour le formater plus joliment, en attendant que dig soit mis à jour, j'ai écrit un petit script en Python (utilisant la bibliothèque dnspython) :

% wallet-dns.py bortzmeyer.fr
bortzmeyer.fr
Code: BTC ; Address: 1HtNJ6ZFUc9yu9u2qAwB4tGdGwPQasQGax
  

Et voilà, l'adresse est joliment affichée. (Une gestion assez minimale de ce type est en cours de développement dans dnspython.)

PS : il existe aussi cette alternative.


L'article seul

RFC 9537: Redacted Fields in the Registration Data Access Protocol (RDAP) Response

Date de publication du RFC : Mars 2024
Auteur(s) du RFC : J. Gould, D. Smith (VeriSign), J. Kolker, R. Carney (GoDaddy)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF regext
Première rédaction de cet article le 14 juillet 2024


RDAP est le protocole recommandé pour accéder aux données sociales sur un nom de domaine, comme le nom du titulaire ou son adresse postale. Pour d'évidentes raisons de vie privée, certains registres ne renvoient pas la totalité de l'information dont ils disposent. Que doit-on mettre dans RDAP dans ce cas ? La question n'était pas tranchée et chaque registre faisait différemment. Désormais, il existe une solution normalisée.

Au passage, oui, d'accord, il n'y a pas que RDAP pour obtenir les données sociales (cet article vous en indiquera d'autres). Mais c'est le service le plus moderne et le plus adapté aux programmeur·ses. Contacté en HTTPS, le serveur RDAP va renvoyer du JSON que le client n'aura plus qu'à filtrer et formatter. Voici par exemple une partie de la réponse RDAP obtenue en se renseignant sur nouveaufrontpopulaire.fr :

% curl -s https://rdap.nic.fr/domain/nouveaufrontpopulaire.fr | jq
…
          [
            "fn",
            {},
            "text",
            "Parti Socialiste"
          ],
          [
            "org",
            {},
            "text",
            "Parti Socialiste"
          ],
          [
            "adr",
            {},
            "text",
            [
              "",
              "",
              "99 Rue Moliere",
              "Ivry-sur-Seine",
              "",
              "94200",
              "FR"
            ]
          ],
…
  

Ici, il s'agit d'une personne morale donc les données sont toutes envoyées. Et s'il s'agissait d'une personne physique, pour laquelle la loi Informatique & et Libertés s'applique, depuis 1978 ? La solution évidente est de ne pas envoyer les données qu'on ne veut pas diffuser mais attention, il y a un piège, il ne faut pas casser la syntaxe JSON. Par exemple, RDAP utilise (c'est en cours de changement, cf. RFC 9553) jCard pour formater les adresses (RFC 7095) et les champs dans jCard ne sont pas étiquetés, c'est leur position dans le tableau qui indique leur rôle (c'est un des nombreux inconvénients de jCard). On ne peut donc pas supprimer, par exemple, la rue, en indiquant :

[
            "adr",
            {},
            "text",
            [
              "",
              "",
              "Ivry-sur-Seine",
              "",
              "94200",
              "FR"
            ]
],
          [
            "email",
            {},
            "text",
            "e5d92838d5f0268143ac47d86880b5f7-48916400@contact.gandi.net"
          ],

Car, alors, on ne saurait plus si "Ivry-sur-Seine" est la rue ou bien la ville.

Le principe de notre RFC est donc : si on peut, retirer le membre JSON. Si on ne peut pas (cas du tableau de taille fixe), mettre une valeur vide ou null.

Petit point de terminologie : comment traduire le redacted du titre ? « Censuré » est inadapté (l'intervention ne vient pas d'un tiers mais d'une des deux parties). Je vais dire « élidé », mais « caviardé », « biffé » et « expurgé » sont également de bonnes solutions. Le nom correspondant est « élision ». Évidemment, il ne faut surtout pas dire « anonymisé », il n'y a rien d'anonyme ici, puisque le registre connait toute l'information, il refuse simplement de la diffuser.

La section 1 du RFC expose les grands principes de l'élision. Elle explique notamment qu'en cas d'élision, il faut ajouter un membre (nommé redacted) à la réponse JSON, expliquant les raisons et utilisant le langage JSONPath (RFC 9535) pour désigner de manière formelle la partie élidée.

Compte-tenu des contraintes sur la syntaxe de la réponse JSON (RFC 9083), le RFC normalise quatre façons d'élider (section 3) :

  • Suppression d'un champ, si possible (c'est la méthode préférée). Cela marche dans la plupart des cas. Par exemple, si on ne veut pas publier le titulaire d'un domaine, on ne l'inclut pas dans la réponse, point.
  • Mettre une valeur vide. Quand les contraintes de syntaxe empêchent de supprimer complètement un champ, on lui met une valeur vide. C'est notamment nécessaire pour les tableaux que jCard utilise abondamment : le retrait d'un champ casserait le tableau, qui est censé avoir un nombre d'élements fixe.
  • Une valeur trop détaillée peut être remplacée par une valeur partielle. L'adresse "label":"123 Maple Ave\nSuite 901\nVancouver BC\nCanada" (un exemple du RFC 7095) peut être remplacée par une valeur moins précise comme "label":"Vancouver\nBC\nCanada\n".
  • Enfin, la dernière méthode est de remplacer une valeur par une autre, par exemple une adresse de courrier par une adresse qui masque la vraie, comme e5d92838d5f0268143ac47d86880b5f7-48916400@contact.gandi.net dans l'exemple plus haut.

Et le RFC insiste qu'il ne faut pas utiliser de texte bidon (« XXX », « lorem ipsum dolor » ou « Ano Nymous ») car ce texte ne correspond pas forcément aux règles de syntaxe du champ (et, j'ajoute, peut être difficile à identifier pour le lecteur, qui peut ne pas avoir la référence).

Pour la première méthode, la suppression d'un champ, si on supprime le titulaire, on aura un membre nommé redacted (élidé) ajouté ainsi :

    "redacted": [
     {
       "name": {
         "description": "Remove registrant"
       },
       "prePath": "$.entities[?(@.roles[0]=='registrant')]",
       "method": "removal"
     }
     ]
  

Notez le (difficile à lire) code JSONPath $.entities[?(@.roles[0]=='registrant')].

Le deuxième cas, celui d'une valeur vide, donnerait, pour le cas où on supprime juste le nom du titulaire (qui est en position 1 dans le jCard, et son nom en position 3 - sachant qu'on part de 0) :

   [
     "fn",
     {},
     "text",
     ""
   ]
   …
      "redacted": [
     {
       "name": {
         "description": "Registrant Name"
       },
       "postPath": "$.entities[?(@.roles[0]=='registrant')].
         vcardArray[1][?(@[0]=='fn')][3]",
       "pathLang": "jsonpath",
       "method": "emptyValue",
       "reason": {
         "description": "Server policy"
       }
     }
     ]
     

Troisième technique d'élision, réduire une valeur. Le redacted devient :

   
   "redacted": [
     {
       "name": {
         "description": "Home Address Label"
       },
       "postPath": "$.vcardArray[1][?(@[0]=='adr')][1].label",
       "pathLang": "jsonpath",
       "method": "partialValue",
       "reason": {
         "description": "Server policy"
       }
     }
   ]
  

Et pour finir, la quatrième et dernière méthode, le remplacement :

   "redacted": [
     {
       "name": {
         "description": "Registrant Email"
       },
       "postPath": "$.entities[?(@.roles[0]=='registrant')].
                  vcardArray[1][?(@[0]=='email')][3]",
       "pathLang": "jsonpath",
       "method": "replacementValue",
     }
     ]
  

Ce membre appelé redacted est spécifié en détail dans la section 4 du RFC. (Et il est enregistré à l'IANA parmi les extensions RDAP.) Pour signaler qu'il peut apparaitre, le membre rdapConformance de la réponse JSON va l'indiquer :

{
  "rdapConformance": [
    "itNic",
    "redacted",
    "rdap_level_0"
  ],
…

Dès qu'il y a élision, redacted doit être ajouté. Il contient un tableau JSON d'objets, dont les membres peuvent être (seul le premier est obligatoire) :

  • name : un terme qui décrit le champ élidé,
  • prePath et postPath : des expressions JSONPath (RFC 9535) qui dénotent le membre retiré ou modifié,
  • method : la technique d'élision utilisée (suppression, nettoyage, remplacement, etc),
  • reason : texte libre décrivant la raison de l'élision.

Téléchargez le RFC 9537


L'article seul

Passage de mes zones DNS à des signatures à courbes elliptiques

Première rédaction de cet article le 6 juillet 2024


Vous l'avez peut-être remarqué, mes zones DNS personnelles (comme bortzmeyer.org, que vous utilisez pour lire ce blog) viennent de changer d'algorithme de signature cryptographique. RSA a été remplacé par ECDSA.

Pourquoi ce grand remplacement ? Les signatures DNSSEC faites avec ECDSA (RFC 6605) sont plus petites, ce qui peut présenter des avantages dans certains cas (mais ne va évidemment pas diminuer l'empreinte environnementale de mes zones). Mais, surtout, l'avis de la grande majorité des experts en cryptographie (je ne fais pas partie de ces experts, très loin de là, donc je leur fais confiance) est que la cryptographie sur courbes elliptiques, qui est à la base d'ECDSA, est plus sûre, surtout face aux futures évolutions de la cryptanalyse, que le traditionnel RSA. Vous noterez d'ailleurs que beaucoup de zones DNS importantes ont changé, par exemple .com. De même, .fr a migré il y a plusieurs années et c'est uniquement la paresse qui m'avait jusque là empêché d'en faire autant. (La racine du DNS, elle, est toujours en RSA, car il est bien plus compliqué de changer une clé que tous les résolveurs de la planète doivent connaitre, et ce malgré le RFC 5011.)

J'ai un peu hésité à passer à ECDSA car il dépend d'une courbe elliptique, la P-256, conçue par la NSA et normalisée par le NIST, et à utiliser plutôt EdDSA (RFC 8080). Mais, autant tous les résolveurs DNSSEC acceptent aujourd'hui aussi bien ECDSA que RSA, autant Ed25519 reste moins répandu.

Une fois la décision prise, comment faire ? Comme toujours avec le DNS, il faut tenir compte du fait que la réjuvénation n'est pas instantanée. Si on change brutalement les clés qu'on publie, on risque que certains résolveurs aient encore dans leur mémoire des clés qui ne valideront pas les signatures récentes (ou bien le contraire). Que l'on change les clés ou, comme ici, les algorithmes, il faut procéder à ce remplacement (rollover) en intégrant les contraintes temporelles (RFC 6781 et RFC 7583).

Suivre manuellement ces contraintes (ajouter la nouvelle clé, attendre le TTL, ajouter l'enregistrement DS dans la zone parente, attendre qu'il soit publié, attendre le TTL, retirer l'ancien DS, attendre, retirer l'ancienne clé…) est pénible et le risque d'erreur est très élevé. Il faut donc automatiser, ce que j'ai fait. Mes zones DNS personnelles sont gérées avec OpenDNSSEC et c'est donc lui qui a fait tout le travail.

Prenons l'exemple de la zone cyberstructure.fr. DNSviz va nous montrer ses différents états (l'archivage des anciennes mesures et la facilité de navigation dans cet historique font partie des grandes forces de DNSviz). Elle était signée uniquement avec RSA. (Les erreurs signalées par DNSviz sont dues au non-respect du RFC 9276, j'y reviendrai.) Le 17 juin 2024, je change la configuration OpenDNSSEC. Dans ce logiciel, chaque zone gérée l'est selon une politique choisie par l'administrateur système. La politique utilisée, nommée default était d'utilise RSA. Je crée une nouvelle politique, nommée, sans imagination, new. Dans la syntaxe XML du fichier de configuration d'OpenDNSSEC, le fichier kasp.xml contient :


<Policy name="new">
<Description>A new policy with ECDSA</Description>
…
                <Keys>
                        …
                        <!-- Parameters for KSK only -->
                        <KSK>
                                <Algorithm length="512">13</Algorithm>
                                <Lifetime>P3Y</Lifetime>
                                <Repository>SoftHSM</Repository>
                                <ManualRollover/>
                        </KSK>

                        <!-- Parameters for ZSK only -->
                        <ZSK>
                                <Algorithm length="512">13</Algorithm>
                                <Lifetime>P90D</Lifetime>
                                <Repository>SoftHSM</Repository>
                                <!-- <ManualRollover/> -->
                        </ZSK>
                </Keys>
…

  

L'algorithme de numéro 13 est ECDSA (RSA est le numéro 8, cf. le registre IANA). On change ensuite la configuration de la zone (dans zonelist.xml) :


<Zone name="cyberstructure.fr">
    <Policy>new</Policy>
    …

On recharge alors OpenDNSSEC :

% sudo ods-enforcer zonelist import                            
…
Updated zone cyberstructure.fr successfully

Les nouvelles clés ECDSA (rappel : algorithme 13) sont alors créées par OpenDNSSEC :

% sudo ods-enforcer key list --verbose --zone cyberstructure.fr
Keys:
Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:
cyberstructure.fr               KSK      active    2024-06-18 10:53:01      2048  8          2d63a8cc9f68602d5b98f2bcb2714119 SoftHSM     63130
cyberstructure.fr               ZSK      active    2024-06-18 10:53:01      1024  8          b8e16f9a3aad96676ae36cd6fdb955ad SoftHSM     11668
cyberstructure.fr               KSK      publish   2024-06-18 10:53:01      512   13         02e0ddf994431d5fa3d89cdc12f7addd SoftHSM     10825
cyberstructure.fr               ZSK      ready     2024-06-18 10:53:01      512   13         cebc635b489780d2fddf5efabeba5b81 SoftHSM     54500

Elles n'apparaissent pas dans le DNS immédiatement, il faut attendre leur passage en état ready (regardez la colonne Date of next transition). Une fois que c'est fait, DNSviz nous montre le nouvel état, avec pour l'instant les clés ECDSA publiées mais qui ne seront pas utilisées pour la validation. rollover-cs-1.png

Pensez aussi à recharger le signeur d'OpenDNSSEC (ods-signer update --all). Dans le DNS, on note que les deux ZSK (Zone-signing key) signent (même si, pour l'instant, les signatures ECDSA ne servent à rien) :


% dig @ns4.bortzmeyer.org. cyberstructure.fr SOA
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18279
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 8, ADDITIONAL: 1
…
;; ANSWER SECTION:
cyberstructure.fr.	7200 IN	SOA ns4.bortzmeyer.org. hostmaster.bortzmeyer.org. (
				2024061703 ; serial
				7200       ; refresh (2 hours)
				3600       ; retry (1 hour)
				604800     ; expire (1 week)
				3600       ; minimum (1 hour)
				)
cyberstructure.fr.	7200 IN	RRSIG SOA 13 2 7200 (
				20240701143938 20240617155301 54500 cyberstructure.fr.
				CW/V6zSkMn/cC8E2hUHYlaSparKbOgc03CRcbOecTOMY
				HxMTavaExj9fvvkH3srNrP9Kx/VYRQsi4YrjMFH6DA== )
cyberstructure.fr.	7200 IN	RRSIG SOA 8 2 7200 (
				20240701143938 20240617155301 11668 cyberstructure.fr.
				UCskHbeGjx20Bqo+9IyczDaHrEZ83uBYQsjDy/Etqngy
				QeCH1gADMbsl3VaBPHiLDd8MIVkzH2I73/jEUo2R22wq
				KPtSTsGHQ8I2vPff5ylplqJFXVUitiyGcEYVaAtI3hAk
				eijaGI6J3nAdcYuAxFo9Gi+WRCEmTRcL8RZAjCo= )
 

On voit notamment que la signature ECDSA est plus petite, ce qui était une des motivations pour ce remplacement. Et les clés ?



% dig @ns4.bortzmeyer.org. cyberstructure.fr DNSKEY
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51884
;; flags: qr aa rd; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
cyberstructure.fr.	7200 IN	DNSKEY 257 3 8 (
				AwEAAddHCFxVIpXyRRVCBh4zHt22o3ReQzk+Avi5J+c2
				hLnB2zSB7obXWsxj0fZSeyYE4VAClJ5/7TF687gRjVRW
				3cNTsJ9mrQzbLbuxL3nnIKWZRrVKWg9RpKHDul9QL1EC
				trgum18SK9QpRnywZx8kM0zFviu75Df2636wT1YcQZUz
				KDXRE0IGg6r9qGMcq6PXL3woDPoVmv3H7SvXZjlj/2zI
				nMvQo15Y0Y7kO6Epng9qgnJaZeTrTo4OtzIPMSOahFMJ
				YD8AxlsT5yN7lQZSRMJDYjJ1HC+PgyLMnz7y+iwvVLMZ
				6IVr1yeYbCp+inTHi+qn9fRJSIjirWJWb/7sHdk=
				) ; KSK; alg = RSASHA256 ; key id = 63130
cyberstructure.fr.	7200 IN	DNSKEY 256 3 8 (
				AwEAAcGW9K353z/T1ZKstnQ4Y0ricKlmb2DyVEE0Dcrc
				St/fNVdB3g2Y9tlXh9oQH0RzNK2UqIAm2PxmAleeWOZp
				8qzYdtWZj5O/4VXtLkjAwOUuinjaYIfDskcuue/pg+cT
				ilQhXnh/sKktyci4wtFIDZLBL7gYyiZSFrR4DCwcpITr
				) ; ZSK; alg = RSASHA256 ; key id = 11668
cyberstructure.fr.	7200 IN	DNSKEY 257 3 13 (
				zyVnEtBlrgWpNtDUnhPIikEIUaAj+/VwHfC7j1jpWeqa
				fAE04Mx9nXDFhznhDD0uvIFpY3se9wefPddNZJDVCA==
				) ; KSK; alg = ECDSAP256SHA256 ; key id = 10825
cyberstructure.fr.	7200 IN	DNSKEY 256 3 13 (
				s+HVObz03Vzug26yX3KjlyXbpMcCzoD/8CblfTR2zQsi
				e35hf2DBwLarHOCcMpu6X5+FgHMsOwmvaSJH/AzZCA==
				) ; ZSK; alg = ECDSAP256SHA256 ; key id = 54500
cyberstructure.fr.	7200 IN	RRSIG DNSKEY 13 2 7200 (
				20240701061231 20240617155301 10825 cyberstructure.fr.
				EbgfiMIxj2zhVgnAD2MPf4fZ6PZjCT4iZMhMgUb6EK/m
				o8foczgd9PFotvcaaQxaE6rybMiOvhRETbIrX9IeCA== )
cyberstructure.fr.	7200 IN	RRSIG DNSKEY 8 2 7200 (
				20240701061231 20240617155301 63130 cyberstructure.fr.
				qTI+5RbOnuWfpkXgTSiYEv04An19XjxP1vGyYEnD5ao0
				zaexw3yh1xhNGlsqFU1XLkADTilpt1w60qO/9lshE3kD
				eA73s6u03hsrLxL71YjvUEU68pO/iT4LxhpYY0P1gCPX
				rdiM50mYauiSQROnt5UeQ0wJ/Q4NSl4fQrko1cHcymcD
				05JeCS4e2gq7HlCQsn2rTQTwP2A0d9ccYBe02rPziTP4
				HnyEAcBqATHPU1U+yqd5OZLYkJh+mGJTFFHoXfxYSqKu
				6C86KVV5wtrX+bCxcNGrdRiyGI0FSDioXQG7p1+/oLYf
				j6vQnfns9INHEH2uY6P6LdJX4GTFKq3gpg== )

;; Query time: 0 msec
;; SERVER: 2001:4b98:dc0:41:216:3eff:fe27:3d3f#53(ns4.bortzmeyer.org.) (UDP)
;; WHEN: Mon Jun 17 18:53:46 CEST 2024
;; MSG SIZE  rcvd: 1048

Ouf, ça en fait, des données à envoyer. Mais ce n'est que transitoire.

À la prochaine étape (tout se déroule automatiquement et est géré par OpenDNSSEC), la clé ECDSA est prête :

% sudo ods-enforcer key  list --verbose --zone cyberstructure.fr
Keys:
Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:
cyberstructure.fr               KSK      retire    waiting for ds-gone      2048  8          2d63a8cc9f68602d5b98f2bcb2714119 SoftHSM     63130
cyberstructure.fr               ZSK      active    2024-09-15 18:53:01      1024  8          b8e16f9a3aad96676ae36cd6fdb955ad SoftHSM     11668
cyberstructure.fr               KSK      ready     waiting for ds-seen      512   13         02e0ddf994431d5fa3d89cdc12f7addd SoftHSM     10825
cyberstructure.fr               ZSK      active    2024-09-15 18:53:01      512   13         cebc635b489780d2fddf5efabeba5b81 SoftHSM     54500

Maintenant, il va falloir travailler, l'étape suivante ne peut pas être automatisée. Il faut prévenir la zone parente (dans le cas de .fr, via le BE) et indiquer à OpenDNSSEC (qui ne sait pas faire de requête DNS lui-même) quand l'enregistrement DS arrivera. On lui demande d'exporter la clé :

% sudo ods-enforcer key  export --zone cyberstructure.fr  

(Si votre BE et/ou votre registre demande le DS et pas le DNSKEY, il faudra ajouter --ds à la commande.) On indique alors la nouvelle clé dans l'interface du BE (Web ou API). Attention à soigner cette étape : cette clé va désormais être utilisée pour la validation, il ne faut pas se tromper. On patiente ensuite le temps que le registre ait bien mis à jour la zone parente et, lorsque notre DS est dans le DNS, on prévient OpenDNSSEC :

% sudo ods-enforcer key ds-seen --keytag 10825   --zone cyberstructure.fr
1 KSK matches found.
1 KSKs changed.

% sudo ods-enforcer key  list --verbose --zone cyberstructure.fr
Keys:
Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:
cyberstructure.fr               KSK      retire    waiting for ds-gone      2048  8          2d63a8cc9f68602d5b98f2bcb2714119 SoftHSM     63130
cyberstructure.fr               ZSK      active    2024-06-21 14:06:08      1024  8          b8e16f9a3aad96676ae36cd6fdb955ad SoftHSM     11668
cyberstructure.fr               KSK      active    2024-06-21 14:06:08      512   13         02e0ddf994431d5fa3d89cdc12f7addd SoftHSM     10825
cyberstructure.fr               ZSK      active    2024-06-21 14:06:08      512   13         cebc635b489780d2fddf5efabeba5b81 SoftHSM     54500

Parfait, la KSK (Key-signing key) ECDSA est désormais active. La KSK RSA va être retirée. Regardons d'abord le nouvel état. Il y a deux DS et deux clés actives. rollover-cs-2.png

On va maintenant retirer l'ancien DS. On le supprime via l'interface du BE puis, lorsque le registre a mis la zone à jour :

% sudo ods-enforcer key ds-gone --keytag 63130    --zone cyberstructure.fr
1 KSK matches found.
1 KSKs changed.

% sudo ods-enforcer key  list --verbose --zone cyberstructure.fr         
Keys:
Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:
cyberstructure.fr               KSK      retire    2024-06-21 14:06:08      2048  8          2d63a8cc9f68602d5b98f2bcb2714119 SoftHSM     63130
cyberstructure.fr               ZSK      active    2024-06-21 14:06:08      1024  8          b8e16f9a3aad96676ae36cd6fdb955ad SoftHSM     11668
cyberstructure.fr               KSK      active    2024-06-21 14:06:08      512   13         02e0ddf994431d5fa3d89cdc12f7addd SoftHSM     10825
cyberstructure.fr               ZSK      active    2024-06-21 14:06:08      512   13         cebc635b489780d2fddf5efabeba5b81 SoftHSM     54500
  

Plus qu'un seul DS, mais l'ancienne clé RSA est toujours là, pour les résolveurs qui auraient des anciennes informations dans leur mémoire. rollover-cs-3.png

Enfin, les clés et signatures RSA seront automatiquement supprimées du DNS lorsqu'elles sont devenues inutiles, ce qui nous mène au dernier état, lorsque le remplacement est terminé. Les clés disparaitront ensuite du trousseau d'OpenDNSSEC (mais cela prendra davantage de temps).

% sudo ods-enforcer key list --verbose --zone cyberstructure.fr
Keys:
Zone:                           Keytype: State:    Date of next transition: Size: Algorithm: CKA_ID:                          Repository: KeyTag:
cyberstructure.fr               KSK      retire    2024-07-06 08:09:09      2048  8          2d63a8cc9f68602d5b98f2bcb2714119 SoftHSM     63130
cyberstructure.fr               ZSK      retire    2024-07-06 08:09:09      1024  8          b8e16f9a3aad96676ae36cd6fdb955ad SoftHSM     11668
cyberstructure.fr               KSK      active    2024-07-06 08:09:09      512   13         02e0ddf994431d5fa3d89cdc12f7addd SoftHSM     10825
cyberstructure.fr               ZSK      active    2024-07-06 08:09:09      512   13         cebc635b489780d2fddf5efabeba5b81 SoftHSM     54500
  

Voici le résultat : rollover-cs-4.png

Ah, et j'avais dit qu'il y avait des erreurs dues au non-respect du RFC 9276, qui a changé les paramètres recommandés pour les enregistrements NSEC3 (RFC 5155). C'est exact, donc il a fallu également modifier cela dans notre politique :


<!-- Régime sans sel, et sans itérations -->
<NSEC3>
…
       <Hash>
         <Algorithm>1</Algorithm>
         <Iterations>0</Iterations>
         <Salt length="0"/>
       </Hash>
</NSEC3>

Quelques liens intéressants :


L'article seul

OpenDNS plus accessible depuis la France

Première rédaction de cet article le 28 juin 2024
Dernière mise à jour le 3 juillet 2024


Le résolveur DNS public OpenDNS ne répond désormais plus aux adresses IP situées en France, se pliant aux exigences des ayant-tous-les-droits.

OpenDNS a fait un communiqué sur ces exigences. Voici le résultat, avec dig, depuis une adresse chez Free :

    
% dig @208.67.222.222 www.bortzmeyer.org

; <<>> DiG 9.18.24-0ubuntu0.22.04.1-Ubuntu <<>> @208.67.222.222 www.bortzmeyer.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 102
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1410
; EDE: 16 (Censored)
;; QUESTION SECTION:
;www.bortzmeyer.org.	IN A

;; ADDITIONAL SECTION:
www.bortzmeyer.org.	0 IN TXT "Due to a court order in France issued under Article L.333-10 of the French Sport code the OpenDNS service is not currently available to users in France and certain French territories."

;; Query time: 4 msec
;; SERVER: 208.67.222.222#53(208.67.222.222) (UDP)
;; WHEN: Fri Jun 28 17:39:19 CEST 2024
;; MSG SIZE  rcvd: 249

  

Notez le status: REFUSED et l'enregistrement de type TXT qui explique. La loi en question est vouée à défendre les intérêts du sport-spectacle, qui passent avant tout, et est lisible ici (et le jugement qui a contraint OpenDNS semble être celui-ci, vous y trouverez la liste des noms concernés, ça vient de cet article de l'Informé). Les défenseurs de l'appropriation intellectuelle affirment souvent qu'elle sert à « protéger les créateurs » mais, comme on le voit ici, elle sert surtout à enrichir les clubs de rugby ou de football. Les personnes qui utilisaient OpenDNS le faisaient sans doute pour contourner une censure qui bénéficie surtout aux ayant-droits.

Ce n'est pas spécifique au nom de domaine demandé, tous donnent le même résultat. En outre, on peut vérifier, par exemple avec les sondes RIPE Atlas, que c'est pareil depuis quasiment tous les FAI français :

%  blaeu-resolve --requested 200 --country FR --nameserver 208.67.222.222 --type A www.bortzmeyer.org
Nameserver 208.67.222.222
[ERROR: REFUSED] : 180 occurrences 
[80.77.95.49] : 4 occurrences 
[TIMEOUT] : 2 occurrences 
Test #74529588 done at 2024-06-28T15:43:35Z
  

(Et inutile d'essayer en IPv6, c'est pareil.)

Celles et ceux qui avaient configuré leur réseau pour utiliser le résolveur OpenDNS n'avaient donc plus d'accès réseau (sans résolveur DNS, on ne peut quasiment rien faire, et cela bloquait un certain nombre d'équipements). C'est sans doute pour cela qu'OpenDNS a fait une exception (notée par David Ponzone) pour un service critique, la synchronisation d'horloges avec NTP :


%  dig @208.67.222.222 ntp.org           
…
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 6126
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 2
…
;; ADDITIONAL SECTION:
ntp.org.		0 IN TXT "Due to a court order in France issued under Article L.333-10 of the French Sport code the OpenDNS service is not currently available to users in France and certain French territories."

;; Query time: 8 msec
;; SERVER: 208.67.222.222#53(208.67.222.222) (UDP)
;; WHEN: Wed Jul 03 09:57:37 CEST 2024
;; MSG SIZE  rcvd: 238

%  dig @208.67.222.222 pool.ntp.org
…
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47543
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
…
;; ANSWER SECTION:
pool.ntp.org.		130 IN A 185.123.84.51
pool.ntp.org.		130 IN A 51.15.182.163
pool.ntp.org.		130 IN A 51.38.113.118
pool.ntp.org.		130 IN A 51.255.141.76

;; Query time: 48 msec
;; SERVER: 208.67.222.222#53(208.67.222.222) (UDP)
;; WHEN: Wed Jul 03 09:57:41 CEST 2024
;; MSG SIZE  rcvd: 105

Notez qu'on observe la même chose au Portugal, pays également cité dans le communiqué d'OpenDNS :

% blaeu-resolve --requested 200 --country PT --nameserver 208.67.222.222 --type A www.bortzmeyer.org
Nameserver 208.67.222.222
[ERROR: REFUSED] : 168 occurrences 
[80.77.95.49] : 1 occurrences 
Test #74532654 done at 2024-06-28T18:07:19Z
  

OpenDNS n'est qu'un des nombreux résolveurs DNS publics (et pas forcément le plus sympathique, par exemple, pendant longtemps, ils remplaçaient les réponses négatives par des publicités à eux). Par exemple, en Europe, il y a dns.sb, DNS4ALL, en France, il y a celui de FDN et il y en a même un à moi. Si on utilise un résolveur public (ce qui n'est pas forcément une bonne idée), le choix est vaste et les alternatives nombreuses (aucune raison de tous aller sur le résolveur d'une grosse entreprise capitaliste étatsunienne). Mais il n'est pas évident de choisir.

Un de ces gros résolveurs étatsuniens est celui de Google, qui est cité dans le jugement et qui, contrairement à OpenDNS, n'a pas bloqué tout service mais censure seulement les domaines demandés par la justice. (OpenDNS a sans doute jugé plus simple de bloquer tout accès depuis la France.)


% dig @8.8.8.8 volkastream.xyz A 

; <<>> DiG 9.18.24-0ubuntu0.22.04.1-Ubuntu <<>> @8.8.8.8 volkastream.xyz A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 18572
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; EDE: 16 (Censored): (The requested domain is on a court ordered copyright piracy blocklist for FR (ISO country code). To learn more about this specific removal, please visit https://lumendatabase.org/notices/41939614.)
;; QUESTION SECTION:
;volkastream.xyz.	IN A

;; Query time: 4 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Fri Jun 28 20:10:16 CEST 2024
;; MSG SIZE  rcvd: 246

  

Notez l'EDE (Extended DNS Error), concept normalisé dans le RFC 8914. Le code 16 pour indiquer la censure est très rarement observé dans la nature, la plupart des censeurs étant hypocrites.

En parlant de ce domaine, volkastream.xyz, voyons sa censure par les résolveurs DNS des FAI français :

% ./blaeu-resolve --country FR --requested 100 --ede --type A volkastream.xyz
[104.21.38.55 172.67.219.135] : 68 occurrences 
[127.0.0.1] : 18 occurrences 
[ERROR: NXDOMAIN] : 2 occurrences 
[EDE 16 (Censored): The requested domain is on a court ordered copyright piracy blocklist for FR (ISO country code). To learn more about this specific removal, please visit https://lumendatabase.org/notices/41939614. ERROR: REFUSED] : 2 occurrences 
Test #74533089 done at 2024-06-28T18:26:58Z
  

Ce domaine n'est pas bloqué par le résolveur DNS public de Cloudflare mais, comme Cloudflare est son hébergeur Web, il a pu quand même le censurer, et renvoie désormais le code de statut HTTP 451 (normalisé dans le RFC 7725) :


% curl -v https://volkastream.xyz
…
* Connected to volkastream.xyz (2606:4700:3037::6815:2637) port 443 (#0)
…
> GET / HTTP/2
> Host: volkastream.xyz
> user-agent: curl/7.81.0
> accept: */*
…
< HTTP/2 451 
< date: Sat, 29 Jun 2024 17:52:55 GMT
< content-type: text/html

  

OpenDNS est un service de Cisco.

Merci à capslock pour le signalement.


L'article seul

Problème DNSSEC au Libéria

Première rédaction de cet article le 13 juin 2024
Dernière mise à jour le 16 juin 2024


Le 12 juin, une panne (partielle ?) a touché le TLD .lr. Il s'agit d'un problème DNSSEC (qui a fait l'objet d'un retex détaillé par le gestionnaire technique.

L'alerte a été donné sur la liste de l'OARC. Au matin du 13 juin, on constate :

Les sondes RIPE Atlas sont d'accord pour dire que ça marche mais pas parfaitement :

% blaeu-resolve --requested 200 --type SOA --displayvalidation lr
[ (Authentic Data flag)  rip.psg.com. hostmaster.psg.com. 1718251170 345600 3600 2592000 14400] : 88 occurrences 
[rip.psg.com. hostmaster.psg.com. 1718251170 345600 3600 2592000 14400] : 85 occurrences 
[ERROR: SERVFAIL] : 13 occurrences 
[ERROR: NXDOMAIN] : 11 occurrences 
[ (Authentic Data flag)  rip.psg.com. hostmaster.psg.com. 1718225894 345600 3600 2592000 14400] : 1 occurrences 
[] : 1 occurrences 
Test #73322645 done at 2024-06-13T07:39:43Z
  

L'explication technique est probablement la suivante : en interrogeant tous les serveurs faisant autorité pour .lr, avec la requête lr/DNSKEY, on voit que certains envoient deux signatures (ayant le même identificateur de clé, 29984) :

lr.			86400 IN DNSKEY	257 3 8 (
				AwEAAbdBaOsz0xNn+L+8+GopcC0w9NneWhKl9GJyCR5d …
				) ; KSK; alg = RSASHA256 ; key id = 29984
lr.			86400 IN DNSKEY	256 3 8 (
				AwEAAci9weuAQKBbKsqkOYnm1H0C5a7ZX/8xoQDmNp8Y …
				) ; ZSK; alg = RSASHA256 ; key id = 42940
lr.			86400 IN RRSIG DNSKEY 8 1 86400 (
				20240626012025 20240611235025 29984 lr.
				YeZQ3KiSsDQD3jizNHXnTUYxRtzJwXl0aoctrgqDqajW …
lr.			86400 IN RRSIG DNSKEY 8 1 86400 (
				20240626205813 20240612192813 29984 lr.
				lDt9P1RZtcs+/SDilJZ6tNRsZr+F5EdisfmsNw7E62+1 …
  

Cela ne se voit pas à l'œil nu mais une des deux signatures est invalide (cf. les rapports de DNSviz et Zonemaster). Les résolveurs qui réussissent sont ceux qui sont tombés sur le serveur faisant autorité qui ne servait que la bonne signature, ou bien testaient les deux signatures (d'où l'importance de tester plus qu'une signature, malgré KeyTrap). Notez que, malgré cette différence des réponses, tous les serveurs faisant autorité ont le même numéro de série :

% check-soa lr
fork.sth.dnsnode.net.
	77.72.229.254: OK: 1718251170
	2a01:3f0:0:306::53: OK: 1718251170
ns-lr.afrinic.net.
	196.216.168.61: OK: 1718251170
	2001:43f8:120::61: OK: 1718251170
rip.psg.com.
	2001:418:1::39: OK: 1718251170
	147.28.0.39: OK: 1718251170
  

La commande pour interroger tous les serveurs est :

% for server in 77.72.229.254 2a01:3f0:0:306::53 2001:43f8:120::61 196.216.168.61 2001:418:1::39 147.28.0.39; do
  echo $server
  dig +dnssec @$server lr DNSKEY
done  > lr.txt
  

Comme elle est faite depuis un seul point de mesure (mon bureau), elle a ses limites, notamment, elle ne détectera pas les différences entre instances d'un même nuage anycast.

Y avait-il collision des identificateurs de clé comme en Russie en début d'année ? Comme vu plus loin, le problème était autre. Un indice : le Liban, qui a le même gestionnaire technique, avait le même problème.

Bref, les explications techniques complètes figurent dans cet article très détaillé ; une attaque par déni de service a déclenché une bogue assez bizarre dans le signeur, Knot.


L'article seul

Articles des différentes années : 2024  2023  2022  2021  2020  2019  2018  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.