Τα δικαιώματα στο Linux απαντούν στο ερώτημα «ποιος μπορεί να διαβάσει αυτό το αρχείο». Το AppArmor απαντά σε άλλο: «τι επιτρέπεται να κάνει καν αυτό το πρόγραμμα». Η διαφορά φαίνεται σε μια παραβίαση. Ένα web shell τρέχει ως ο χρήστης του διακομιστή ιστού και κληρονομεί όλα του τα δικαιώματα — δηλαδή πρόσβαση ανάγνωσης στο μισό σύστημα. Ένα προφίλ AppArmor περιορίζει τη διεργασία στη λίστα όσων χρειάζεται για τη δουλειά της, και μια απόπειρα ανάγνωσης του /etc/shadow ή εκκίνησης του /bin/bash καταλήγει σε άρνηση ανεξάρτητα από τα δικαιώματα του χρήστη.
Τι είναι ήδη ενεργό
sudo aa-status
Η έξοδος απαντά σε τρία ερωτήματα: πόσα προφίλ είναι φορτωμένα, πόσα από αυτά είναι σε enforce και σε complain, και ποιες διεργασίες τρέχουν χωρίς κανένα προφίλ. Σε ένα τυπικό Ubuntu θα υπάρχουν λίγες δεκάδες προφίλ, αλλά σχεδόν όλα αφορούν βοηθητικά προγράμματα όπως το man και το tcpdump. Οι βασικές υπηρεσίες — nginx, Apache, PHP-FPM — απουσιάζουν συνήθως από τη λίστα των περιορισμένων.
Τρεις λειτουργίες αξίζει να ξεχωρίζετε:
- enforce — οι κανόνες εφαρμόζονται, ό,τι περισσεύει απορρίπτεται·
- complain — οι παραβιάσεις μόνο καταγράφονται στο ημερολόγιο, τίποτα δεν αποκλείεται. Η λειτουργία για ρύθμιση·
- unconfined — δεν υπάρχει προφίλ, το πρόγραμμα τρέχει χωρίς περιορισμούς.
Το πιο χρήσιμο μέρος της εξόδου του aa-status είναι το τελευταίο: διεργασίες που ακούν στο δίκτυο και δεν περιορίζονται από τίποτα. Από αυτή τη λίστα ξεκινάτε.
Τα εργαλεία
sudo apt install apparmor-utils
Χωρίς αυτό το πακέτο οι εντολές aa-complain, aa-enforce και aa-logprof δεν υπάρχουν στο σύστημα, παρότι το ίδιο το AppArmor τρέχει.
Πώς ενεργοποιείται ένα προφίλ χωρίς να σταματήσει η υπηρεσία
Η σειρά είναι θεμελιώδης. Ένα προφίλ που μπαίνει κατευθείαν σε enforce θα αρνηθεί με μεγάλη πιθανότητα κάτι που η υπηρεσία χρειάζεται, και εκείνη θα σταματήσει να δουλεύει — συνήθως όχι αμέσως αλλά σε κάποια σπάνια ενέργεια όπως μια μεταφόρτωση αρχείου ή η αποστολή αλληλογραφίας.
Η σωστή ακολουθία:
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
Μία εβδομάδα δουλειάς σε αυτή τη λειτουργία, καλύπτοντας κάθε ασυνήθιστο σενάριο: τη λήψη αντιγράφου ασφαλείας, μια ενημέρωση, τη μεταφόρτωση μεγάλων αρχείων. Έπειτα περάστε από όσα συσσωρεύτηκαν:
sudo aa-logprof
Η εντολή διατρέχει τις καταγεγραμμένες παραβιάσεις και ρωτά για καθεμία αν θα επιτραπεί. Εδώ χρειάζεται προσοχή: επιτρέψτε ό,τι ανήκει πραγματικά στη δουλειά της υπηρεσίας, όχι ό,τι βλέπετε μπροστά σας — αλλιώς καταλήγετε με προφίλ που επιτρέπει τα πάντα και το νόημα χάνεται.
Και μόνο τότε:
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Πού φαίνονται οι αρνήσεις
Όλες οι παραβιάσεις καταλήγουν στο ημερολόγιο του πυρήνα:
sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log
Το δεύτερο αρχείο υπάρχει αν είναι εγκατεστημένο το auditd — και μαζί του οι εγγραφές είναι αισθητά πιο αναλυτικές. Μια εγγραφή άρνησης δείχνει το όνομα του προφίλ, την ενέργεια που ζητήθηκε και τη διαδρομή στην οποία έγινε πρόσβαση· αυτό αρκεί για να καταλάβετε αν πρέπει να διορθώσετε το προφίλ ή να χαρείτε που ενεργοποιήθηκε.
Ένα σύμπτωμα αξίζει να το θυμάστε: μια υπηρεσία συμπεριφέρεται παράξενα — δεν διαβάζει ρύθμιση, δεν γράφει σε κατάλογο, δεν ανοίγει socket — ενώ τα δικά της αρχεία δείχνουν σφάλμα «permission denied» με δικαιώματα που είναι φανερά σωστά. Αυτό είναι σχεδόν πάντα το AppArmor, και το πρώτο που κάνετε είναι να κοιτάξετε στο ημερολόγιο του πυρήνα.
Πρακτικό μέτρο, όχι θεωρητικό
Ένα προφίλ για PHP-FPM ή nginx αποδίδει με συγκεκριμένο τρόπο. Με τη διεργασία περιορισμένη, ένα web shell που φτάνει στον ιστότοπο δεν μπορεί ούτε να διαβάσει αρχεία συστήματος, ούτε να ξεκινήσει κέλυφος, ούτε να γράψει οτιδήποτε εκτός των επιτρεπόμενων καταλόγων. Ένας παραβιασμένος ιστότοπος παραμένει παραβιασμένος ιστότοπος αντί να μετατραπεί σε πρόσβαση σε ολόκληρο το μηχάνημα — και αυτή ακριβώς η μετάβαση ευθύνεται για τον κύριο όγκο της ζημιάς.
Μια λογική σειρά υιοθέτησης: πρώτα προφίλ για ό,τι βλέπει στο διαδίκτυο (ο διακομιστής ιστού, το PHP-FPM), μετά για τις βάσεις δεδομένων, μετά κατά περίπτωση. Δεν χρειάζεται να τα ενεργοποιήσετε όλα ταυτόχρονα και δεν υπάρχει καθολικό έτοιμο σύνολο: ένα προφίλ εξαρτάται από το πού βρίσκονται τα αρχεία σας.
Τι να ελέγχετε τακτικά
Τα προφίλ ξαναπέφτουν σε unconfined συχνότερα απ' ό,τι φαντάζεστε: μια ενημέρωση πακέτου μπορεί να αντικαταστήσει ένα αρχείο προφίλ, η χειροκίνητη αποσφαλμάτωση αφήνει μια υπηρεσία σε complain και μια νέα υπηρεσία έρχεται χωρίς κανένα προφίλ. Δύο αριθμοί είναι χρήσιμοι: πόσα προφίλ είναι σε enforce και πόσες διεργασίες που βλέπουν στο δίκτυο είναι unconfined. Μια αλλαγή σε οποιονδήποτε από τους δύο αξίζει να τη μάθετε. Πώς μοιάζει αυτό συγκεντρωμένο σε μία σελίδα το δείχνει η επίδειξη παρακάτω.