tls-auth key-direction: 0 i 1 muszą się różnić, nie zgadzać
Przy tls-auth oba końce potrzebują przeciwnych kierunków, 0 i 1, albo oba muszą pominąć to ustawienie. Ten sam numer zawodzi, a tls-crypt nigdy go nie używa.
Jedna strona tunelu podpisuje kanał sterujący slotem klucza, którego druga strona nigdy nie sprawdza, i połączenie umiera z błędem uwierzytelniania, zanim wymieniony zostanie choćby jeden certyfikat. Tak wygląda niezgodność kierunku w tls-auth i jest ona deterministyczna: te same dwa pliki zawodzą przy każdej próbie, z każdej sieci. Nic w logu nie nazywa opcji, której szukasz, dlatego ludzie odtwarzają klucze i ponownie wystawiają certyfikaty, które nigdy nie były zepsute. Rozwiązaniem jest uczynienie obu końców komplementarnymi albo pozostawienie obu dwukierunkowymi, a nie osłabianie weryfikacji.
Awaria następuje przed certyfikatami
Przy tls-auth obie strony mają ten sam współdzielony klucz i każda używa jednego z dwóch wyprowadzonych z niego slotów: jeden slot podpisuje wychodzące pakiety sterujące, drugi weryfikuje przychodzące. Kierunek 0 i kierunek 1 przypisują te role w odwrotnej kolejności, więc para musi być komplementarna, aby kontrole HMAC się zgadzały. Gdy przypisanie zostanie odwrócone po jednej stronie, odbiorca szuka podpisu w niewłaściwym slocie i odrzuca pakiet. Sesja kończy się tam, dlatego błąd dotyczy uwierzytelniania pakietów, a nie czegoś, co wygenerowałby magazyn certyfikatów.
Determinizm jest ważny dla diagnostyki, bo problem z czasem lub trasą zostawia inny ślad: sporadyczne przerwy, awaria jednego kierunku albo sesja, która umiera tylko w określonej sieci. Niezgodność kierunku zawodzi przy pierwszym uścisku dłoni za każdym razem i zawodzi identycznie na innym komputerze z tymi samymi dwoma plikami. Czytaj log przy --verb 4 i znajdź pierwszy odrzucony pakiet, a nie ostatnią linię. Jeśli to odrzucenie następuje przed jakąkolwiek wymianą certyfikatów, współdzielony klucz i jego kierunek to dwie rzeczy warte sprawdzenia.
| What you see | What it rules out | Next check |
|---|---|---|
| Authentication error before any certificate is sent | The data channel is irrelevant; the control channel never authenticated | Compare tls-auth and its direction on both ends |
| Certificate or handshake failure after the control channel authenticates | The shared key and its direction already agree | Check the CA, the certificate dates and the hostname |
| Session completes but throughput or cipher warnings appear | Direction was never the problem | Compare the data-channel cipher settings |
| Startup stops on an options error | The number itself is not the issue | Re-read the inline versus external directive syntax |
Gdzie mieszka numer
Podręcznik OpenVPN 2.6 dokumentuje dwa miejsca dla kierunku: drugi argument tls-auth, gdy klucz jest w osobnym pliku, oraz osobny wiersz key-direction, gdy klucz jest wbudowany w profil. Oba ustawiają tę samą wartość, więc profil powinien używać jednej formy albo drugiej, nigdy obu. Pominięcie też jest wyborem i ustawia oba końce w układzie dwukierunkowym, który działa, gdy żadna strona nie podaje kierunku. Dwa końce z tym samym numerem nie są w tym układzie: każdy oczekuje podpisywania w jednym slocie i weryfikacji w drugim, i oba robią to tak samo.
# server.conf, external key tls-auth ta.key 0 # client.ovpn, external key tls-auth ta.key 1 # client.ovpn, inline key key-direction 1
Forma wbudowana to dyrektywa w osobnym wierszu, nie atrybut znacznika otwierającego blok klucza, a dodanie argumentu do tego znacznika jest błędem, nie zmianą kierunku. Znaczenie ma też umiejscowienie: dyrektywa stoi poza blokiem, do którego należy, więc wartość zapisana wewnątrz bloku jest czytana jako materiał klucza. Kopiuj układ, który zamierzył dystrybutor profilu, zamiast wymyślać parę, bo profil działający wobec jednego serwera może już być odbity po drugiej stronie.
Czego opcja nie rusza
Nie szyfruje ruchu aplikacji. tls-auth dodaje HMAC wokół pakietów kanału sterującego, a kanał danych chronią klucze sesji negocjowane podczas uścisku dłoni, więc pytanie o przepustowość lub szyfr nie ma nic wspólnego z numerem kierunku. Ustawienie nie dodaje też drugiej warstwy szyfrowania, i właśnie to założenie wysyła ludzi na poszukiwanie dłuższego klucza.
Nie dotyczy tls-crypt, innego mechanizmu kanału sterującego z własnymi opcjami i obsługą kluczy, i nic nie mówi o tożsamości certyfikatu żadnej strony. Działające dopasowanie kierunku dowodzi więc tylko, że oba końce zgadzają się co do sposobu uwierzytelniania kanału sterującego, a nie że łańcuch zaufania został zweryfikowany.
Wyrównaj parę, potem połącz ponownie
Porównaj obie konfiguracje, zanim zmienisz którąkolwiek, bo edycja strony, która była już poprawna, podwaja pracę. Poniższy grep pokazuje, który mechanizm wybiera każdy plik; szczegółowe uruchomienie pokazuje, czy kanał sterujący w ogóle został uwierzytelniony. Zachowaj oba wyjścia, aby następną zmianę można było porównać ze znanym stanem.
grep -n -E 'tls-auth|tls-crypt|key-direction' server.conf client.ovpn openvpn --config client.ovpn --verb 4 2>&1 | grep -i -E 'hmac|tls error|control channel'
Po każdej zmianie uruchom ponownie oba końce, bo te opcje są czytane raz przy starcie, a przeładowanie jednej strony pozostawia parę niespójną przez cały czas życia starej sesji. Jeśli wdrożenie działa teraz bez skonfigurowanego kierunku, dodanie ustawienia po jednej stronie odtwarza awarię, od której zaczęliście; albo zostaw oba, albo skonfiguruj oba. Zmieniaj jeden koniec naraz i zachowaj poprzedni plik, aby regresja była dwuminutowym wycofaniem, a nie przebudową.
Zapisz mechanizm, plik klucza i kierunek dla każdego końca w notatkach wdrożeniowych, bo inaczej następna osoba przeczyta dwa podobne pliki i założy, że numery muszą do siebie pasować. Kierunek to szczegół koordynacji, nie ulepszenie bezpieczeństwa: oddziela dwa kierunki kanału sterującego i nic więcej nie robi.