Giv OpenVPN CAP_NET_ADMIN uden at give det root
En unit, der starter som en uprivilegeret bruger, har stadig brug for det rigtige sæt kapabiliteter. Kontroller unit'en, den levende proces og exec-grænsen, i den rækkefølge.
Tjenesten starter, loggen klager over, at den ikke kan åbne tun-enheden, og ruterne dukker aldrig op. Kør capsh --print i din shell, og cap_net_admin er lige der, hvilket får fejlen til at se umulig ud. Det, der adskiller din shell og unit'en, er privilegieovergangen, ikke kernens vilje til at give kapabiliteten. Gå gennem de fire kontroller nedenfor i rækkefølge, og stop ved den første, der forklarer forskellen.
Adskil en manglende kapabilitet fra en skjult enhed
To fejl ser ens ud i loglinjen. En proces uden CAP_NET_ADMIN kan ikke oprette eller konfigurere tunneglinterfacet, og en proces, hvis sandbox skjuler /dev/net/tun, kan slet ikke åbne det. At tilføje kapabiliteter løser ikke det andet tilfælde.
Kontroller, om enheden findes inde i tjenestens namespace, før du redigerer noget. PrivateDevices=yes er en almindelig hærdningslinje, der fjerner tun-noden helt, og en restriktiv ProtectSystem kan gøre konfigurationsstien skrivebeskyttet på en måde, der læses som en tilladelsesfejl. Begge giver loglinjer, der nævner tunnelen, og derfor får kapabiliteterne skylden. Bekræft først, at noden er til stede og kan åbnes, og gå så videre.
Vid, hvilket kapabilitetssæt du kigger på
Linux holder tilladte, effektive, nedarvede, begrænsende og ambiente sæt, og det ambiente sæt er det, der overlever et exec fra en bruger, der ikke er root. Filkapabiliteter på binæren kan overdrage tilladte og effektive rettigheder ved exec, men kun så længe intet i kæden blokerer den overførsel.
Det er her, sudo vildleder folk. En kommando, der køres gennem sudo -u, starter en ny privilegieovergang, og det ambiente sæt er væk, så den samme kontrol, der lykkes som root, fejler der. Tjenestestyringen er endnu en overgang, og den giver intet ambient, medmindre unit'en siger det.
Giv kapabiliteten i unit'en, ikke i en wrapper
En minimal tjenestesektion til en tunnel, der skal oprette en enhed og installere ruter, ser sådan ud.
[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 sætter rettigheden i det ambiente sæt, før processen starter, og CapabilityBoundingSet forhindrer processen i at holde noget uden for den liste. NoNewPrivileges=yes blokerer privilegieopnåelse gennem setuid eller filkapabiliteter, mens den kapabilitet, som unit'en udtrykkeligt giver, stadig gælder. Tilføj kun CAP_NET_BIND_SERVICE, når tjenesten skal binde en lav port, og tilføj aldrig CAP_SYS_ADMIN, fordi en forumtråd gjorde det.
Hvis unit'en wrapper binæren i sudo, skal du fjerne wrapperen. systemd anvender allerede User=, og det ekstra lag er den mest sandsynlige grund til, at det ambiente sæt er tomt.
Verificer mod den levende proces, ikke unit-filen
Læs, hvad styringen faktisk har anvendt, og læs derefter den proces, den har startet.
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")/statusHvis unit'en lister kapabiliteten, og CapEff stadig mangler den, tilsidesætter et drop-in indstillingen, eller et ExecStartPre-trin ændrer miljøet. Søg i drop-in-mapperne efter unit-navnet, før du antager, at hovedfilen er autoritativ, fordi en senere fil vinder i stilhed. Hvis både unit'en og processen viser kapabiliteten, og tunnelen stadig fejler, så gå tilbage til enheds- og stikontrollerne i stedet for at udvide det begrænsende sæt. Udvidelse skjuler den reelle årsag og efterlader tjenesten mere privilegeret, end den var.
Foretræk at droppe privilegier efter opstart
OpenVPN kan starte med privilegier og derefter skifte til en uprivilegeret konto via sine egne user- og group-indstillinger, mens persist-key og persist-tun holder tunnelen brugbar bagefter. Den ordning indsnævrer vinduet, hvor processen har rettigheder, og den passer ofte bedre end at starte hele daemonen uprivilegeret med permanente kapabiliteter.
Uanset hvilken model du vælger, skal du genstarte unit'en og gentage kontrollerne efter en genstart, fordi en tjeneste, der virker fra en interaktiv root-shell og fejler ved opstart, normalt er en forskel i kapabilitet, enhed eller filrettigheder. Noter unit-indstillingerne ved siden af processens kapabilitetsoutput, så den næste anmelder kan se, om en pakkeopdatering eller et drop-in har flyttet grænsen.