L’erreur pointe la première ligne d’un fichier .ovpn et cite quelque chose qui ressemble à des lettres brouillées là où client devrait se trouver. Le fichier s’ouvre parfaitement dans votre éditeur, la première ligne se lit client, et la directive est tout à fait ordinaire. Les deux observations sont vraies, car l’éditeur décode les octets et le client ne le fait pas. Ce que vous voyez est presque toujours un problème d’encodage, pas un problème de syntaxe.

Le mythe : l’éditeur vous montre le fichier

Un éditeur de texte décode les octets en caractères avec un encodage qu’il détecte ou devine. Quand il devine UTF-16, le fichier paraît parfait à l’écran alors que les octets sous-jacents sont des paires, avec un octet nul après chaque lettre latine. OpenVPN lit ces octets comme des caractères, et la discordance apparaît à la première directive qu’il tente d’analyser.

Ainsi la ligne visible et la ligne livrée sont deux choses différentes. Supprimer les caractères étranges que vous voyez modifie l’affichage, pas l’encodage, et l’analyse suivante échoue pour la même raison avec un message légèrement différent. C’est pourquoi la chasse au jeton dans l’erreur ne mène nulle part. Les octets sont faux à la source, et chaque lecteur en aval devine la même séquence cassée.

La forme précise de l’échec mérite d’être reconnue, car elle est diagnostique d’une manière particulière. Un jeton tout au début du fichier, dans un profil qui a sinon fonctionné sur d’autres machines, est une question d’ordre des octets plutôt que de vocabulaire.

Ce que disent réellement les premiers octets

Lisez les octets plutôt que les caractères. Deux petites commandes règlent la question en quelques secondes, et aucune n’exige d’ouvrir le fichier dans une application qui pourrait le modifier :

file client.ovpn
head -c 24 client.ovpn | od -An -tx1

Le motif que vous cherchez est une paire d’octets initiaux suivie d’un texte où chaque second octet est nul. FF FE indique UTF-16 little-endian, FE FF indique big-endian, et EF BB BF indique UTF-8 avec une marque d’ordre des octets. Un fichier UTF-8 simple sans marque commence directement par l’octet de la première lettre.

Les octets nuls entre les lettres sont l’indice. En UTF-16 little-endian, le mot client occupe douze octets au lieu de six, car chaque caractère ASCII est suivi d’un zéro. Cette structure n’est pas quelque chose que l’affichage d’un éditeur peut vous montrer, et ce n’est pas quelque chose qu’une suppression de deux octets peut enlever.

Une nuance importante se cache ici : le lecteur de configuration d’OpenVPN ignore bel et bien une marque d’ordre des octets UTF-8 au début d’un fichier, comme le montre le lecteur de configuration 2.6. Cette tolérance est propre à cette marque, et elle ne fait rien pour un fichier UTF-16 dont les lettres sont remplies de zéros. Traiter les deux marques comme le même problème est la seconde moitié du mythe.

Convertir, c’est enregistrer sous, pas supprimer

Gardez une copie intacte de l’original de l’opérateur avant de faire quoi que ce soit, et travaillez sur un fichier séparé. Un profil peut contenir une clé privée ou des éléments de compte, la copie est donc à la fois votre retour en arrière et votre référence.

Effectuez ensuite une véritable conversion d’encodage, soit via le menu d’encodage explicite de l’éditeur, soit avec un convertisseur qui indique son encodage d’entrée et de sortie :

iconv -f UTF-16 -t UTF-8 client.ovpn > client-utf8.ovpn
file client-utf8.ovpn

Vérifiez le résultat plutôt que de faire confiance au code de sortie de la commande. La conversion doit préserver chaque directive, et elle doit préserver tout bloc de certificat ou de clé intégré octet par octet à l’intérieur de ses marqueurs. Réenvelopper des données PEM, changer les fins de ligne à l’intérieur d’un bloc ou reformater le profil pendant la conversion crée un nouveau problème tout en corrigeant l’ancien.

Pointez le client ou le service vers le fichier converti et regardez la première erreur qu’il signale. Si le jeton brouillé a disparu, le travail d’encodage est terminé et tout ce qui échoue ensuite est une autre question.

Ce qu’un encodage corrigé ne corrige pas

L’encodage détermine comment le texte est lu ; il ne dit rien sur la validité des options pour le client qui est devant vous. Un profil exporté pour une autre implémentation peut s’analyser proprement et être malgré tout rejeté à cause d’une option que la version en cours ne prend pas en charge, ou d’une directive dont l’argument signifie autre chose dans ce client.

Ces erreurs ultérieures méritent leur propre enquête : l’orthographe exacte, la syntaxe de l’argument et la version qui l’accepte. Ne considérez pas une analyse réussie comme un profil réussi.

Gardez l’enquête locale tant que vous y êtes. Les convertisseurs publics en ligne et les vidages hex collés sont un mauvais endroit pour un fichier qui peut contenir une clé privée, car le problème d’encodage est facile à corriger et une clé divulguée ne l’est pas.

Articles similaires