Dwa sklejone przepisy o minimalnych uprawnieniach nie dają ostrzejszego wdrożenia. Jeden model pozwala demonowi startować z uprawnieniami i po inicjalizacji zejść do konta bez uprawnień; drugi pozwala menedżerowi usług uruchomić go z ograniczoną tożsamością już od pierwszej instrukcji. Każdy działa osobno, a połączenie często daje usługę, która nie potrafi czysto wykonać żadnego z dwóch zadań. Reszta przechodzi przez decyzję po kolei.

Dwa modele, jeden właściciel przełączenia

Pierwszy model należy do demona. Opcje OpenVPN w wersji społecznościowej user i group zmieniają tożsamość po skonfigurowaniu tunelu i kluczy, a persist-key wraz z persist-tun utrzymują te zasoby użytecznymi później.

Drugi model należy do menedżera usług. Ustawienie systemd User= lub Group= decyduje o tożsamości, z jaką startuje proces, a dyrektywy zdolności decydują, co może trzymać. Wybór między modelami to kwestia pakowania, zanim staje się kwestią bezpieczeństwa, a opiekun pakietu już na nią odpowiedział. Twoim zadaniem jest znaleźć tę odpowiedź, a nie wymyślać trzecią opcję.

Oba są uzasadnione. Błędem jest traktowanie ich jako warstw jednego projektu, ponieważ drugi model może uczynić zmianę tożsamości z pierwszego operacją, której procesowi nie wolno już wykonywać.

Zdecyduj, gdzie zmienia się tożsamość

Jeśli jednostka już startuje jako dedykowane konto, dodanie instrukcji demona, by stał się innym kontem, wymaga przejścia setuid, którego utwardzona usługa nigdy nie miała wykonywać. Awaria pojawia się jako błąd uprawnień przy starcie, a nie jako jasny komunikat polityki. Czyta się to jak brakująca zdolność, co popycha ludzi ku szerszemu zbiorowi ograniczeń zamiast ku pytaniu o tożsamość.

Przeczytaj, co zainstalowany pakiet faktycznie dostarcza, zanim cokolwiek zmienisz, łącznie z jego katalogiem drop-in. Niektóre jednostki celowo pomijają własne zejście demona, bo menedżer już się tym zajmuje, a inne polegają na tych opcjach przy przełączeniu po inicjalizacji. Usunięcie któregokolwiek z nich bez wiedzy, który model odziedziczyłeś, to sposób, w jaki działająca usługa przestaje startować.

Zapisz wybrany model w jednej linii: należący do menedżera albo do demona. Każda późniejsza dyrektywa musi być spójna z tym zdaniem, a jednostkę mieszaną należy traktować jako błąd, nie kompromis.

Zdolności to granice, nie nadania

Zbiór ograniczeń zdolności mówi, co proces może najwyżej trzymać. To sufit, a wymienienie tam zdolności samo w sobie nic nie daje, dlatego jednostka z hojnym zbiorem ograniczeń wciąż może nie zdołać utworzyć tunelu.

To, co naprawdę umieszcza zdolność w zbiorze otaczającym usługę, to AmbientCapabilities=. Dokumentacja wykonawcza systemd opisuje obie dyrektywy osobno, i ta różnica wyjaśnia większość mylących porad o zdolnościach w sieci.

Dodawaj zdolność dopiero wtedy, gdy zawodząca operacja ją zidentyfikuje. Szerszy zbiór ograniczeń ukrywa prawdziwą przyczynę i zostawia usługę z większymi uprawnieniami, niż zakładał projekt. Utrudnia też przegląd jednostki, bo sufit nie opisuje już pracy. Usuń dodatkową zdolność, gdy prawdziwa usterka zostanie naprawiona.

Zmapuj uprawnienia w cyklu życia

Wymień, co proces musi robić na każdym etapie: start, stan ustalony, ponowne uwierzytelnienie i demontaż. Tworzenie interfejsu, zmiany tras, odczyt chronionego klucza i wywołanie pomocnika nie dzieją się wszystkie w tej samej chwili ani przy tych samych wymaganiach. Posortuj listę według etapu, zanim posortujesz ją według zdolności.

Opcje trwałości zachowują zasoby między renegocjacjami i nie dają uprawnień, których nigdy nie posiadano. Klucz, którego proces nie może odczytać przy starcie, pozostanie nieczytelny także później, cokolwiek mówią flagi trwałości. Flagi zachowują to, co już działało.

Używaj konta dedykowanego, a nie współdzielonego. Twórcy OpenVPN ostrzegają przed nawykiem używania nobody jako ogólnego przykładu, bo inne usługi na hoście mogą już działać na tym koncie, a izolacji, którą uważasz, że masz, tam nie ma.

Funkcje zmieniające lokalne obciążenie, takie jak odciążenie kanału danych czy kompilacja inaczej linkowana, mogą przesunąć to, jakie operacje są potrzebne. Przejrzyj mapę, gdy zmienia się pakiet, nie tylko gdy coś się zepsuje.

Zapisz plan i zachowaj dostęp do odzyskiwania

Zapis wdrożenia powinien wymieniać menedżera, tożsamość startową, zamierzoną tożsamość ustaloną i każde nadanie wraz z operacją, która go wymaga. To ten zapis czyni następną zmianę przeglądalną, a nie eksperymentalną.

Utrzymuj dostęp do konsoli podczas edycji, bo jednostka, która zawodzi przy starcie, jest trudna do naprawy zdalnie. Przetestuj restart i pełny restart przed uznaniem zmiany za zakończoną. Jednostka, która przetrwa restart, nadal może zawieść, zanim sieć będzie gotowa.

Sukces to zrozumiały cykl życia o minimalnych uprawnieniach, a nie proces, który przypadkiem działa pod nazwą inną niż root.

Powiązane artykuły