Rettigheder i Linux svarer på spørgsmålet »hvem må læse denne fil«. AppArmor stiller et andet: »hvad må dette program overhovedet gøre«. Forskellen viser sig ved et indbrud. En webshell køres med webserverbrugerens rettigheder og arver alle dens privilegier — altså læseadgang til en god del af systemet. En AppArmor-profil begrænser processen til listen over det, den har brug for til sit arbejde, og et forsøg på at læse /etc/shadow eller starte /bin/bash ender med afvisning, uanset brugerens rettigheder.
Hvad der allerede er slået til
sudo aa-status
Outputtet svarer på tre spørgsmål: hvor mange profiler der er indlæst, hvor mange af dem der kører i enforce og complain, og hvilke processer der kører helt uden profil. I et typisk Ubuntu bliver det nogle snese profiler, men næsten alle til hjælpeprogrammer af typen man og tcpdump. De centrale tjenester — nginx, Apache, PHP-FPM — mangler som regel på listen over begrænsede.
Tre tilstande skal holdes adskilt:
- enforce — reglerne gælder, alt overflødigt er forbudt;
- complain — overtrædelser registreres blot, intet blokeres. Tilstanden til indkøring;
- unconfined — ingen profil findes, programmet kører uden begrænsninger.
Den nyttigste del af aa-status er den sidste: processer, der lytter på netværket og ikke begrænses af noget. Det er listen, man begynder med.
Værktøjerne
sudo apt install apparmor-utils
Uden den pakke findes kommandoerne aa-complain, aa-enforce og aa-logprof ikke i systemet, selv om AppArmor selv virker.
Hvordan du slår en profil til uden at standse tjenesten
Rækkefølgen er afgørende. En profil, der sættes direkte i enforce, vil med stor sandsynlighed forbyde tjenesten noget, den har brug for, og så holder den op med at virke — som regel ikke straks, men ved en sjælden operation som at sende en fil eller et brev.
Rigtig rækkefølge:
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
En uge i den tilstand, inklusive alle usædvanlige forløb: sikkerhedskopiering, opdatering, upload af store filer. Derefter en gennemgang af det, der har samlet sig:
sudo aa-logprof
Kommandoen gennemgår registrerede overtrædelser og spørger ved hver enkelt, om den skal tillades. Her kræves opmærksomhed: tillad det, der virkelig hører til tjenestens arbejde, og ikke alt på stribe — ellers bliver resultatet en profil, der tillader alt, og pointen forsvinder.
Og først derefter:
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Hvor du ser afvisningerne
Alle overtrædelser havner i kernelogfilen:
sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log
Den anden fil findes, hvis auditd er installeret — og så er posterne betydeligt fyldigere. I en afvisningspost ses profilnavnet, den forespurgte operation og stien, der blev spurgt efter; det rækker til at afgøre, om profilen skal rettes, eller om man skal glæde sig over, at den virkede.
Læg særligt mærke til symptomet: tjenesten opfører sig underligt — læser ikke konfigurationen, skriver ikke til en mappe, åbner ikke en socket — og har i sine egne logfiler fejlen »adgang nægtet« på trods af helt korrekte rettigheder. Det er næsten altid AppArmor, og det første, man gør, er at se i kernelogfilen.
Et praktisk tiltag, ikke et teoretisk
En profil til PHP-FPM eller nginx betaler sig på en konkret måde. Med processen begrænset kan en webshell, der er havnet på hjemmesiden, hverken læse systemfiler, starte en skal eller skrive noget sted uden for de tilladte mapper. Et indbrud på hjemmesiden forbliver et indbrud på hjemmesiden i stedet for at blive til adgang til hele maskinen — og netop den overgang udgør den væsentlige del af skaden.
En fornuftig indføringsrækkefølge: først en profil til det, der vender mod internettet (webserveren, PHP-FPM), så til databaserne, derefter efter behov. Alt behøver ikke slås til på én gang, og noget færdigt universelt sæt findes ikke: profilen afhænger af, hvor dine filer ligger.
Hvad du kontrollerer jævnligt
Profiler falder tilbage til ubegrænset oftere, end man tror: en pakkeopdatering kan skifte profilfilen ud, manuel fejlsøgning efterlader tjenesten i complain, og en ny tjeneste kommer helt uden profil. To tal er nyttige: hvor mange profiler der er i enforce, og hvor mange netværksprocesser der kører uden begrænsninger. En ændring i det ene eller det andet er værd at bemærke. Hvordan det ser ud samlet på én side, viser demonstrationen nedenfor.