Dlaczego openssl rand nie potrafi utworzyć klucza, którego chce tls-crypt
OpenSSL tworzy losowe bajty; tls-crypt wymaga ustrukturyzowanego pliku klucza statycznego, a tls-crypt-v2 wymaga klucza, który tylko serwer może opakować. Użyj openvpn --genkey.
OpenSSL jest już zainstalowany, host ma entropię, a generowanie nim klucza wydaje się oczywistym skrótem. Wynik będzie losowy i tajny i całkowicie bezużyteczny, a błąd pojawi się jako błąd kanału sterującego, a nie jako coś, co wspomina o formacie klucza. To właśnie to mylenie jest kosztowną częścią, bo wysyła ludzi do sprawdzania ich szyfrów. To, co czyta VPN, to konkretna struktura pliku, a nie dowolny blok bajtów, a jednego wariantu tej funkcji nie da się w ogóle wytworzyć poza serwerem.
Jaki naprawdę musi być plik na dysku
Plik klucza statycznego OpenVPN to tekst. Zaczyna się wierszem komentarza, który deklaruje, czym jest, przenosi dane szesnastkowe w wierszach o stałej szerokości i liczy łącznie 256 bajtów materiału klucza. OpenVPN czyta go jako wspólny sekret kanału sterującego, nie jako certyfikat, nie jako frazę hasła i nie jako coś, co rozpoznałaby biblioteka TLS.
Ten sam typ obiektu obsługuje obie funkcje kanału sterującego. W tls-auth każdy peer potrzebuje także kierunku, aby pakiety jednej strony nie mogły zostać odbite z powrotem do niego. W tls-crypt jeden wspólny sekret szyfruje i uwierzytelnia kanał sterujący w obu kierunkach, co ukrywa uzgadnianie połączenia, a zarazem je chroni.
Nic z tego nie jest tajną wiedzą, a format nie jest sednem. Sednem jest to, że plik musi dokładnie odpowiadać temu, czego oczekuje czytelnik: nagłówek, szerokość wiersza, końcowy znak nowej linii i całkowita długość. Plik przesunięty o jeden wiersz wczytuje się jako śmieci albo w ogóle zawodzi. Porównanie dwóch peerów bajt po bajcie jest więc uzasadnionym pierwszym testem i jest szybsze niż czytanie któregokolwiek z dwóch plików konfiguracji.
Obsługiwany sposób utworzenia jednego
Wygeneruj zwykły klucz statyczny narzędziem, które go użyje, a następnie odwołaj się do niego z obu stron:
openvpn --genkey secret /etc/openvpn/tc-shared.key
tls-crypt /etc/openvpn/tc-shared.key
Pisownia opcji zmieniała się z czasem: starsze instalacje z ery 2.4 używały formy z osobną flagą przed nazwą pliku, a obecne kompilacje akceptują krótszą. Tak czy inaczej wynikowy plik jest tym samym typem obiektu, więc sprawdzeniem jest to, czy oba peery mają identyczne bajty.
Druga generacja dodaje strukturę, której nie wymyśli żaden zewnętrzny generator. Klucz serwera powstaje raz, a każdy klient otrzymuje opakowany klucz z niego wyprowadzony:
openvpn --genkey tls-crypt-v2-server /etc/openvpn/tc-v2-server.key
openvpn --genkey tls-crypt-v2-client /etc/openvpn/laptop1.key --tls-crypt-v2 /etc/openvpn/tc-v2-server.key
To, co otrzymuje klient, nie jest zduplikowanym własnym kluczem serwera. To opakowany obiekt niosący metadane, które tylko serwer może rozpakować, i właśnie to opakowanie jest powodem, dla którego plik dla jednego urządzenia można unieważnić bez dotykania żadnego innego urządzenia. Trzymaj klucz serwera na serwerze i traktuj go jako korzeń tego zaufania na urządzenie.
Gdzie załamują się bajty zrobione ręcznie
Wydrukowanie 256 losowych bajtów jako szesnastkowych pod poprawnym nagłówkiem teoretycznie dałoby wczytywany plik klucza statycznego. To nadal zły pomysł. Każdy szczegół formatowania staje się okazją do wytworzenia materiału, który zawodzi przy wczytywaniu albo, co gorsza, zostawia dwa peery z różnymi wartościami, które ujawniają się dopiero jako błąd uwierzytelniania.
Z wariantem v2 nic równoważnego nie jest możliwe. Opakowany klucz klienta istnieje tylko jako wynik procesu klucza serwera, a serwer zachowuje materiał potrzebny do jego rozpakowania. Losowy blok zostanie odrzucony albo po prostu nie da się odszyfrować, i żaden z tych dwóch komunikatów nie wspomni o losowości.
Zgodność wersji stoi na tym wszystkim. Pierwsza generacja wymaga wydania, które obsługuje ją po obu stronach, a druga znów wymaga nowszego wydania. Klient zbudowany przed istnieniem tej funkcji nie może ukończyć uzgadniania połączenia z serwerem, który akceptuje tylko opakowany materiał, a zgłaszany błąd wskazuje na kanał sterujący, a nie na wersję.
Rotacja bez zamykania wszystkich na zewnątrz
Rotacja jednego wspólnego sekretu to ćwiczenie z koordynacji, a nie techniczne. Każdy klient musi mieć plik zastępczy w ręku, zanim serwer wycofa poprzedni, a każda maszyna, która wciąż ma starą wartość, zawodzi w tej chwili. Nie zaczynaj tej rotacji w środku dnia pracy.
W układzie v2 rotacja odbywa się na urządzenie: wydaj nowy opakowany klucz dla jednej maszyny i wycofaj stary tylko dla tej maszyny. To główny argument za przejściem, gdy każdy klient jest na wydaniu, które to obsługuje.
Uprawnienia plików należą do tej samej rozmowy. Klucz powinien być czytelny tylko dla konta, które uruchamia usługę, i nie powinien mieszkać w tym samym repozytorium co profile, które chroni. Dokumentacja OpenVPN 2.6 opisuje formy generowania i sekcje materiału klucza, co jest lepszym źródłem niż skopiowane polecenie z postu na forum.