Storitev se zažene, dnevnik se pritožuje, da ne more odpreti naprave tun, poti pa se nikoli ne pojavijo. Zaženite capsh --print v svoji lupini in cap_net_admin je takoj tam, zaradi česar je napaka videti nemogoča. Kar se razlikuje med vašo lupino in enoto, je prehod privilegijev, ne pripravljenost jedra, da dodeli zmogljivost. Pojdite skozi štiri preverjanja spodaj po vrsti in ustavite se pri prvem, ki pojasni razliko.

Ločite manjkajočo zmogljivost od skrite naprave

Dve napaki sta iz vrstice dnevnika videti enaki. Proces brez CAP_NET_ADMIN ne more ustvariti ali konfigurirati vmesnika tunela, proces, katerega peskovnik skriva /dev/net/tun, pa ga sploh ne more odpreti. Dodajanje zmogljivosti ne bo popravilo drugega primera.

Preden kar koli uredite, preverite, ali naprava obstaja znotraj imenskega prostora storitve. PrivateDevices=yes je pogosta vrstica utrjevanja, ki vozel tun povsem odstrani, omejevalni ProtectSystem pa lahko naredi pot do konfiguracije samo za branje na način, ki se bere kot napaka dovoljenj. Oba ustvarjata vrstice dnevnika, ki omenjata tunel, zato se krivda pripiše zmogljivostim. Najprej potrdite, da vozel obstaja in da ga je mogoče odpreti, nato nadaljujte.

Vedite, kateri nabor zmogljivosti gledate

Linux hrani dovoljeni, dejanski, dedni, omejitveni in ambientni nabor, in prav ambientni nabor preživi exec uporabnika, ki ni root. Datotečne zmogljivosti na binarni datoteki lahko pri exec prenesejo dovoljene in dejanske pravice, a le dokler nič v verigi tega prenosa ne blokira.

Tu sudo zavaja ljudi. Ukaz, zagnan skozi sudo -u, začne nov prehod privilegijev in ambientni nabor izgine, zato isto preverjanje, ki uspe kot root, tam spodleti. Upravitelj storitev je še en prehod in ne dodeli nič ambientnega, če enota tega ne pove.

Dodelite zmogljivost v enoti, ne v ovoju

Minimalni razdelek storitve za tunel, ki mora ustvariti napravo in namestiti poti, je videti takole.

[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.conf

AmbientCapabilities postavi pravico v ambientni nabor, preden se proces zažene, CapabilityBoundingSet pa procesu prepreči, da bi imel kar koli zunaj tega seznama. NoNewPrivileges=yes blokira pridobivanje privilegijev prek setuid ali datotečnih zmogljivosti, medtem ko zmogljivost, ki jo enota izrecno dodeli, še vedno velja. CAP_NET_BIND_SERVICE dodajte le, kadar mora storitev vezati nizka vrata, in nikoli ne dodajte CAP_SYS_ADMIN samo zato, ker je tako storila neka forumska nit.

Če enota ovije binarno datoteko v sudo, odstranite ovoj. systemd že uporablja User=, in ta dodatna plast je najverjetnejši razlog, da je ambientni nabor prazen.

Preverjajte na živem procesu, ne na datoteki enote

Preberite, kaj je upravitelj dejansko uporabil, nato preberite proces, ki ga je ustvaril.

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")/status

Če enota navaja zmogljivost, CapEff pa je še vedno nima, nek drop-in prepisuje nastavitev ali korak ExecStartPre spreminja okolje. Preden glavno datoteko razglasite za merodajno, v mapah drop-in poiščite ime enote, ker poznejša datoteka tiho zmaga. Če zmogljivost kažeta tako enota kot proces, tunel pa še vedno ne deluje, se vrnite k preverjanjem naprave in poti, namesto da bi razširili omejitveni nabor. Njegova razširitev skrije pravi vzrok in pusti storitev bolj privilegirano, kot je bila.

Raje se odpovejte privilegijem po zagonu

OpenVPN lahko začne s privilegiji in nato prek svojih možnosti user in group preide na neprivilegiran račun, pri čemer persist-key in persist-tun ohranita tunel uporaben tudi pozneje. Takšna ureditev zoži okno, v katerem ima proces pravice, in pogosto bolje ustreza kot zagon celotnega demona brez privilegijev s trajnimi zmogljivostmi.

Ne glede na izbrani model znova zaženite enoto in po ponovnem zagonu ponovite preverjanja, ker je storitev, ki deluje iz interaktivne lupine root in ob zagonu spodleti, običajno razlika v zmogljivosti, napravi ali datotečnih dovoljenjih. Zapišite nastavitve enote ob izpisu zmogljivosti procesa, da bo naslednji pregledovalec videl, ali je mejo premaknila posodobitev paketa ali drop-in.

Sorodni članki