Po odebraniu uprawnień: które pliki OpenVPN nadal działają?
Deskryptory otwarte przed odebraniem uprawnień działają dalej; ścieżki otwierane ponownie później nie. Zdecyduj, który z trzech plików czasu działania twoja konfiguracja musi otworzyć ponownie.
Długi czas działania dowodzi tylko, że start się udał z uprawnieniami, które demon miał w tej chwili. Awarie, które tu mają znaczenie, przychodzą później: nowy klient się łączy, lista unieważnień jest podmieniana, skrypt pomocniczy musi zapisać plik. Każda z nich to nowe otwarcie wykonywane przez konto bez uprawnień, z własnym pytaniem o prawa i własnym komunikatem błędu. Trzy decyzje oddzielają konfigurację, która działa dalej, od tej, która zawodzi przy następnym zdarzeniu.
Oddziel to, co wczytano wcześnie, od tego, co otwiera się później
Deskryptor to uchwyt na otwarty opis pliku, a tryb dostępu został ustalony przy tworzeniu tego opisu. Późniejsza zmiana użytkownika procesu nie zamyka uchwytu, dlatego plik klucza odczytany jako root działa także po odebraniu uprawnień. Tryb też się nie zmienia: uchwyt otwarty do czytania nie staje się zapisywalny, a uchwyt zapisywalny nie jest odbierany tylko dlatego, że konto straciło prawa do ścieżki. Te dwa fakty wyjaśniają większość zaskakującego zachowania w tych raportach.
Druga połowa to pamięć. Demon może przeanalizować certyfikat, zachować przeanalizowany materiał i zamknąć plik; w użyciu pozostają dane, a nie otwarty plik. Dlatego trwający ruch nie dowodzi ani tego, że deskryptor jest otwarty, ani że nazwa ścieżki jest osiągalna. Dowodzi tylko, że materiał potrzebny do bieżącej sesji uzyskano wcześniej.
Późniejsze otwarcie to inna transakcja. Odbywa się pod bieżącymi poświadczeniami, bieżącym kontekstem bezpieczeństwa i bieżącym widokiem montowania, więc ścieżka czytelna przy starcie może zostać odrzucona przy następnym połączeniu. Rotacja dodaje pułapkę: zapis nowego pliku pod tą samą nazwą ścieżki pozostawia istniejący deskryptor przypięty do starego obiektu, więc przeładowanie może wyglądać na udane, podczas gdy demon wciąż używa poprzedniej treści. Porównaj inode trzymany przez proces z tym na dysku, zanim uwierzysz w rotację.
Nazwij trzy odczyty czasu działania i moment każdego z nich
Trzy zasoby są zwykle otwierane długo po inicjalizacji i zawodzą w różnych momentach. Plik konfiguracji konkretnego klienta jest czytany, gdy ten klient się łączy, więc może się zepsuć dla jednego użytkownika, podczas gdy pozostali działają. Dane unieważnień są sprawdzane podczas uwierzytelniania partnera i ponownie przy podmianie pliku. Katalog tymczasowy jest dotykany tylko wtedy, gdy skrypt lub wtyczka coś zapisze.
Żaden z trzech nie należy do ścieżki startu, dlatego serwer zdrowy przez tygodnie może zawieść przy następnym połączeniu. Kategoria wskazuje też właściciela poprawki: pierwsze dwa to prawa czytania konfiguracji pod kontem demona, a trzeci to miejsce zapisywalne o wąskim przeznaczeniu.
| Path reopened later | What triggers the open | First sign when it fails |
|---|---|---|
| Client configuration file | A connection for that client identity | One client rejected while others connect |
| Revocation data | Peer authentication, including after replacement | Revoked and valid peers both refused |
| Script or plugin temporary directory | A helper needs to create a file | The helper exits with a path error |
persist-key odpowiada na węższe pytanie, niż większość zakłada. Utrzymuje plik klucza otwarty przez udokumentowane resetowania SIGUSR1 i ping-restart, i nie robi nic dla plików CCD, danych unieważnień, programów pomocniczych ani pełnego restartu procesu. Te nadal podążają własnymi ścieżkami otwierania, pod kontem, które wtedy działa.
Potwierdź konto i widok, który ono naprawdę ma
Zapytaj działającego demona, którego konta używa, zamiast ufać plikowi unit, a potem porównaj odpowiedź z tym, co ustawia unit. Rozbieżność to pierwsza rzecz do rozwiązania, bo każde późniejsze sprawdzenie praw działa jako ten, kim proces jest naprawdę. Następnie przejdź ścieżkę komponent po komponencie; przejście jest oceniane na każdym poziomie, więc czytelny plik w katalogu, przez który nie da się przejść, pozostaje nieczytelny. Końcowy tryb pliku to ostatnie pytanie, a nie pierwsze.
Przestrzenie nazw i piaskownice usług dodają granice, których własność i bity trybu nie opisują. Ścieżka widoczna w twojej powłoce może nie istnieć albo być tylko do czytania w chroot, w przestrzeni nazw montowania lub w unicie ukrywającym katalogi domowe. Moduły bezpieczeństwa dodają kolejną warstwę, więc plik, który wygląda na czytelny, nadal może zostać odrzucony przy otwarciu.
ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/aliceUdany odczyt w powłoce administratora nie testuje żadnego z tych połączonych warunków. Uruchom sprawdzenie jako konto demona, z tą samą przestrzenią nazw i piaskownicą, albo przyjmij, że wynik opisuje twoją powłokę, a nie serwer. Trzecie polecenie to tania wersja tego testu: wypisuje tryb każdego komponentu i zawodzi na pierwszym, przez który konto demona nie może przejść.
Daj zapisowi czasu działania własny katalog
Czytanie to tylko połowa spisu. Skrypt pomocniczy może potrzebować utworzyć plik stanu, wtyczka może potrzebować zapisać stan obok swojej konfiguracji, a tych zapisów nie obejmuje uczynienie drzewa konfiguracji zapisywalnym. Daj konkretnemu katalogowi uprawnienie zapisu, którego wymaga jego funkcja, z właścicielem i trybem, które potrafisz wyjaśnić. Preferuj dostęp tylko do czytania dla wszystkiego, co jest tylko czytane.
Trzymaj uprawnienia klucza prywatnego oddzielnie od plików polityki. Klucz, który trzeba ponownie odczytać po resecie, ma inne wymaganie niż plik klienta czytany przy każdym połączeniu, a jeden łagodny tryb dla obu daje więcej dostępu, niż wymaga problem. Dedykowane konto demona z wąską własnością łatwiej audytować niż szeroką grupę. Gdy klucz musi przetrwać resetowania, persist-key usuwa ponowny odczyt zamiast poszerzać katalog.
Decyduj na podstawie zdarzenia, które możesz odtworzyć
Żywy tunel dowodzi jednej ścieżki w kodzie. Zdarzenie, które potrzebuje pliku, to jedyny test obejmujący otwarcie, na którym ci zależy, czy to nowe połączenie klienta, podmieniony plik unieważnień, dozwolony miękki reset czy zaplanowany restart. Wybierz zdarzenie, wykonaj je i zachowaj pierwszy błąd, a nie ostatni.
Przy miękkim resecie jeden sygnał i dziennik unita pokazują, czy klucz został odczytany ponownie. Wyślij sygnał, a potem przeczytaj ostatnie linie zapisane przez unit:
systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pagerNie wnioskuj, że przejęty demon nie może już zmieniać plików tylko dlatego, że obniżono uprawnienia. To, co jeszcze może, zależy od pozostałych poświadczeń, jego zdolności, katalogów, w których może pisać, i każdego wciąż trzymanego zapisywalnego deskryptora. Redukcja uprawnień zwęża władzę, a spis otwarć czasu działania pokazuje, jak bardzo. Zapisz tę granicę obok konfiguracji, żeby następna osoba nie musiała jej odkrywać ponownie.