Hook deluje, ko ga zaženete ročno kot root, in vrne Operation not permitted v trenutku, ko ga storitev zažene. Datoteka se med tema zagonoma ni spremenila; spremenilo se je okolje. systemd da procesu manjši svet: manj zmožnosti, drugačen /dev, poti datotečnega sistema samo za branje in zgornjo mejo opravil. Napako berite kot mejo, ki je zavrnila eno določeno operacijo, ne kot pokvarjeno skripto.

Začnite pri operaciji, ki je bila zavrnjena

Vrstica dnevnika, da je unit spodletel, vam ne pove skoraj nič. Uporabna vrstica poimenuje klic, ki je bil zavrnjen: vozlišče naprave, ki se ni dalo odpreti, mapa, v katero se ni dalo pisati, imenski prostor, ki se ni dal ustvariti. Poiščite ta klic, preden se dotaknete ene same direktive, ker vsaka ustreza drugi omejitvi. Nato preberite unit, ki je v resnici tekel, vključno z drop-in, namesto datoteke, ki jo je prinesel paket.

Spodnja poizvedba izpiše pot fragmenta, mape drop-in in lastnosti, ki so pomembne pri zavrnitvi naprave ali datotečnega sistema. Preberite jih vse, preden se odločite, katera meja je pomembna:

systemctl show "[email protected]" -p FragmentPath -p DropInPaths -p PrivateDevices -p DevicePolicy -p DeviceAllow -p ProtectHome -p ProtectSystem -p TasksMax
journalctl -u "[email protected]" -b --no-pager | grep -iE 'operation not permitted|permission denied|cannot open|failed'

Nič v tem bloku ne piše. Če zavrnjenega klica ni v dnevniku, za en zagon povečajte podrobnost odjemalca, namesto da ugibate direktive. Delujoč proces dokazuje, da se je unit zagnal, ne da je hook tekel s potrebnimi pravicami.

Imenski prostor potrebuje pravice za mount, ki jih naprava TUN nikoli ne uporablja

Dve operaciji, ki sta znotraj enega hooka videti enaki, imata različna profila dovoljenj. Odpiranje /dev/net/tun in ustvarjanje vmesnika potrebuje upravljanje omrežja in dostop do tega vozlišča. Ustvarjanje poimenovanega omrežnega imenskega prostora potrebuje tudi delo z mount, ker orodje za imenske prostore mounta svež /sys pogled in priveže mapo stanja na njeno mesto. nadrejeni odjemalski unit namenoma pušča upravljanje mounta zunaj svoje množice meja, zato je korak z imenskim prostorom zavrnjen, čeprav bi tunel sam deloval.

Zato dodelitev vozlišča naprave ne reši skripte. Dovoljenje za napravo odgovarja na eno vprašanje, ali ta proces sme odpreti to vozlišče, vprašanje imenskega prostora pa je drugo. Ujemite spodleteli klic z njegovo zmožnostjo, preden karkoli razširite.

Preizkus v vašem shellu podeduje vse zmožnosti, ki jih ima neomejen root, unit pa podeduje tisto, kar je obdržala njegova množica meja. Ta dva zagona sta različna poskusa tudi ko je binarna datoteka enaka.

Naprave, zaščitene poti in zgornje meje opravil

Ko je zavrnjena operacija znana, tri skupine direktiv pojasnijo večino spodletelih zagonov. Dostop do naprav ureja PrivateDevices, ki nadomesti /dev z najmanjšo množico psevdonaprav, in DevicePolicy z DeviceAllow, ki odločata, kaj cgroup dovoli. /dev/net/tun ni del te najmanjše množice, zato unit z PrivateDevices=yes tega ne more odpreti, karkoli pravi politika naprav.

Zaščita datotečnega sistema odgovarja na drugo vprašanje. ProtectHome=yes naredi /home, /root in /run/user nedostopni, in ProtectSystem=full naredi /usr, /boot in /etc samo za branje. Zato hook, ki piše ob svoji konfiguracijski datoteki, deluje v vašem shellu in spodleti pod unitom, z enako obliko dovoljenja kot manjkajoča zmožnost. Premaknite zapisljivi vhod na pot, ki jo politika dovoli, ali dodajte ozek ReadWritePaths= vnos.

Omejitve virov so tretja skupina in najmanj očitna. TasksMax= omejuje, koliko opravil sme unit ustvariti, zgornja meja datotečnih deskriptorjev pa se obnaša enako za vtičnice in ročaje. Namestitev, ki je prerasla mejo, spodleti z napako vira, ne z napako dovoljenja, in zato natančno sporočilo še vedno šteje.

Prestavite korak z imenskim prostorom iz hooka

Priprava, ki potrebuje pravico, ki je odjemalec ne sme imeti, sodi v svoj unit. Oneshot, ki teče pred odjemalcem, ohrani svoj rezultat in je razvrščen pred povezavo, da koraku z imenskim prostorom, kar potrebuje, ne da pa teh pravic procesu tunela. Odjemalec se nato sklicuje na ta unit, namesto da bi skripto klical iz svojega up-hooka.

Predloga spodaj je začetna oblika, ne kaj, kar se uporabi neprebrano. Pripravo drži tam, kjer živi pravica, in unit tunela pusti nedotaknjen:

# /etc/systemd/system/[email protected]
[Unit]
Description=Namespace preparation for %i
Before=openvpn-client@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/netns-up.sh %i
CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.target

Dodajte vrstni red z drop-inom, namesto da bi urejali pakirani unit, da posodobitev ne more tiho zavreči vaše spremembe. Mapa je vezana na ime instance, zato drugi profil potrebuje svojo datoteko:

sudo mkdir -p /etc/systemd/system/[email protected]
sudo tee /etc/systemd/system/[email protected]/10-namespace.conf >/dev/null <<'CONF'
[Unit]
[email protected]
[email protected]
CONF
sudo systemctl daemon-reload

Ponovite isti klic po spremembi

Popravilo je potrjeno šele, ko isti klic da drugačen rezultat. Znova zaženite oba unita, izvedite operacijo, ki je spodletela, in primerjajte njen rezultat z vrstico dnevnika, ki ste jo shranili pred spremembo. Unit, ki se zažene, medtem ko hook nikoli več ne teče, ni popravilo.

Zaporedje spodaj ohranja primerjavo pošteno, ker preverja zavrnjeni klic in ne barve unita. Shranite njegov izhod ob vrstico dnevnika, ki ste jo ujeli pred spremembo:

sudo systemctl restart "[email protected]" "[email protected]"
systemctl status "[email protected]" --no-pager
journalctl -u "[email protected]" -b --no-pager | grep -c 'Operation not permitted'
ip -brief addr show tun0

Štejte zavrnitve, namesto da berete zadnjo vrstico, ker lahko hook spodleti, poskusi znova in uspe, in samo število pokaže, ali se je meja premaknila. V drop-inu pustite komentar z imenom direktive, ki ste jo popustili, in razlogom, saj naslednja posodobitev primerja vašo konfiguracijo s pakirano privzeto. Unit, ki se zažene šele po izklopu vsake zaščite, ni popravljen.

Sorodni članki