Tjenesten logger en chroot-feil og profilen ser allerede romslig ut, så den fristende løsningen er å utvide en stiregel og starte på nytt. Det endrer vanligvis ingenting, fordi chroot styres av en rettighet profilen aldri kunne overlevere. Å avgjøre hvilket lag du skal ta i, krever tre billige kontroller: hva prosessen får lov til å holde, hva policyen tillater, og hva oppstarteren fjernet før noen av de to telte.

To separate porter, og bare én tilhører AppArmor

chroot trenger CAP_SYS_CHROOT i brukernavnerommet prosessen kjører i. Det er en vanlig Linux-rettighet, kontrollert av kjernen før kallet gjør noe med stier. Separat kan en håndhevende AppArmor-profil nekte kapabiliteten selv når prosessen har den, fordi obligatorisk policy konsulteres i tillegg til legitimasjonen og ikke i stedet for den. Forskjellen betyr noe i praksis: de to lagene bor i forskjellige filer og vedlikeholdes vanligvis av forskjellige folk.

De to portene feiler med samme errno. Begge gir EPERM, og begge fremstår som en generisk tillatelsesklage i tjenesteloggen, og derfor kaster gjetting på profilinnhold bort så mye tid. Stiregelen du var i ferd med å legge til, styrer filtilgang etter at chroot lykkes; den har ingenting å gjøre med om operasjonen i det hele tatt er tillatt.

En tredje port ligger oppstrøms for begge. Hvis tjenestebehandleren eller en innpakning startet prosessen uten kapabiliteten i sitt begrensende sett, kan ingen AppArmor-endring sette den tilbake, og å legge kapabiliteter til profilen dokumenterer bare en intensjon kjernen ikke vil respektere.

Les rettighetstilstanden før du redigerer policyen

Start fra den kjørende prosessen og ikke fra konfigurasjonen du tror er aktiv. Statusfilen viser fem kapabilitetsmasker og no-new-privileges-flagget, og de svarer på forskjellige spørsmål:

grep -E '^(CapInh|CapPrm|CapEff|CapBnd|CapAmb|NoNewPrivs):' /proc/$(pidof openvpn)/status
sudo aa-status | grep -i openvpn

CapEff er settet som betyr noe for kallet: en kapabilitet som finnes i CapBnd men mangler i CapEff, er tillatt av taket og holdes ikke nå. CapAmb betyr noe når binæren ikke er privilegert i vanlig setuid-forstand, fordi omgivelseskapabiliteter er måten en tjeneste beholder en rettighet gjennom exec uten filkapabiliteter. CapInh holder biter som kan arves gjennom exec, men bare når det arvbare settet til filen som kjøres tillater det, så en bit der gir ingenting alene.

Bekreft deretter hvilken profil som faktisk er festet. En prosess kan være innesperret av et profilnavn du ikke ventet, særlig når en distribusjon sender sin egen enhetsfil og profil sammen, og å lese /proc/PID/attr/current avgjør det på én linje. Å sammenligne filen du redigerte med profilen kjernen rapporterer, er forskjellen mellom å rette årsaken og å redigere en fil ingen laster.

Legg til kapabilitetsregelen bare når revisjonssporet sier det

Kjerne- og revisjonsoppføringene navngir laget som nektet. Se etter en nektelse som bærer operasjonen capable og navnet sys_chroot, sammen med profilen som produserte den. Hvis den oppføringen finnes, hadde prosessen allerede kapabiliteten og AppArmor nektet, og den målrettede endringen er en kapabilitetsregel inne i den virkelige profilen:

capability sys_chroot,

Hold den som et fragment i profilen som faktisk er festet, og kontroller nøkkelordet mot referansen for apparmor.d-profiler i stedet for å kopiere en regel fra en urelatert veiledning. Å putte den i en delt include gir den til hvert innesperret program som drar inn filen, og å bytte profilen til complain-modus skjuler neste nektelse i stedet for å løse denne. Profilregelen fjerner en policynektelse; den lager ikke rettigheter, så en prosess som aldri hadde CAP_SYS_CHROOT i sitt effektive sett, vil fortsatt feile med regelen på plass.

Hvis revisjonsoppføringen ikke viser noen AppArmor-nektelse i det hele tatt, slutt å redigere profilen. Du ser på et legitimasjonsproblem, og det gjenværende arbeidet er i enhetsfilen eller foreldreprosessen, ikke i policyspråket.

Tjenestebehandleren holder sitt eget tak

systemd setter et begrensende kapabilitetssett for hver tjeneste, og som standard er det settet trangt. Alt som er utelukket der, er utilgjengelig for prosessen uansett hva profilen sier, og derfor kan herdede enheter feile i en operasjon som virket når tjenesten ble startet for hånd. De relevante direktivene er lette å lese i enhetsfilen og lette å overse når applikasjonen rapporterer feilen. Drop-in-filer fra distribusjonspakken er den vanlige kilden til et tak ingen husker å ha konfigurert.

Å heve taket og å gi kapabiliteten er to endringer, ikke én. En oppføring i det begrensende settet sier at prosessen kan holde kapabiliteten; den legger den ikke til det effektive settet, og NoNewPrivs kan hindre en senere heving fra å lykkes selv når alt annet stemmer. Legg bare til det operasjonen trenger, behold resten av herdingen, og stå imot snarveien med å gi alle kapabiliteter for at ett kall skal gå gjennom.

Rekkefølgen betyr også noe her. Endre taket i enhetsfilen først, bekreft at CapEff nå inneholder biten, og avgjør først da om AppArmor fortsatt nekter. Å gjøre begge endringene samtidig lar deg gjette igjen hvis feilen vedvarer.

Når nektelsen er borte, kontroller fengselet selv

En vellykket chroot flytter roten, så hver sti tjenesten berører etterpå, løses inne i det nye treet. Manglende konfigurasjon, en fraværende enhetsnode eller en sertifikatkatalog som ikke ble kopiert, vil nå vises som en filfeil, og den feilen er et layoutproblem og ikke et kapabilitetsproblem. Les neste hendelse i stedet for å legge til nok en bred tillatelse. Flyttingen endrer også hva en relativ sti betyr, og derfor insisterer herdeveiledninger på absolutte stier i tjenestekonfigurasjonen.

Det hjelper også å huske hva chroot ikke gjør. Det er en stigrense, ikke en sandkasse: en prosess som beholder rettigheten, kan rømme, og derfor slippes kapabiliteten vanligvis etter kallet, og derfor skal innesperringen bli værende rundt tjenesten. Å holde AppArmor-profilen, det begrensende kapabilitetssettet og filsystembegrensningene sammen er poenget med øvelsen, ikke en rest som fjernes når tjenesten starter.

Beslutningsregelen er kort. Hvis revisjonsoppføringen navngir AppArmor, legg til én kapabilitetsregel i den festede profilen. Hvis det effektive settet er tomt, rett taket i enhetsfilen og rekkefølgen for å slippe rettigheten. Hvis profilen ikke er den du redigerte, slutt å redigere og finn den virkelige.

Relaterte artikler