OpenVPN weigert de eerste regel? Het bestand is waarschijnlijk UTF-16
Een fout op de eerste regel met vreemde tekens betekent meestal dat het profiel als UTF-16 is opgeslagen. Lees de eerste bytes en converteer het bestand daarna goed.
De fout wijst naar de eerste regel van een .ovpn-bestand en citeert iets dat op door elkaar geraakte letters lijkt waar client hoort te staan. Het bestand opent prima in je editor, de eerste regel leest client, en de richtlijn is volkomen gewoon. Beide waarnemingen zijn waar, omdat de editor de bytes decodeert en de client dat niet doet. Wat je ziet is bijna altijd een coderingsprobleem, geen syntaxprobleem.
De mythe: de editor toont je het bestand
Een teksteditor decodeert bytes naar tekens met een codering die hij ofwel detecteert ofwel raadt. Als hij UTF-16 raadt, ziet het bestand er perfect uit op het scherm terwijl de onderliggende bytes paren zijn, met een nulbyte na elke Latijnse letter. OpenVPN leest die bytes als tekens, en de mismatch verschijnt bij de eerste richtlijn die het probeert te parseren.
Dus de zichtbare regel en de afgeleverde regel zijn twee verschillende dingen. De vreemde tekens wissen die je ziet is een wijziging van de weergave, niet van de codering, en de volgende parse mislukt om dezelfde reden met een iets andere melding. Daarom leidt de jacht op het token in de fout steeds nergens heen. De bytes zijn fout bij de bron, en elke lezer stroomafwaarts raadt dezelfde kapotte reeks.
De specifieke vorm van de fout is de moeite waard te herkennen, want die is op een bepaalde manier diagnostisch. Een token helemaal aan het begin van het bestand, in een profiel dat verder op andere machines heeft gewerkt, is een kwestie van bytevolgorde en niet van woordenschat.
Wat de eerste bytes werkelijk zeggen
Lees de bytes in plaats van de tekens. Twee kleine commando’s beslechten het in seconden, en geen van beide vereist dat je het bestand opent in een toepassing die het kan wijzigen:
file client.ovpn
head -c 24 client.ovpn | od -An -tx1
Het patroon dat je zoekt is een paar voorloopbytes gevolgd door tekst waarin elke tweede byte nul is. FF FE markeert UTF-16 little-endian, FE FF markeert big-endian, en EF BB BF markeert UTF-8 met een byteordermarkering. Een gewoon UTF-8-bestand zonder markering begint direct met de byte van de eerste letter.
Nulbytes tussen de letters zijn de aanwijzing. In UTF-16 little-endian neemt het woord client twaalf bytes in beslag in plaats van zes, omdat elk ASCII-teken door een nul wordt gevolgd. Die structuur kan een editorscherm je niet laten zien, en die kan een verwijdering van twee bytes niet weghalen.
Hier zit een belangrijke nuance: de configuratieleser van OpenVPN slaat inderdaad een UTF-8-byteordermarkering aan het begin van een bestand over, zoals de configuratieleser 2.6 laat zien. Die tolerantie geldt precies voor die markering, en ze doet niets voor een UTF-16-bestand waarvan de letters met nullen zijn opgevuld. De twee markeringen als hetzelfde probleem behandelen is de tweede helft van de mythe.
Converteren is opslaan als, niet verwijderen
Bewaar een onaangetaste kopie van het origineel van de operator voordat je iets doet, en werk op een apart bestand. Een profiel kan een privésleutel of accountmateriaal bevatten, dus de kopie is zowel je terugweg als je referentie.
Voer dan een echte coderingsconversie uit, hetzij via het expliciete coderingsmenu van de editor, hetzij met een converter die zijn invoer- en uitvoercodering vermeldt:
iconv -f UTF-16 -t UTF-8 client.ovpn > client-utf8.ovpn
file client-utf8.ovpn
Controleer het resultaat in plaats van te vertrouwen op de exitstatus van het commando. De conversie hoort elke richtlijn te behouden, en ze moet elk ingebed certificaat- of sleutelblok byte voor byte binnen zijn markeringen behouden. PEM-gegevens opnieuw omwikkelen, regeleinden binnen een blok wijzigen of het profiel tijdens de conversie herformatteren schept een nieuw probleem terwijl het oude wordt opgelost.
Wijs de client of dienst naar het geconverteerde bestand en kijk naar de eerste fout die hij meldt. Als het door elkaar geraakte token weg is, is het coderingswerk klaar en is alles wat daarna mislukt een andere kwestie.
Wat een gerepareerde codering niet repareert
Codering bepaalt hoe tekst wordt gelezen; ze zegt niets over of de opties geldig zijn voor de client voor je. Een profiel dat voor een andere implementatie is geëxporteerd kan schoon worden geparseerd en toch worden geweigerd vanwege een optie die de draaiende build niet ondersteunt, of vanwege een richtlijn waarvan het argument in die client iets anders betekent.
Die latere fouten verdienen hun eigen onderzoek: de exacte spelling, de syntaxis van het argument en de versie die het accepteert. Beschouw een geslaagde parse niet als een geslaagd profiel.
Houd het onderzoek lokaal terwijl je bezig bent. Openbare online converters en geplakte hex-dumps zijn een slechte plek voor een bestand dat een privésleutel kan bevatten, want het coderingsprobleem is makkelijk te verhelpen en een gelekte sleutel niet.