Dać OpenVPN CAP_NET_ADMIN bez przyznawania root
Jednostka uruchamiana jako użytkownik bez uprawnień nadal potrzebuje właściwego zestawu zdolności. Sprawdź jednostkę, działający proces i granicę exec, w tej kolejności.
Usługa startuje, log skarży się, że nie może otworzyć urządzenia tun, a trasy nigdy się nie pojawiają. Uruchom capsh --print w swojej powłoce, a cap_net_admin jest od razu tam, co czyni błąd pozornie niemożliwym. Tym, co różni twoją powłokę od jednostki, jest przejście uprawnień, a nie gotowość jądra do przyznania zdolności. Przejdź przez cztery kontrole poniżej po kolei i zatrzymaj się na pierwszej, która wyjaśnia różnicę.
Oddziel brakującą zdolność od ukrytego urządzenia
Dwa błędy wyglądają w logu tak samo. Proces bez CAP_NET_ADMIN nie może utworzyć ani skonfigurować interfejsu tunelu, a proces, którego sandbox ukrywa /dev/net/tun, w ogóle nie może go otworzyć. Dodanie zdolności nie naprawi drugiego przypadku.
Zanim cokolwiek zmienisz, sprawdź, czy urządzenie istnieje w przestrzeni nazw usługi. PrivateDevices=yes to popularny wiersz utwardzania, który całkowicie usuwa węzeł tun, a restrykcyjny ProtectSystem może uczynić ścieżkę konfiguracji tylko do odczytu w sposób, który czyta się jak błąd uprawnień. Oba tworzą wiersze logu wspominające tunel, dlatego obwinia się zdolności. Najpierw potwierdź, że węzeł istnieje i można go otworzyć, a potem idź dalej.
Wiedz, na który zestaw zdolności patrzysz
Linux utrzymuje zbiory dozwolone, efektywne, dziedziczone, ograniczające i otoczenia, a zbiór otoczenia to ten, który przeżywa exec użytkownika innego niż root. Zdolności pliku na binarium mogą przekazać dozwolone i efektywne prawa przy exec, ale tylko dopóki nic w łańcuchu nie blokuje tego przekazania.
Tu sudo wprowadza ludzi w błąd. Polecenie uruchomione przez sudo -u rozpoczyna nowe przejście uprawnień i zbiór otoczenia znika, więc ta sama kontrola, która udaje się jako root, tam zawodzi. Menedżer usług to kolejne przejście i nie przyznaje nic otoczenia, jeśli jednostka tego nie mówi.
Przyznaj zdolność w jednostce, nie w opakowaniu
Minimalna sekcja usługi dla tunelu, który musi utworzyć urządzenie i zainstalować trasy, wygląda tak.
[Unit]
Description=OpenVPN client, office profile
After=network-online.target
[Service]
Type=notify
User=openvpn
Group=openvpn
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/office.confAmbientCapabilities umieszcza prawo w zbiorze otoczenia, zanim proces się uruchomi, a CapabilityBoundingSet powstrzymuje proces przed trzymaniem czegokolwiek spoza tej listy. NoNewPrivileges=yes blokuje zdobycie uprawnień przez setuid lub zdolności pliku, a zdolność przyznana wyraźnie przez jednostkę nadal obowiązuje. Dodawaj CAP_NET_BIND_SERVICE tylko wtedy, gdy usługa musi związać niski port, i nigdy nie dodawaj CAP_SYS_ADMIN tylko dlatego, że zrobił to jakiś wątek na forum.
Jeśli jednostka opakowuje binarium w sudo, usuń opakowanie. systemd już stosuje User=, a ta dodatkowa warstwa jest najprawdopodobniejszą przyczyną pustego zbioru otoczenia.
Weryfikuj na działającym procesie, nie na pliku jednostki
Przeczytaj, co menedżer faktycznie zastosował, a potem przeczytaj proces, który utworzył.
unit=openvpn-client@office
systemctl show -p User -p AmbientCapabilities "$unit"
systemctl show -p MainPID --value "$unit" | xargs -r getpcaps
grep -E '^Cap(Eff|Amb)' /proc/$(systemctl show -p MainPID --value "$unit")/statusJeśli jednostka wymienia zdolność, a CapEff nadal jej nie ma, jakieś drop-in nadpisuje ustawienie albo krok ExecStartPre zmienia środowisko. Zanim uznasz plik główny za wiążący, przeszukaj katalogi drop-in pod kątem nazwy jednostki, bo późniejszy plik wygrywa po cichu. Jeśli zarówno jednostka, jak i proces pokazują zdolność, a tunel nadal zawodzi, wróć do kontroli urządzenia i ścieżki zamiast rozszerzać zbiór ograniczający. Rozszerzenie go ukrywa prawdziwą przyczynę i zostawia usługę z większymi uprawnieniami niż wcześniej.
Wolej zrzucić uprawnienia po starcie
OpenVPN może wystartować z uprawnieniami, a następnie zejść do konta bez uprawnień przez własne opcje user i group, podczas gdy persist-key i persist-tun utrzymują tunel użytecznym później. Taki układ zawęża okno, w którym proces ma prawa, i często pasuje lepiej niż uruchamianie całego demona bez uprawnień z trwałymi zdolnościami.
Niezależnie od wybranego modelu zrestartuj jednostkę i powtórz kontrole po restarcie, bo usługa, która działa z interaktywnej powłoki root, a zawodzi przy starcie, to zwykle różnica w zdolności, urządzeniu lub uprawnieniach pliku. Zapisz ustawienia jednostki obok wyjścia zdolności procesu, aby następny recenzent widział, czy aktualizacja pakietu albo drop-in przesunęły granicę.