Jakich uprawnień Linux potrzebuje twój proces VPN?
Konfiguracja interfejsu, trasy, dostęp do urządzeń i zwykłe sockety to odrębne uprawnienia. Nazwij operację, która się nie powiodła, zanim przyznasz CAP_NET_ADMIN.
Demon VPN potrzebuje uprzywilejowanych operacji sieciowych, choć zwykłe aplikacje otwierają sockety wychodzące zupełnie bez uprawnień. Właśnie w tej luce zaczyna się większość błędów z uprawnieniami: ktoś widzi błąd dostępu, przyznaje cały zestaw, a usługa działa z powodów, których nikt później nie potrafi wyjaśnić. Poniższy przewodnik zaczyna się od nieudanej operacji, przypisuje ją do jednego uprawnienia, a następnie sprawdza kontekst, w którym proces faktycznie działa. Działanie jako nieograniczony root jest dla niektórych wdrożeń poprawną odpowiedzią, ale powinno być decyzją, a nie domyślnym ustawieniem.
Zacznij od operacji, która się nie powiodła
Przeczytaj błąd, zanim przeczytasz poradnik. „Operacja niedozwolona” przy zmianie interfejsu, odmowa otwarcia węzła urządzenia i niepowodzenie bind na niskim porcie to trzy różne problemy z trzema różnymi zgodami. Jeśli proces startuje i zawodzi dopiero przy pierwszej zmianie trasy, oznacza to też, że utworzenie interfejsu już się udało, co znacznie zawęża odpowiedź.
Odtwórz błąd przy zatrzymanej usłudze, a następnie uruchom ją na pierwszym planie pod tym samym użytkownikiem, jeśli implementacja na to pozwala. Błąd, który widzisz, jest lepszy niż linia logu, którą trzeba zgadywać, i jasno pokazuje różnicę między problemem z uprawnieniami a odmową SELinux lub AppArmor.
Przypisz każdą operację do jednego uprawnienia
Tabela to mapa startowa, a nie zamiennik dokumentacji implementacji:
| Operation | Usual authority | Watch for |
|---|---|---|
| Create or configure tun/tap | CAP_NET_ADMIN in the relevant namespace | Creating the device and opening it are separate steps |
| Add routes, rules, firewall entries | CAP_NET_ADMIN | Same capability, different namespace than you think |
| Open /dev/net/tun | Device permissions, not a capability | Group membership or a udev rule may be enough |
| Raw sockets | CAP_NET_RAW | Needed by some user-space tunnel implementations |
| Bind a port below 1024 | CAP_NET_BIND_SERVICE | Irrelevant for most modern tunnel ports |
Dwa wiersze w tej tabeli to te, które ludzie mylą. Otwarcie /dev/net/tun to kwestia uprawnień do pliku; proszenie jądra o skonfigurowanie tego, co otworzyłeś, to kwestia uprawnień procesu. Przyznanie CAP_NET_ADMIN nie naprawia węzła urządzenia, którego użytkownik usługi nie może odczytać, a naprawa węzła nie daje uprawnień do tras. Sprawdź oba, zanim zmienisz którykolwiek.
WireGuard w jądrze i programy tunelowe w przestrzeni użytkownika też nie mają identycznych wymagań. Ścieżka modułu jądra konfiguruje istniejący interfejs przez netlink, podczas gdy implementacja w przestrzeni użytkownika może potrzebować także urządzenia, a dla niektórych transportów surowych socketów.
Przeczytaj kontekst: usługa, kontener czy powłoka
Uprawnienie w przestrzeni nazw sieci hosta może wpłynąć znacznie bardziej niż ta sama operacja w celowo odizolowanym stosie. Środowisko uruchomieniowe kontenerów zwykle startuje z ograniczonym zbiorem granic; dodanie NET_ADMIN do kontenera współdzielącego sieć hosta to znacznie większa zgoda niż dodanie go do kontenera z własną przestrzenią nazw sieci i bez montowań hosta.
W jednostkach systemd czytaj to, co jest naprawdę stosowane, a nie to, co zdaje się mówić plik jednostki: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities raportuje wartości efektywne, które może ustawić zapomniany drop-in. Pytaj o wartość efektywną, nigdy o zamierzoną. Uprawnienia ambient mają znaczenie, bo usługa bez roota traci uprawnienia przy exec bez nich.
Jako podstawę przyjmij obsługiwaną konfigurację pakietu lub obrazu. Nie dodawaj uprawnień do surowych socketów ani trybu uprzywilejowanego tylko dlatego, że inny poradnik wymienił je dla innego narzędzia; takie rozumowanie niczego nie przenosi i kosztuje cię izolację, za którą zapłaciłeś. W razie wątpliwości nie przyznawaj niczego i przeczytaj notatki implementacji dla dokładnie tej operacji, której potrzebujesz.
Obserwuj, co dzieje się po spadku uprawnień
Wiele demonów startuje z uprawnieniami, konfiguruje interfejs, a potem przechodzi na użytkownika bez uprawnień i utrzymuje tunel. Od tego momentu proces nie może już dodać trasy, przepisać reguły firewalla ani otworzyć nowego uprzywilejowanego urządzenia, co jest w porządku, dopóki ponowne połączenie nie wymaga dokładnie tego. Późniejsze odczyty plików i uruchamianie hooków mogą zawieść z tego samego powodu.
Testuj cały cykl życia, a nie pierwszą sekundę: start, odnowienie lub ponowne połączenie i sprzątanie przy zatrzymaniu. Pierwsze udane utworzenie interfejsu nie dowodzi, że każda późniejsza uprzywilejowana operacja nadal będzie działać, a awaria zwykle pojawia się godziny później na produkcji.
Implementacje, które utrzymują tunel otwarty podczas zmiany użytkownika, zwykle łączą to z opcjami zachowania tunelu i kluczy. Po stronie systemd równoważne pytanie brzmi, czy zbiór uprawnień jednostki przetrwa skonfigurowaną zmianę użytkownika.
Zapisz przyznane uprawnienie i jego powód
Zapisz dokładne uprawnienie, operację, którą umożliwia, i błąd, który naprawiło. Jedna linijka w notatkach wdrożeniowych — „CAP_NET_ADMIN w przestrzeni nazw sieci jednostki, potrzebne do zmian tras po ponownym połączeniu” — wystarczy, by powstrzymać następną osobę przed ponownym rozszerzeniem uprawnienia.
Potem po każdej aktualizacji przeczytaj ponownie zbiór efektywny. Dostawcy dodają funkcje, obrazy zmieniają wartości domyślne, a uprawnienie niepotrzebne w zeszłym roku może stać się nośne, zanim ktokolwiek to zauważy.