OpenVPN nie znajduje ca.crt mimo że profil się ładuje
Ścieżka profilu nie jest podstawą dla plików w nim zawartych. Zobacz, dlaczego bezwzględny --config nadal zawodzi na ca.crt i jak uruchomienie rozstrzyga odpowiedź.
Usługa startuje, czyta profil bez skarg, a potem umiera na linii, która wygląda na niepowiązaną: nie może otworzyć ca.crt. Nic w certyfikacie się nie zmieniło, a ścieżka profilu w pliku unit jest bezwzględna. Właśnie ta kombinacja jest wskazówką. Podana ścieżka wskazuje jeden plik, a nazwy wewnątrz tego pliku są rozwiązywane zupełnie gdzie indziej, więc uruchomienie, które wygląda w pełni kwalifikowanie, może nadal czytać swoje klucze z katalogu, którego nikt nie zamierzał.
Awaria ma niewiele przyczyn i warto je rozdzielić po kolei: katalog bazowy, który proces faktycznie miał, kontekst uruchomienia usługi oraz uprawnienia lub sandbox wokół pliku, gdy ścieżka jest już poprawna. Każda zostawia inny ślad — w unit, w procesie i w systemie plików.
Ścieżka profilu nie jest katalogiem bazowym
Wyobraź sobie proces, który startuje w /tmp i otrzymuje /etc/vpn/prod/tenant-a.ovpn. Wewnątrz tego profilu linia ca ca.crt nazywa ścieżkę względną. Nic w argumencie, który zlokalizował profil, nie przepisuje tej nazwy, więc proces szuka /tmp/ca.crt i zgłasza brakujący plik.
Myląca jest kolejność błędów. OpenVPN najpierw parsuje konfigurację i otwiera wskazane pliki, gdy do nich dociera, więc literówka w profilu jest zgłaszana, zanim dotknięty zostanie jakikolwiek klucz, natomiast brakujący certyfikat pojawia się dopiero, gdy parsowanie tam dotrze. Profil, który się ładuje, jest więc dowodem poprawności składni, a nie tego, że pliki, które nazywa, zostały znalezione.
Co rozdziela podręcznik: --config i --cd
Podręcznik OpenVPN 2.6 opisuje dwie różne opcje. Jedna ładuje plik konfiguracji. Druga zmienia katalog procesu, zanim zostaną odczytane konfiguracja, klucz, skrypt i inne pliki, i wymaga katalogu bezwzględnego bez odwołania do bieżącego.
openvpn --cd /etc/vpn/prod --config tenant-a.ovpn
To wywołanie jest formą, nie poleceniem uruchomienia cudzego profilu. Daje determinizm: podstawa każdej względnej nazwy w łańcuchu jest podana w poleceniu, zamiast być odziedziczona po powłoce lub menedżerze, który uruchomił proces. Alternatywa jest równie ważna i często lepsza dla usługi: zostaw katalog roboczy w spokoju i uczyń każdy wskazany plik bezwzględnym wewnątrz profilu.
Cokolwiek wybierzesz, przejrzyj cały łańcuch, a nie pierwszy błąd. Profil może wciągnąć inny plik konfiguracji, a względne nazwy dołączonego pliku są rozwiązywane względem tego samego katalogu procesu, nie względem katalogu pliku, który je dołączył. Ścieżki logów, pliki uwierzytelniania i skrypty pomocnicze podlegają tej samej regule.
Usługa startuje gdzie indziej
Interaktywna powłoka w katalogu profilu niczego nie dowodzi o spakowanym unit. Menedżery ustawiają własny katalog roboczy, a skrypt opakowujący może go ponownie zmienić, zanim uruchomi się plik binarny. Unit, który zawodzi, jest jedynym uruchomieniem, o którym warto rozumować.
systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd
Drugie polecenie pokazuje katalog, który żywy proces faktycznie trzyma, i jest to bardziej wiarygodne niż plik unit, gdy w grę wchodzi opakowanie. Jeśli oba się nie zgadzają, opakowanie jest odpowiedzią, a unit fałszywym tropem.
Po wyszukaniu: uprawnienia, chroot i sandbox
Poprawny katalog bazowy nadal może dać ten sam komunikat, bo rozwiązywanie i dostęp to osobne kroki. Proces potrzebuje prawa wykonania na każdym katalogu nadrzędnym i prawa odczytu pliku, a unit usługi, który ukrywa część systemu plików, zmienia to, co proces w ogóle może zobaczyć.
Trzy typowe warianty dają identyczny błąd. Plik jest czytelny tylko dla root, podczas gdy usługa zrzeka się uprawnień przed jego otwarciem. Unit ustawia ochronny widok systemu plików, który nie obejmuje katalogu profilu. Demon działa z chroot, więc ścieżka istniejąca na hoście nie istnieje w tym widoku.
Diagnozuj po właścicielu pliku i tożsamości procesu, a nie przez luzowanie uprawnień. Uczynienie klucza prywatnego czytelnym dla wszystkich, by uciszyć ten błąd, zamienia głośną awarię na cichą, a klucz jest właśnie tą częścią katalogu, którą najmniej chcesz ujawnić.
Udowodnij poprawkę własnym uruchomieniem
Zrestartuj prawdziwy unit z katalogu niezwiązanego z profilem i obserwuj tę samą linię startową. Następnie potwierdź, że proces podczas działania trzyma zamierzony katalog, a załadowany certyfikat jest tym, którego oczekujesz.
systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager
Gdy ładowanie ścieżek się powiedzie, uwierzytelnianie i routing nadal są osobnymi etapami z własnymi awariami, a połączenie, które wstaje, ale nie przepuszcza ruchu, to inne śledztwo. Poprawka tutaj dotyczy tylko tego, z którego katalogu przyszły pliki, i powinna być widoczna w wywołaniu, a nie pamiętana przez tego, kto ostatnio uruchamiał je ręcznie.
Jeśli profil jest wdrażany przez menedżer konfiguracji, umieść tam także katalog bazowy lub bezwzględne nazwy plików. Ręczna poprawka na jednym hoście to wersja tego problemu, która wraca po następnej przebudowie.