OpenVPN odrzuca pierwszą linię? Plik prawdopodobnie jest w UTF-16
Błąd w pierwszej linii z dziwnymi znakami zwykle oznacza, że profil zapisano jako UTF-16. Przeczytaj pierwsze bajty, a następnie poprawnie przekonwertuj plik.
Błąd wskazuje pierwszą linię pliku .ovpn i cytuje coś, co wygląda jak pomieszane litery tam, gdzie powinno być client. Plik otwiera się bez problemu w twoim edytorze, pierwsza linia brzmi client, a dyrektywa jest całkowicie zwyczajna. Oba spostrzeżenia są prawdziwe, ponieważ edytor dekoduje bajty, a klient nie. To, co widzisz, prawie zawsze jest problemem kodowania, a nie problemem składni.
Mit: edytor pokazuje ci plik
Edytor tekstu dekoduje bajty na znaki za pomocą kodowania, które albo wykrywa, albo zgaduje. Gdy zgadnie UTF-16, plik wygląda na ekranie idealnie, podczas gdy bajty pod spodem są parami, a po każdej literze łacińskiej następuje bajt zerowy. OpenVPN czyta te bajty jako znaki, a niezgodność pojawia się przy pierwszej dyrektywie, którą próbuje przeanalizować.
Zatem widoczna linia i dostarczona linia to dwie różne rzeczy. Usunięcie dziwnych znaków, które widzisz, jest zmianą wyświetlania, a nie kodowania, i kolejne parsowanie kończy się niepowodzeniem z tego samego powodu z nieco innym komunikatem. Dlatego pogoń za tokenem z błędu zawsze donikąd prowadzi. Bajty są złe u źródła, a każdy dalszy czytelnik zgaduje tę samą uszkodzoną sekwencję.
Konkretny kształt awarii warto rozpoznać, bo jest diagnostyczny w specyficzny sposób. Token na samym początku pliku, w profilu, który poza tym działał na innych maszynach, jest kwestią kolejności bajtów, a nie słownictwa.
Co naprawdę mówią pierwsze bajty
Czytaj bajty, a nie znaki. Dwie małe komendy rozstrzygają to w kilka sekund i żadna nie wymaga otwierania pliku w aplikacji, która mogłaby go zmienić:
file client.ovpn
head -c 24 client.ovpn | od -An -tx1
Wzorzec, którego szukasz, to para początkowych bajtów, po której następuje tekst, w którym co drugi bajt jest zerem. FF FE oznacza UTF-16 little-endian, FE FF oznacza big-endian, a EF BB BF oznacza UTF-8 ze znacznikiem kolejności bajtów. Zwykły plik UTF-8 bez znacznika zaczyna się wprost od bajtu pierwszej litery.
Bajty zerowe między literami są główną wskazówką. W UTF-16 little-endian słowo client zajmuje dwanaście bajtów zamiast sześciu, ponieważ po każdym znaku ASCII następuje zero. Tej struktury ekran edytora nie może ci pokazać, a usunięcie dwóch bajtów jej nie usunie.
Jest tu ważny niuans: czytnik konfiguracji OpenVPN rzeczywiście pomija znacznik kolejności bajtów UTF-8 na początku pliku, co pokazuje czytnik konfiguracji 2.6. Ta tolerancja dotyczy właśnie tego znacznika i nic nie robi dla pliku UTF-16, którego litery są wypełnione zerami. Traktowanie obu znaczników jako tego samego problemu to druga połowa mitu.
Konwersja to zapis jako, a nie usuwanie
Przed zrobieniem czegokolwiek zachowaj nietkniętą kopię oryginału operatora i pracuj na osobnym pliku. Profil może zawierać klucz prywatny lub dane konta, więc kopia jest jednocześnie twoim wycofaniem i twoim odniesieniem.
Następnie wykonaj rzeczywistą konwersję kodowania, albo przez jawne menu kodowania w edytorze, albo konwerterem, który podaje kodowanie wejścia i wyjścia:
iconv -f UTF-16 -t UTF-8 client.ovpn > client-utf8.ovpn
file client-utf8.ovpn
Sprawdź wynik, zamiast ufać kodowi wyjścia polecenia. Konwersja powinna zachować każdą dyrektywę i musi zachować każdy wbudowany blok certyfikatu lub klucza bajt po bajcie w jego znacznikach. Ponowne zawijanie danych PEM, zmiana końców linii wewnątrz bloku lub przeformatowanie profilu podczas konwersji tworzy nowy problem, naprawiając stary.
Skieruj klienta lub usługę na przekonwertowany plik i spójrz na pierwszy zgłoszony błąd. Jeśli pomieszany token zniknął, praca nad kodowaniem jest skończona, a wszystko, co potem zawiedzie, to inne zagadnienie.
Czego naprawione kodowanie nie naprawia
Kodowanie określa, jak odczytywany jest tekst; nie mówi nic o tym, czy opcje są poprawne dla klienta przed tobą. Profil wyeksportowany dla innej implementacji może się czysto parsować i mimo to zostać odrzucony z powodu opcji, której działająca kompilacja nie obsługuje, albo dyrektywy, której argument znaczy w tym kliencie coś innego.
Te późniejsze błędy zasługują na własne dochodzenie: dokładną pisownię, składnię argumentu i wersję, która go akceptuje. Nie traktuj udanego parsowania jako udanego profilu.
Prowadź dochodzenie lokalnie, dopóki się tym zajmujesz. Publiczne konwertery online i wklejane zrzuty hex to złe miejsce dla pliku, który może zawierać klucz prywatny, bo problem kodowania łatwo naprawić, a wyniesionego klucza nie.