Āķis darbojas, kad palaid to ar roku kā root, un atgriež Operation not permitted tajā mirklī, kad pakalpojums to palaiž. Fails starp šīm palaišanām nemainījās; mainījās vide. systemd dod procesam mazāku pasauli: mazāk iespēju, citu /dev, tikai lasāmus failu sistēmas ceļus un uzdevumu griestus. Lasi neveiksmi kā robežu, kas noraidīja vienu konkrētu darbību, nevis kā salūzušu skriptu.

Sāc ar darbību, kura tika noraidīta

Žurnāla rinda, kas saka, ka unit cietis neveiksmi, tev gandrīz neko nepasaka. Noderīgā rinda nosauc izsaukumu, kas tika noraidīts: ierīces mezgls, ko nevarēja atvērt, direktorija, kurā nevarēja rakstīt, nosaukumtelpa, ko nevarēja izveidot. Atrodi šo izsaukumu pirms tam, kad aiztiec kaut vienu direktīvu, jo katra atbilst citam ierobežojumam. Tad lasi to unit, kas tiešām darbojās, ieskaitot drop-in, nevis failu, ko piegādāja pakotne.

Zemāk esošais vaicājums izdrukā fragmenta ceļu, drop-in direktorijas un īpašības, kas svarīgas ierīces vai failu sistēmas noraidījumā. Izlasi tās visas pirms lēmuma par to, kura robeža ir būtiska:

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'

Šajā blokā nekas neraksta. Ja noraidītais izsaukums žurnālā nav, vienai palaišanai paaugstini klienta detalizāciju, nevis mini direktīvas. Darbojošs process pierāda, ka unit ir palaists, nevis ka āķis darbojās ar vajadzīgajām tiesībām.

Nosaukumtelpai vajadzīgas mount tiesības, ko TUN ierīce nekad neizmanto

Divām darbībām, kas vienā āķī izskatās vienādi, ir atšķirīgi atļauju profili. Atverot /dev/net/tun un veidojot saskarni, vajadzīga tīkla administrēšana un piekļuve šim mezglam. Nosauktas tīkla nosaukumtelpas veidošanai arī vajadzīgs mount darbs, jo nosaukumtelpas rīks mountē jaunu /sys skatu un piesaista stāvokļa direktoriju savā vietā. augšupējo klienta unit apzināti atstāj mount administrēšanu ārpus savas robežu kopas, tāpēc nosaukumtelpas solis tiek noraidīts, kamēr pats tunelis būtu darbojies.

Tāpēc ierīces mezgla piešķiršana skriptu neglābj. Ierīces atļauja atbild uz vienu jautājumu, vai šis process drīkst atvērt šo mezglu, un nosaukumtelpas jautājums ir cits. Pirms kaut ko paplašini, saskaņo neveiksmīgo izsaukumu ar tā iespēju.

Tests tavā shell manto visas iespējas, kas ir neierobežotam root, un unit manto to, ko paturēja tā robežu kopa. Tās divas palaišanas ir atšķirīgi eksperimenti pat ja binārais fails ir identisks.

Ierīces, aizsargātie ceļi un uzdevumu griesti

Kad noraidītā darbība ir zināma, trīs direktīvu grupas izskaidro lielāko daļu neveiksmju. Piekļuvi ierīcēm regulē PrivateDevices, kas aizstāj /dev ar minimālu pseidoierīču kopu, un DevicePolicy ar DeviceAllow, kas izlemj, ko atļauj cgroup. /dev/net/tun nav daļa no šīs minimālās kopas, tāpēc unit ar PrivateDevices=yes to nevar atvērt, lai ko teiktu ierīču politika.

Failu sistēmas aizsardzība atbild uz otru jautājumu. ProtectHome=yes padara /home, /root un /run/user nepieejamus, un ProtectSystem=full padara /usr, /boot un /etc tikai lasāmus. Tāpēc āķis, kas raksta blakus savam konfigurācijas failam, darbojas tavā shell un cieš neveiksmi unit apakšā, ar tādu pašu atļaujas formu kā trūkstoša iespēja. Pārvieto rakstāmo ievadi uz ceļu, ko atļauj politika, vai pievieno šauru ReadWritePaths= ierakstu.

Resursu limiti ir trešā grupa, un vismazāk acīmredzamā. TasksMax= ierobežo, cik uzdevumus unit drīkst izveidot, un faila deskriptoru griesti uzvedas tāpat attiecībā uz socket un rokturiem. Izvietojums, kas izaudzis pāri griestiem, cieš neveiksmi ar resursa kļūdu, nevis atļaujas kļūdu, un tāpēc precīzais ziņojums joprojām ir svarīgs.

Izvelc nosaukumtelpas soli ārpus āķa

Sagatavošanās, kam vajadzīga privilēģija, kura klientam nav jābūt, pieder pie sava unit. Oneshot, kas darbojas pirms klienta, patur savu rezultātu un ir sakārtots pirms savienojuma, dod nosaukumtelpas solim vajadzīgo, nenododot šīs tiesības tuneļa procesam. Tad klients atsaucas uz to unit, nevis izsauc skriptu no sava up āķa.

Zemāk esošā veidne ir sākuma forma, nevis kaut kas, ko piemēro nelasītu. Tā patur sagatavošanos tur, kur dzīvo privilēģija, un atstāj tuneļa unit neskartu:

# /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

Pievieno secību ar drop-in, nevis rediģē iepakoto unit, lai atjauninājums nevarētu klusi nomest tavu izmaiņu. Direktorija ir piesaistīta eksemplāra nosaukumam, tāpēc otram profilam vajadzīgs savs fails:

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

Atkārto to pašu izsaukumu pēc izmaiņas

Labojums tiek apstiprināts tikai tad, kad tas pats izsaukums dod citu rezultātu. Restartē abus unit, izpildi darbību, kas cieta neveiksmi, un salīdzini tās rezultātu ar žurnāla rindu, ko saglabāji pirms izmaiņas. Unit, kas startē, kamēr āķis vairs nekad nedarbojas, nav labojums.

Zemāk esošā secība saglabā salīdzinājumu godīgu, jo pārbauda noraidīto izsaukumu, nevis unit krāsu. Saglabā tās izvadi blakus žurnāla rindai, ko uztvēri pirms izmaiņas:

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

Skaiti noraidījumus, nevis lasi pēdējo rindu, jo āķis var ciest neveiksmi, mēģināt vēlreiz un gūt panākumus, un tikai skaits parāda, vai robeža ir pārvietojusies. Atstāj drop-in komentāru, kas nosauc atlaisto direktīvu un iemeslu, jo nākamais atjauninājums salīdzina tavu konfigurāciju ar iepakoto noklusējumu. Unit, kas startē tikai pēc tam, kad izslēgta visa aizsardzība, nav salabots.

Saistītie raksti