Le 28 février dernier, j’ai poussé un peu plus tôt que prévu en production une
nouvelle version de monrer.fr. Presque dix ans depuis sa mise en
service, monrer.fr couvre désormais toutes les lignes RER et Transilien dans
leur intégralité. Oui, même les lignes A et B !
Un exemple ici à la gare d’Auber, sur le RER A, en zone RATP.
J’aurais voulu faire un peu plus de tests la mise en production, mais
l’actualité, marquée par un mouvement social qui avait
toutes les chances d’être bien suivie, m’a poussé à accélérer le tempo.
Jusqu’ici, le pari semble réussi car je ne crois pas avoir détecté de
problèmes majeurs. Il y a peut-être des bugs d’affichage çà et là, mais
je les corrigerai quand j’aurai un peu plus de temps.
J’ai accompli cet exploit simplement en changeant de source de données pour
les horaires temps réel. L’API temps réel Transilien, que j’ai
utilisée depuis plus de neuf ans, va être
décomissionnée à la fin du mois de mars 2023. Et celle de la RATP, que je
comptais intégrer à monrer.fr aussi (mais j’ai fini par abandonner
car elle était fastidieuse à tester et à exploiter), a été décommissionnée
le 30 septembre 2022.
Ces deux sources de données cèdent toutes les deux la place à une nouvelle,
gérée par la nouvelle Plateforme Île-de-France Mobilités (PRIM) :
l’API Prochains passages (requête unitaire). Un
vrai soulagement pour moi pour de nombreuses raisons. Premièrement, le quota
d’appels à cette API est beaucoup plus élevé : au lieu de 20 appels par minute
chez la SNCF, j’ai désormais droit à 1 million d’appels par jour. Je n’ai donc
plus aucune raison de me soucier des problèmes de quota que j’ai pu avoir par
le passé. Deuxièmement, cette API agrégeant les données de plusieurs
transporteurs, je n’ai plus besoin de faire ce travail moi-même.
Troisièmement, les informations sont plus complètes : l’API retourne les
numéros de voie (pour la plupart des gares) et, en fonction du transporteur,
aussi les trains terminus ou sans arrêt.
Avec cette nouvelle version, c’est pour moi un rêve qui devient réalité : une
couverture complète grâce à des jeux de données de qualité, en Open Data et
dont l’accès est gratuit. Je consacrerai un billet ultérieur à une discussion
technique de la nouvelle API, pour les curieux et pour partager mon retour
d’expérience détaillé. En attendant, profitez-en !
J’ai eu l’occasion d’expérimenter récemment avec Wireguard sous FreeBSD.
Globalement, je suis plutôt satisfait du mode de fonctionnement, mais aussi de
la façon dont cela a été packagé de manière générale sous FreeBSD.
Pour mon usage, j’avais besoin de créer un VPN point à point entre deux
machines, une derrière une Livebox et l’autre chez un hébergeur. Je voulais
que la seconde ait accès à des services hébergés sur la première, comme
Postfix et nginx. Ces services sont configurés sur la première machine pour
écouter sur une liste explicite d’adresses IP.
Mais au redémarrage de la machine chez l’hébergeur, Postfix et nginx
refusaient de démarrer, car l’interface wg0 créée par Wireguard n’existait
pas encore. Ce problème est dû au lancement trop tardif du script
/etc/rc.d/wireguard à l’initialisation du système.
Comment faire, alors, pour que les VPN Wireguard soient montés plus tôt ? La
solution consiste à les démarrer en même temps que les autres interfaces
réseau du système, via le script /etc/rc.d/netif et des éléments de
configuration dans /etc/rc.conf. La méthode que je vais vous montrer est en
production chez moi depuis quelques mois, et je n’ai pas rencontré de problème
particulier jusqu’à maintenant.
Prérequis
Pour commencer, installez Wireguard sur les deux côtés :
# pkg install wireguard-kmod wireguard-tools
Il faudra ensuite choisir un plan d’adressage pour le VPN et générer des clefs
et un secret partagé.
Adressage
Pour mon VPN, j’ai choisi d’adresser les deux extrémités en IPv6, en utilisant
les adresses locales uniques (Unique Local Addresses, ULA), dans la
plage fc00::/7. Pour avoir la quasi-garantie d’une plage unique, il faut
utiliser un générateur pour obtenir un /48 privé. J’obtiens par
exemple fdd9:835d:6e41::/48.
Puisqu’il n’y a que deux machines dans ce réseau, alors d’après la
RFC 6164, il est tout à fait possible (et souhaitable) de se
restreindre à un /127 pour adresser les deux côtés. Mais alors, quelles
valeurs choisir pour les 64 bits les plus à droite de l’adresse ?
On pourrait alors choisir fdd9:835d:6e41:: et fdd9:835d:6e41::1 à la place. Là
aussi, le choix est mauvais, car la première des deux adresses a ses 64 bits
de poids faible à zéro et leur usage en tant qu’adresse unicast est
déconseillé. Pour la même raison, l’intervalle
fdd9:835d:6e41::ffff:ffff:ffff:ff7f à fdd9:835d:6e41::ffff:ffff:ffff:ffff est
déconseillé également.
J’ai donc fini par choisir fdd9:835d:6e41::a et fdd9:835d:6e41::b. Ainsi, pour
la suite, j’appellerai les deux côtés « A » et « B », d’après l’identifiant
d’interface que je leur donnerai dans le /127 susmentionné.
Dans mon cas, le côté B est celui qui initie la connexion avec le côté A. Les
deux côtés peuvent initier la connexion, tout comme avec IPSec, mais dans mon
cas, le côté B se trouve derrière un NAT et son adresse IP publique peut
changer, alors que le côté A a une adresse IPv4 publique fixe.
Génération des clefs
Ensuite, il faut créer les clefs publiques et privées de chaque côté. La
commande ci-dessous génère deux fichiers contenant des clefs représentés en
base64.
# umask 077
# wg genkey | tee clef_privee | wg pubkey > clef_publique
Puis, sur l’un ou l’autre des côtés, générez un secret partagé entre les deux
stations, qui se trouvera également représenté en base64 dans un fichier :
root@A:~# umask 077
root@A:~# wg genpsk > secret_partage
Nous pouvons ensuite passer à la configuration proprement dite.
Configuration
La page man de rc.conf(5) explique que, pour chaque interface à
démarrer, netif cherche un script nommé /etc/start_if.<interface>. S’il
existe, alors il est exécuté avant de configurer les adresses. Nous allons
donc créer de chaque côté un script /etc/start_if.wg0, destiné à l’interface
créée pour le VPN Wireguard. Cette interface est configurée en passant par
l’utilitaire wg(8).
Côté B (initiateur)
Ainsi, sur le côté B, qui initie la connexion, le script /etc/start_if.wg0
est le suivant :
#!/bin/sh
/usr/local/bin/wg setconf wg0 /dev/stdin <<EOF
[Interface]
ListenPort = 51820
PrivateKey = clef privée de B
[Peer]
AllowedIPs = fdd9:835d:6e41::a/128
PublicKey = clef publique de A
PreSharedKey = secret partagé
Endpoint = adresse ou nom d’hôte de A:51820
PersistentKeepAlive = 30
EOF
Ici, j’ai choisi d’ajouter l’option PersistentKeepAlive, car il s’agit du
côté qui initie la connexion et que je dois traverser des NAT IPv4. Et dans ce
script, il faut utiliser le chemin complet vers l’utilitaire wg, car
/usr/local/bin ne se trouve pas dans le PATH du shell qui l’exécute.
Étant donné que le fichier contient des secrets, celui-ci doit
impérativement être chmod 700 ou la confidentialité de votre VPN sera
compromise.
On peut ensuite ajouter les éléments de configuration suivants au rc.conf du
côté B :
cloned_interfaces="wg0" # si cette variable existe déjà, ajoutez "wg0"
ifconfig_wg0_ipv6="inet6 fdd9:835d:6e41::b prefixlen 127"
C’est tout !
Côté A
Pour le côté A, l’idée est la même, mais le contenu du
script /etc/start_if.wg0 est légèrement différent :
#!/bin/sh
/usr/local/bin/wg setconf wg0 /dev/stdin <<EOF
[Interface]
ListenPort = 51820
PrivateKey = clef privée de B
[Peer]
AllowedIPs = fdd9:835d:6e41::b/128
PreSharedKey = secret partagé
PublicKey = clef publique de A
Là encore, pensez à faire un chmod 700 sur ce fichier pour éviter de
compromettre votre VPN.
Les éléments à ajouter dans rc.conf sont similaires :
cloned_interfaces="wg0" # si cette variable existe déjà, ajoutez "wg0"
ifconfig_wg0_ipv6="inet6 fdd9:835d:6e41::a prefixlen 127"
Démarrage du VPN
Enfin, de chaque côté, il ne reste plus qu’à démarrer l’interface wg0…
# service netif start wg0
…et de tester en « pingant » l’autre côté (ping6 sous FreeBSD jusqu’à 12,
ping tout court à partir de FreeBSD 13) :
root@A:~# ping6 fdd9:835d:6e41::b
PING6(56=40+8+8 bytes) fdd9:835d:6e41::a --> fdd9:835d:6e41::b
16 bytes from fdd9:835d:6e41::b, icmp_seq=0 hlim=64 time=60.610 ms
16 bytes from fdd9:835d:6e41::b, icmp_seq=1 hlim=64 time=79.763 ms
16 bytes from fdd9:835d:6e41::b, icmp_seq=2 hlim=64 time=59.891 ms
16 bytes from fdd9:835d:6e41::b, icmp_seq=3 hlim=64 time=59.442 ms
^C
--- fdd9:835d:6e41::b ping6 statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 59.442/64.926/79.763/8.576 ms
Conclusion
Je vous ai donc présenté une méthode pour lancer un VPN Wireguard le plus tôt
possible au démarrage de FreeBSD.
Cette méthode ne se limite pas qu’aux VPN point à point, mais il se trouve que
dans mon cas d’usage, un lien entre deux machines suffisait. Si nous avions eu
plusieurs machines initiatrices de connexions à un seul et même point central,
les configurations de chaque initiateur serait identique (à la clef privée
près) et le point central aurait une déclaration par initiateur autorisé.
Il y a aussi quelques opportunités de mettre les choses un peu plus au propre
dans ce système. Tout d’abord, le script /etc/start_if.wg0 contient toute la
configuration pour l’interface wg0, dans un seul fichier. Je peux comprendre
que ce choix puisse déranger certains. Mais adapter ce script pour qu’il lise
des secrets ou un fichier de configuration complet dans
/usr/local/etc/wireguard est tout à fait possible.
De même, le nom wg0 est codé en dur dans le fichier ; mais là encore, il est
possible de modifier le script en examinant le nom sous lequel il est appelé
(variable $0) et d’en dériver le nom de l’interface à démarrer (par la
transformation ${0##*.}). Ainsi, s’il faut démarrer un autre VPN Wireguard,
en imaginant que l’interface s’appelle wg1, on pourrait finir par juste
pouvoir s’en sortir en faisant de /etc/start_if.wg1 un lien symbolique vers
/etc/start_if.wg0.
Dans tous les cas, je vous ai montré qu’il est tout à fait possible de passer
par netif, pour démarrer les VPN Wireguard en même temps que les autres
interfaces réseau, dès l’initialisation du système. Ainsi, les interfaces wg
se comportent beaucoup plus comme des interfaces natives du système, ce qui
est élégant et appréciable.
Après que ma bien-aimée Nausicaa ait préparé sa thèse d’histoire médiévale en LaTeX, notamment grâce à quelques trucs et astuces de LaTeX appliquées aux thèses en sciences humaines, le livre qui en est l’adaptation sera bientôt publié. Dans ce billet, qui sera la conclusion de cette petite série, je vous propose les péripéties de l’adaptation de sa thèse au format livre.
Après le long travail que représente une thèse, on serait tenté de croire que la faire publier au format livre serait une formalité. Le texte est en effet déjà prêt, alors cela ne devrait-il pas passer comme une lettre à la Poste ?
En réalité, c’est un peu plus difficile que cela. Je passe les détails sur le choix de l’éditeur : cela mériterait un billet de blog dédié au sujet. Puis, après avoir soumis la thèse telle quelle au comité de lecture, celui-ci donne un avis positif ou négatif. Mais un avis positif n’est que le début de l’aventure, car dans le cas de Nausicaa, son éditeur a demandé de réduire considérablement le texte pour ne pas dépasser les huit cent mille signes.
S’ajoute à ces contraintes une question technique de taille : la maison d’édition ne saurait que faire de fichiers LaTeX. Leur procédé de soumission impose en effet le format Word. Dans ce billet, nous verrons donc les différents obstacles techniques qu’il a fallu surmonter pour passer de la thèse au livre.
Passer de LaTeX à Word : Pandoc à la rescousse
Les formats de fichiers TeX et DOCX n’ont strictement rien à voir. TeX est en fait un langage assez bas niveau mais qu’il est possible d’enrichir avec des commandes ad hoc, jusqu’à former un mini-langage d’aide à la génération d’éléments structurels (délimiter les chapitres, les sections, etc.) et d’aide à la rédaction. C’est, du moins, ce qu’est LaTeX par rapport à TeX. DOCX, quant à lui, est une archive ZIP contenant une collection de fichiers XML, dont l’un comporte un texte dans une structure similaire au HTML ou à DocBook dans l’idée, mais bien plus complexe. J’avais déjà dit ailleurs ce que je pensais de ce format. Bref : ce sont deux mondes à part et pour des raisons techniques complexes, le passage de LaTeX à DOCX allait forcément entraîner des pertes d’information.
J’étais donc assez pessimiste quant à la fiabilité d’éventuels convertisseurs de LaTeX vers DOCX. Mais étant donné que la thèse faisait plus de six cents pages une fois imprimée et contenait au total 2 014 occurrences de \cite{} et \footcite{}, il était hors de question de faire cette conversion à la main. Il nous fallait donc impérativement un outil automatique qui sache en outre traiter les références bibliographiques.
Heureusement, après avoir essayé plusieurs outils différents, j’ai fini par trouver Pandoc qui, en plus d’être le convertisseur qui marchait le mieux, est activement développé et cochait toutes les cases de ce petit cahier des charges. Il est en outre programmé en Haskell, un langage que j’ai étudié peu de temps avant la soutenance, ce qui m’a permis de l’adapter ponctuellement à nos besoins.
Pandoc est en fait décomposé en deux parties : l’outil de conversion lui-même, la commande pandoc, auquel on peut adjoindre un autre appelé pandoc-citeproc s’il faut convertir des références bibliographiques. Pour cela, pandoc-citeproc lit une base de données bibliographique au format BibTeX et un fichier de style bibliographique au format CSL (le même format que celui utilisé par Zotero) pour produire les références dans le style souhaité.
L’architecture logicielle de pandoc me plaît bien, d’ailleurs : il est en effet conçu comme un compilateur. D’abord, pandoc utilise une front-end pour convertir le texte source dans une représentation intermédiaire, puis une back-end pour transformer cette structure intermédiaire dans le format cible. Ainsi, ajouter la prise en charge d’un format de fichiers ne nécessite l’écriture que d’une front-end et d’une back-end pour ce format et il devient alors possible de le convertir depuis ou vers n’importe quel autre format déjà pris en charge par pandoc.
Une conversion fidèle mais un peu laborieuse
J’ai donc chargé le style bibliographique des Presses Universitaires de
Rennes (PUR), différent du style ISO 690 utilisé dans
la thèse, et fait un essai sur un petit extrait de la thèse. J’avais utilisé
les dernières versions de ces deux outils à cette époque-là : Pandoc
version 2.10.1 et pandoc-citeproc version 0.17.0.2. Le résultat était plutôt
convaincant, comme on peut le voir sur la comparaison que j’ai reproduite.
Comparison des apparences visuelles de la thèse originale en LaTeX (en haut) et du résultat d’une conversion en DOCX par Pandoc et pandoc-citeproc, tel qu’il s’affiche dans LibreOffice Writer 7.3.7.2 (en bas). Extraits reproduits avec l’aimable autorisation de Nausicaa.
Et ainsi, j’obtenais un résultat qui, à première vue, semblait plutôt fidèle. La perte de la mise en forme lors de la conversion ne nous importait peu, mais le texte et les notes de bas de page y sont. On notera que les références bibliographiques sont également converties du style ISO 690 au style des PUR.
La conversion de la thèse complète ne s’est pas passée entièrement sans accrocs, cependant.
Premièrement, le document Word contenait des guillements à l’anglo-saxonne (“ ”), alors qu’il fallait des guillements français (« »), car Pandoc convertissait les commandes \enquote{} (du package csquotes) sans tenir compte de la langue du document. Je ne me souviens plus comment j’ai résolu ce problème, mais il me semble que j’ai dû préciser à Pandoc que le document doit être en français (avec l’option de ligne de commandes -M lang=fr-FR).
Deuxièmement, la source LaTeX était un peu trop complexe pour Pandoc. Elle est composée d’un fichier racine, these.tex, dont les réglages de forme se trouvaient dans un fichier auxiliaire these-style.sty référencé dans le fichier principal par une commande \usepackage{these-style}. Chaque chapitre se trouve dans un fichier séparé et these.tex les référence, dans le bon ordre, avec des commandes \include. Las, quand je donnais à Pandoc le fichier these.tex tel quel, la conversion échouait avec un message d’erreur vraiment pas clair :
Error at "source" (line 107, column 16):
unexpected end of input
\end{document}
^
La solution a donc été de préparer une version allégée de these.tex appelée these-light.tex. J’ai copié le contenu de these-style.sty directement dans these.tex avant d’en retirer pratiquement toutes les commandes de mise en forme. Parmi les \usepackage, je n’ai gardé que l’essentiel, dont biblatex, babel, csquotes, tabu, hyperref, graphicx et quelques autres. Avec cette modification, Pandoc était content.
En fin de compte, après s’être placé dans le répertoire racine de la thèse LaTeX et y avoir téléchargé le fichier CSL des PUR, j’ai fini par trouver cette ligne de commande exacte pour convertir la thèse de LaTeX vers Word :
À première vue, la conversion avait bien marché. In fine, seuls quelques tableaux faits avec l’environnement tabulary n’ont pas été converties correctement.
Il y avait aussi quelques problèmes dans les notes de bas de page. Par exemple, dans certaines références, il manquait des espaces entre l’abréviation « coll. » et le nom de la collection. Par ailleurs, la thèse utilisait beaucoup de raccourcis comme « ibid. » ou « op. cit. » et la moindre modification du texte a des répercussions sur ces références-là.
Or, la cible des huit cent mille signes imposée par l’éditeur imposait des coupes parfois très lourdes dans le texte. Les notes de bas de page étaient donc à reprendre intégralement quoi qu’il arrivait.
Il en émergeait aussi le besoin de compter les signes. Or LaTeX ne permet pas de facilement compter les signes d’un document fini. Une recherche sur Internet donne quelques scripts qui s’y essayent, mais je doute de leur fiabilité : avec TeX, il n’est pas possible d’accéder à une représentation intermédiaire où toutes les macros ont été substituées (afin de pouvoir, notamment, compter les caractères dans les notes de bas de page, également inclus dans le décompte). Un outil comme Pandoc serait à mon avis mieux à même d’en donner une estimation.
C’est ce besoin de surveiller constamment le nombre de signes qui a imposé le workflow consistant à convertir la thèse au format DOCX d’abord et la réduire ensuite. Sinon, le travail aurait probablement été fait dans l’ordre inverse : réduire le texte en intervenant sur la source LaTeX d’abord, puis convertir en DOCX ensuite.
Dans tous les cas, après une conversion comme celle-ci, il est indispensable d’examiner intégralement le résultat afin de s’assurer que rien n’a été perdu au moment de la conversion. Pour cette raison, convertir d’abord et réduire ensuite était peut-être la bonne méthode.
Conclusion : Markdown comme format source ?
Les éditeurs qui imposent des formats de fichiers qui, sans l’existence d’alternatives libres, auraient imposé l’achat d’un logiciel onéreux et non libre, sont un effet émergent regrettable de la mainmise qu’ont certains éditeurs de logiciels sur le marché des suites bureautiques, alors qu’il existe des systèmes de préparation mieux adaptés aux travaux scientifiques, mais moins connus en dehors des milieux techniques.
Or, pour des publications scientifiques préparées sur ordinateur, il est justement important de pouvoir conserver les textes dans des formats de fichiers pérennes et peu susceptibles de tomber dans l’obsolescence. Les formats reposant sur du texte brut, combiné à des outils externes transformant ce texte brut en un format lisible, ont donc tout intérêt à être favorisés.
Pandoc pourrait peut-être bien apporter une solution à cela : en permettant à l’auteur de rédiger son texte dans l’outil de son choix puis de convertir à la demande dans les formats requis par les éditeurs, nul besoin d’enfermer son propos dans des formats difficiles à lire par autre chose que le logiciel de l’éditeur. Pour ce faire, Pandoc propose une variante de Markdown avec des extensions propres à Pandoc, conçu pour que tout document préparé dans ce format puisse être converti sans trop de pertes dans l’un des autres formats cible de Pandoc – y compris LaTeX.
Pour ces raisons, si je devais moi-même faire une thèse, j’envisagerais sérieusement de rédiger le manuscrit en Markdown-Pandoc, puis de passer par une conversion vers LaTeX pour en faire un joli PDF. Le résultat sera toujours aussi esthétiquement plaisant grâce à la puissance de TeX, mais cela me donne davantage de souplesse vis-à-vis des exigences des éditeurs lorsqu’il sera temps de la publier. La méthodologie est décrite dans l’article de Dennis Tenen et Grant Wythoff intitulé Sustainable Authorship in Plain Text using Pandoc and Markdown, qui montre qu’en sciences humaines tout du moins, cette approche pourrait bien être le meilleur de plusieurs mondes.
Mise à jour du 7 août 2022 : la version 4.53.14 du firmware souffre des mêmes problèmes.
Un soir, j’ai été surpris de découvrir que
la Livebox propose désormais une fonction de délégation de préfixes IPv6 dans
son interface d’administration.
C’est une fonction que j’attendais depuis très longtemps sur la Livebox, car
sans elle, je ne pouvais pas avoir de connectivité IPv6 à cause de la
configuration particulière de mon réseau. Au lieu de me fier directement à ma
Livebox pour le routage, le pare-feu et le Wi-Fi, j’ai en effet choisi
d’utiliser mes propres équipements au lieu de la box, et je n’utilise cette
box que comme un pont entre le réseau délimité par mon propre routeur et le
réseau d’Orange.
Après quelques heures passées à expérimenter, j’ai fini par être un peu déçu à
cause de quelques limitations, selon moi injustifiées, imposées par la
Livebox. Dans ce billet, je vous propose d’approfondir ce que j’ai déjà écrit
sur Mastodon, avec quelques exemples, captures d’écran et captures réseau à
l’appui. J’ai effectué mes tests sur une Livebox 4 ; les premiers ont été
effectués avec la version 4.43.12 du firmware et des tests complémentaires
pour préparer cet article avec la version 4.46.0, ma box ayant été
subrepticement mise à jour (mais apparemment, les bugs seraient les
mêmes).
La délégation de préfixes par DHCPv6
Le mécanisme de délégation de préfixes utilise une option DHCPv6, appelée
IA_PD, spécifiée dans la RFC 3633. Un routeur souhaitant obtenir
une délégation de préfixe (appelé requesting router dans la RFC, mais
j’utiliserai ici le terme « routeur délégataire ») envoie un paquet DHCPv6
Solicit contenant, dans une ou plusieurs associations d’identité (IA), une
option IA_PD. Le routeur délégant (delegating router) répond alors avec un
DHCPv6 Advertise contenant elle aussi un ou plusieurs IA_PD par préfixe qu’il
accepte de déléguer.
Orange utilise déjà la délégation de préfixes IPv6 dans son propre
réseau pour attribuer les préfixes IPv6, des /56, aux abonnés. Donc si un
routeur en aval de la Livebox peut demander des délégations de préfixes à la
Livebox, on obtient une chaîne de délégation comme ceci :
pour le préfixe 2001:db8:af3c:5a00::/56, un routeur quelque part dans le
réseau opérateur d’Orange est le routeur délégant et la Livebox
est le routeur délégataire ;
pour le préfixe 2001:db8:af3c:5a82::/64, la Livebox est le routeur délégant
et le routeur aval est le routeur délégataire.
Position du problème
La force des choses, c’est-à-dire, entre autres, ma passion pour
l’informatique, ma méfiance vis-à-vis de certains appareils connectés que je
présume être trop bavards, une certaine pandémie mais surtout une simple
question d’hygiène informatique, m’a amené à découper mon réseau domestique en
plusieurs VLAN : bureautique, multimédia (et autres bidules connectés),
consoles de jeux, téléphonie sur IP, administration, labo d’expérimentation
IPv6 et télétravail. Tous ces VLAN sont isolés entre eux et certains sont
également isolés d’Internet.
En IPv4, parmi les plages d’adresses mises de côté par la RFC 1918
pour un usage privé, j’ai choisi un /16 que je découpe ensuite en /24 pour
chacun de mes VLAN. En IPv6, il me faut idéalement un /64 par VLAN, donc le
fait qu’Orange alloue un /56 par abonné est plutôt opportun. Bien que la
Livebox réserve un des 256 /64 disponibles, cela me laisse tout de même la
possibilité d’adresser 255 VLAN en IPv6, ce qui suffira amplement pour mes
besoins.
Plus tôt, quand j’avais mis en place ma connectivité IPv6 en étant chez
Free, j’avais un réseau beaucoup plus simple dans lequel je
n’avais qu’un seul VLAN ; j’utilisais d’ailleurs un démon, ndppd, pour jouer
le rôle de proxy NDP. Mais je souhaite écarter d’emblée cette solution, que je
considère comme un honteux bidouillage qui oblige, par ailleurs, à utiliser
des préfixes plus longs dans ses VLAN comme des /80, ce qui impose la mise en
œuvre d’un serveur DHCPv6.
Les limitations de la Livebox en matière de délégation de préfixes
En passant une soirée à expérimenter avec la Livebox, j’ai pu trouver trois
problèmes majeurs qui font obstacle, dans l’immédiat, à un déploiement
généralisé d’IPv6 dans mon réseau : l’impossibilité de demander la délégation
d’un préfixe plus court qu’un /64 ; l’impossibilité de choisir à l’avance
le /64 à déléguer ; enfin, l’incapacité, pour la box, de déléguer correctement
plus d’un /64 au même routeur délégataire lorsque ce dernier en demande
plusieurs.
Déléguer un /56 ou un /60 ne fonctionne pas
Mon premier essai consistait à demander la délégation de mon /56 complet,
c’est-à-dire 2001:db8:af3c:5a00::/56 dans le schéma d’exemple. Au lieu de
cela, la Livebox me délègue un /64 que je n’ai pas choisi !
On le voit d’ailleurs bien dans l’interface d’administration de la Livebox :
l’adresse MAC de mon routeur apparaît bien, mais pas le /56 que j’avais
demandé. Sur le routeur délégataire, aucune des interfaces qui devait profiter
des préfixes délégués par la Livebox n’a d’adresse IPv6, faute d’obtenir la
délégation souhaitée. Donc demander un /56 ne marche pas.
À première vue, il est assez logique qu’une demande de délégation de
2001:db8:af3c:5a00::/56 n’aboutisse pas : ce /56 correspond à la plage complète
déléguée à la Livebox, or elle réserve déjà 2001:db8:af3c:5a00::/64.
Mais même demander un /60 ne fonctionne pas non plus : dans ce cas, la
Livebox délègue obstinément un /64, au lieu de renvoyer une erreur. Il y a
pourtant 15 préfixes /60 qui n’entrent pas en conflit avec le /64 réservé par
la Livebox.
Rien n’empêche a priori la Livebox d’accepter de déléguer
2001:db8:af3c:5a00::/56 excepté 2001:db8:af3c:5a00::/64 : il est même possible
d’exprimer cela grâce à une option DHCPv6 décrite dans la RFC 6603.
Le routeur délégataire doit pour cela signaler la prise en charge de cette RFC
dans son DHCPv6 Solicit. Or le client wide-dhcpv6, utilisé par mon routeur,
ne le fait pas ; seul dhcpcd sait le faire.
J’ai donc cherché à savoir si la Livebox prend en charge cette option. Pour ce
faire, j’ai pris une machine sous Linux, installé dhcpcd dessus, créé une
interface virtuelle avec la commande ip link create dummy0 type dummy, puis
préparé un fichier de configuration dhcpcd.conf avec le contenu suivant :
interface eth0
ia_pd 0/::/56 eth0/0 dummy0/1
J’ai alors lancé dhcpcd -6B -f /chemin/vers/dhcpcd.conf eth0, tout en étant
connecté en Ethernet à ma Livebox, pendant que je capturais les paquets
DHCPv6. Malgré la présence de l’indication de prise en charge de la RFC 6603
dans le DHCPv6 Solicit, la Livebox continue d’attribuer un /64 aléatoire.
C’est d’autant plus dommage que le souhait de disposer librement des
sous-préfixes 2001:db8:a3fc:5a01::/64 à 2001:db8:a3fc:5aff::/64 est à mon avis
le cas d’usage le plus répandu nécessitant la délégation de préfixes par la
Livebox. Même disposer seulement d’un /60 m’aurait déjà permis de connecter en
IPv6 seize VLAN, ce qui aurait été largement suffisant pour mon usage.
En l’état, cette mise en œuvre de la délégation de préfixes par la Livebox est
déjà une opportunité manquée.
Pas de choix du préfixe délégué
Nous savons maintenant que la Livebox n’accepte de déléguer que des /64.
Sur l’interface d’administration de la box, il n’est pas possible de
configurer à l’avance quels sous-préfixes la box peut déléguer : au lieu de
cela, à chaque fois qu’un routeur délégataire demande un /64, il s’en voit
attribuer un aléatoire par la box.
Ces préfixes ont l’air stables, c’est-à-dire que le même couple DUID/IAID
donne le même préfixe ; mais attention, si on désactive puis réactive la
fonction de délégation de préfixes sur la Livebox, tous les préfixes
anciennement attribués sont oubliés et la box attribuera d’autres préfixes
choisis au hasard pour le même couple DUID/IAID. Ou du moins, c’est ce qui est
arrivé une fois : lorsque j’ai essayé de reproduire ce comportement, je n’y
suis pas arrivé et la Livebox a attribué au même couple DUID/IAID le même /64.
Quoi qu’il en soit, il manque cruellement d’options pour paramétrer plus
finement les préfixes délégués.
Le caractère aléatoire des préfixes délégué n’est guère pratique quand on
souhaite placer des serveurs dans une plage d’adresses ainsi déléguée : un
préfixe imprévisible complique la publication de leurs adresses dans le DNS.
Pourtant, il est possible pour un routeur délégataire de demander la
délégation d’un préfixe bien précis. Mais même quand l’option IA_PD du
message DHCPv6 Solicit émis par le routeur délégataire désigne un préfixe
qu’il souhaite obtenir, la Livebox n’en tient pas compte.
Au plus un /64 pour un équipement
Nous savons maintenant que la Livebox ne délègue que des /64 et qu’il est
impossible de savoir à l’avance quels sont les préfixes qu’il distribue à
chaque équipement. Au moins, elles devraient être relativement stables.
Dans un message DHCPv6, il est possible de demander la délégation de plusieurs
préfixes, chacun identifiés par des IAID uniques (un IAID étant un entier non
signé de 32 bits). Il serait donc normalement possible de contourner les
précédentes limitations en demandant autant de délégations distinctes que de
VLAN dans mon réseau.
J’ai donc essayé d’envoyer à la Livebox un DHCPv6 Solicit avec deux
délégations, ayant les IAID respectifs 0 et 1. À première vue, ça a l’air de
fonctionner, car je reçois bien deux préfixes /64 dans le DHCPv6 Advertise
avec lequel la Livebox me répond.
Mais je suis alors tombé sur un autre bug de la Livebox : en passant d’un seul
préfixe avec l’IAID 0 à deux préfixes avec les IAID 0 et 1, celui associé à
l’IAID 0 perd toute connectivité à Internet (du moins, il ne m’est plus
possible de pinger une autre machine en IPv6 avec) mais l’autre fonctionne.
En somme, quand un routeur délégataire demande plusieurs délégations de
préfixes, toutes sont accordées, mais seule la dernière apparaissant dans le
message DHCPv6 Solicit est routable. Impossible, donc, de faire router sept /64 en
IPv6 par la Livebox vers mon routeur !
La fonction a-t-elle été testée ?
Je note aussi qu’il est impossible de désactiver la fonction. Après avoir
décoché la case « Activer la délégation de préfixe IPv6 » puis cliqué sur
« Enregistrer », j’avais fait un test en envoyant un DHCPv6 Solicit avec
l’option IA_PD : la box répond quand même avec un IA_PD dans son DHCPv6
Advertise.
Ensuite, comme on peut le voir sur les captures d’écran plus haut dans ce
billet, il semble que les informations affichées sur la page sont
incomplètes : deux champs auraient dû afficher des informations d’adressage et
de préfixes, mais ceux-ci n’apparaissent pas.
Conclusion
En l’état, la fonction de délégation de préfixes IPv6 telle que faite par la
Livebox est un pas vers la bonne direction, mais sa mise en œuvre est encore
loin d’être satisfaisante et ne me permet pas encore de relier mon réseau
domestique à IPv6.
On dirait que la fonction a été développée à la va-vite, avec pour objectif de
cocher une case sur une plaquette marketing avant tout, et sans tenir
réellement compte des besoins et des cas d’utilisation de ce genre de
fonctions. Le résultat est donc une bonne idée, mais insuffisamment testée,
mal exécutée et à côté de la plaque. Dommage, parce que j’apprécie beaucoup
qu’Orange ait la générosité de donner un /56 à chaque abonné !
Si je devais concevoir une fonction similaire sur une box d’opérateur,
j’aurais prévu une interface de configuration permettant de lister
précisément, pour un DUID donné, quels sont les préfixes à déléguer, IAID par
IAID, avec une taille allant jusqu’au /56 (et si l’utilisateur sélectionne
le /56, ce sera fait à l’exception du /64 réservé par la box, bien entendu).
Cela permettrait de contrôler quels sont les routeurs ayant le droit de
demander des délégations au sein de son réseau, mais aussi de savoir à
l’avance qui obtient quoi. Ce serait par ailleurs plus simple à mettre en
œuvre d’un point de vue technique, tout en étant moins susceptible d’avoir des
bugs. Enfin, je pense que procéder ainsi couvrirait tous les cas d’usage
possible d’une délégation de préfixes IPv6.
Bien sûr, d’aucuns me diront qu’il y a moult instructions sur des forums comme
lafibre.info qui expliquent comment se passer de la Livebox. Mais c’est
oublier que substituer un routeur tiers à la Livebox revient à mettre une
croix sur la ligne téléphonique fixe, incluse dans l’abonnement et que
j’utilise beaucoup ; et puisque j’ai déjà eu des problèmes quand
j’ai été un peu trop curieux à propos de la téléphonie, ce n’est
pas pour tout de suite. En attendant, il n’y a plus qu’à croiser les doigts
pour qu’un jour, ces bugs soient corrigés.
J’ai récemment eu l’occasion de vendre une de mes photos, dont j’avais fait
tirer une petite série de cinq exemplaires numérotés et signés dans un
laboratoire spécialisé en tirages d’art. Je ne l’avais pas vraiment prévu, car
ça s’était passé au détour d’une conversation.
Cette vente était une petite source d’angoisse, car quand on vend une photo,
il convient de fournir à l’acheteur un certificat d’authenticité, prouvant
l’origine (et l’originalité) de l’œuvre achetée. Ce que je n’avais jamais fait
avant.
Ces certificats d’authenticité sont généralement édités sur des papiers
spéciaux, avec des encres spéciales, accompagnés de filigranes, hologrammes et
autres mesures de sécurité pour en dissuader la falsification. Mais je n’avais
pas du tout le temps pour faire éditer un certificat sous cette forme-là ; je
n’avais qu’une soirée pour fournir à mon acheteur quelque chose de semblable.
Heureusement, puisqu’il a des notions solides en cybersécurité, je savais que
je pouvais improviser quelque chose avec rien d’autre que LaTeX, GPG,
qrencode et ImageMagick.
Mais alors, comment créer ce certificat ?
En guise d’exemple, je vais utiliser la photo ci-dessous, que j’ai prise
récemment :
TGV 2N2-3UF (rame 820), assurant le train 5316 (Le Havre – Marseille),
photographiée le 15 février 2022.
Imaginons que j’aie fait tirer cette photo à dix exemplaires par mon
laboratoire de prédilection, puis que j’aie vendu l’exemplaire numéro 1 de
cette série. Je vais donc préparer un certificat d’authenticité qui reprend
les informations ci-dessous, que je sauvegarde par ailleurs dans un fichier
texte (appelons-le meta.txt) :
Auteur: x0r
Titre: TGV 2N2-3UF (rame 820)
Date de la prise de vue: 15 février 2022
Numéro du tirage: 1/10
Format: 45 × 30 cm
Type d'impression: Piezography - Encres pigmentaires Epson UltraChrome™ HDR
Papier: Platine Fibre Rag 310 g/m² Canson
C’est une bonne idée d’ajouter, sur le certificat, une petite vignette de
l’image en question. Je la prépare donc avec une résolution suffisante pour
apparaître à environ 300 dpi sur la feuille :
Avec tout ça, on a de quoi faire un certificat d’authenticité avec LaTeX ; je
pourrais alors l’imprimer, la signer et m’arrêter là. Mais n’importe qui
pourrait le falsifier, alors que faire ?
C’est là où GPG peut nous aider. Tout d’abord, je signe mon fichier meta.txt
avec GPG :
% gpg --clear-sign meta.txt
J’utilise l’option --clear-sign afin de conserver le contenu de
meta.txt lisible. Le fichier signé, meta.txt.asc, ressemble à ceci :
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Auteur: x0r
Titre: TGV 2N2-3UF (rame 820)
Date de la prise de vue: 15 février 2022
Numéro du tirage: 1/10
Format: 45 × 30 cm
Type d'impression: Piezography - Encres pigmentaires Epson UltraChrome™ HDR
Papier: Platine Fibre Rag 310 g/m² Canson
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEE/JoAQPj3zjdYk5ClL0gWKnq2LYYFAmJ2ZvQACgkQL0gWKnq2
LYZ0RBAAwYLAjfHcz26d9FTJemxWGattypV6m7BReH9n9XDUSP8TR0n0fjgw5sf5
meoddDc5SyXZW8O9wZVYZygnFiZIo98TQCCkWfWgLc2wOPMNKZAT7s1c6kgcFIrU
wldKq0udGtF5psRYWd6pLjgjNFMzB8lk+SPM6zi8pS/9pJcNqrYTCTbB+Pdbbrm2
NJcLwIn6gCRNUtz51dLtWywszej9nmY1E00QqTzBaFzxisGX1S64jiOawprYcNHr
ysrUzKvWTg8ywC9h9g47lP5ZkN++ak87y9iqkojwfky5aVdsfC/S14wB5vADmUEg
9jIbVbG2YWaA9bFPvgw0vCPm/qLGhmQ9ARTHMrLJj6uBkoQQTh98EBvp0oyA38c0
qJNZSt6W5bD/MJyZsZ9HY/yRzpswNa0KLzYH5dFQ2QhmkhnFHJ6VwZTGMNefZFDn
qz058EAWDM3rq7beLz0ksAjImOn8s4dr3k7kA0ydUrqRANZsSl0cUlwKKn5j412v
YuvjCud9oBFtczFbz4K21VKrDlTPRL2q2rQpsX1UZyLezm4MfJTmYd1IEEJrkC/F
6t5xbnlcomAshQK9+3XI96Jog4CMTcSGZwux1VasbsCWmONh9aE6CRmxB3CZuD6x
NMNGcSHVnhH56hjlP/RYv5X9IzRoChh3e4+nvDQVYLRNweoRldk=
=yE6O
-----END PGP SIGNATURE-----
Puis, on en fait un code QR.
% qrencode -r meta.txt.asc -o meta_qr.png
L’ajout de la signature cryptographique multiplie par plus de quatre la taille
de l’entrée : on passe de 249 à 1 131 octets. Mais on reste largement sous la
limite permise par la spécification, car le résultat est un code QR
version 24, de 113 × 113 pixels, alors que les codes QR les plus grands,
appelés « version 40 », ont pour dimensions 177 × 177, soit presque 2,5 fois
la surface d’une version 24.
Comme j’utilise XeLaTeX, il faut d’abord convertir cette image au format PDF :
% convert meta_qr.png meta_qr.pdf
Et ensuite, on peut l’embarquer dans le document. J’y ajoute un paragraphe
décrivant l’utilité de cet énorme QR code, ainsi que l’empreinte de la clef
publique ayant permis de signer les métadonnées.
Et voilà le résultat : un joli document avec toutes les informations à
propos de ma photo vendue, avec une signature électronique qui protège contre
la majorité des fraudes. Une fois imprimée, j’y ajoute juste une signature de
ma propre main, en utilisant une encre indélébile.
En pratique, le code QR a besoin de faire au moins 6,4 cm de côté pour qu’il
puisse être lu par un téléphone. Avec une imprimante à jet d’encre, les points
du QR code peuvent donc avoir tendance à « baver » ; descendre en-dessous de
cette taille risque de rendre ce code QR inexploitable.
Vérification de la signature
Une signature électronique n’aurait que peu d’intérêt s’il n’y avait aucune
façon de la vérifier.
Avec un téléphone Android, c’est facile : il faut d’abord installer une
application de scan de codes QR (j’utilise QR Scanner de SECUSO Research
Group, mais si vous en connaissez d’autres, sans
publicité, qui sont recommandables, je suis tout ouïe), puis
OpenKeychain pour gérer la partie GPG.
Puis il faut importer ma clef publique dans l’application
OpenKeychain (il n’est pas forcément nécessaire de créer des clefs GPG).
Ensuite, pour vérifier ma signature numérique, il faut procéder ainsi :
scannez le QR code, sélectionnez l’icône « Partager », puis l’icône
OpenKeyChain avec la légende « Déchiffrer… ». Vous devriez alors voir à
l’écran l’indication que la signature est bonne.
Après avoir scanné le code QR, on peut vérifier que la signature est
bonne.
Que se passe-t-il si j’essaye de falsifier le contenu du QR Code ? Ici, j’ai
changé le numéro du tirage de 1/10 à 1/30 dans meta.txt.asc, puis j’ai
généré un nouveau code QR. Lorsque je le scanne, le changement est visible
dans le texte en clair… mais OpenKeychain m’affiche un gros avertissement,
indiquant que quelqu’un a modifié le texte.
Mais si je modifie ne serait-ce qu’un caractère, la signature n’est plus
valable.
Conclusion
Vous savez maintenant comment j’ai improvisé un certificat d’authenticité pour
des tirages d’art que je ne pensais pas forcément vendre de façon organisée.
Bien entendu, si j’avais vraiment voulu vendre mes photos de façon habituelle
(autrement dit, si j’avais pris le statut d’artiste-photographe par exemple),
je me serais tourné vers des certificats d’authenticité édité par des services
visant un public de photographes professionnels. Pour les acheteurs, vérifier
un document comme celui-ci nécessite tout de même d’être familiarisé avec GPG,
une compétence que je ne pourrais pas exiger d’acheteurs « lambda ».
Au moins, la seule façon réaliste de frauder serait de générer un document
similaire, mais de tout signer avec une clef qui ne serait pas la mienne.
Seule une personne avertie qui connaîtrait préalablement l’empreinte de ma
vraie clef publique pourrait alors déceler le subterfuge. Mais cette méthode
me donne, pour mon cas d’utilisation, un niveau de protection qui me semble
tout à fait acceptable.
En fabriquant ces certificats d’authenticité, j’ai beaucoup pensé aux
non-fungible tokens (NFT), la nouvelle mode du moment (et bien expliqués
dans cet article). Je ne me suis pas intéressé de plus près à ce
nouvel objet de spéculation, mais pourtant, la question se pose : aurais-je
créé une sorte de « NFT physique » sans le savoir ?
Le contenu du fichier meta.txt.asc tout seul ne suffirait pas pour qualifier
de NFT : j’y ai par exemple omis une empreinte (SHA-512 par exemple) du
fichier JPEG que j’ai fait tirer, car la miniature figurant sur le certificat
joue déjà ce rôle. Ce n’est donc pas meta.txt.asc qui jouerait le rôle de
« NFT physique », mais bel et bien le document imprimé complet. Même si là
encore, ça se discute : cette feuille de papier ne rentrera dans aucune chaîne
de bloc et je ne peux pas non plus y attacher un contrat automatique stipulant
que je touche de l’argent à chaque revente. Mais là, comme ça, c’est déjà pas
mal.