In diesem Szenario verwendete ich Gentoo Linux mit einem entsprechenden Kernel um eine Unterstützung für SELinux bieten zu können. Es wird davon ausgegangen das SELinux bereits installiert ist und grundlegend funktioniert.
1. SELinux im sog. "permissive mode" laufen lassen
Im permissive mode lässt SELinux zwar noch alle Aktionen zu, die im strict mode verboten wären jedoch werden die Verstöße an verschiedenen Stellen geloggt. Diese werden später genutzt um dann daraus die Regeln zu erstellen.
Um zu überprüfen, ob SELinux im richtigen Modus läuft reicht es, folgenden Befehl in der Konsole einzugeben:
getenforce
Dies sollte als Ergebnis Permissive liefern. Sollte dies nicht der Fall sein, so sollte man einen Blick auf seine SELinux Config werfen, die sich unter /etc/selinux/config findet. Dort sollte SELINUX=permissive eingetragen werden. Um sicher zu gehen, dass dies übernommen wird starten wir anschließend neu.
2. SELinux lernen lassen
Nun ist es an der Zeit SELinux lernen zu lassen. Am besten macht ihr dies, indem ihr das System wie gewohnt benutzt, alle Dienste die später darauf laufen sollen testet usw. Ich demonstriere dies am Beispiel eines FTP-Daemons. Diesen habe ich gestartet, mich darauf verbunden mit einem FTP-Client wie z.B. Filezilla und dort z.B. Ordner erstellt, gelöscht, umbenannt usw. Ihr solltet all das machen, was ihr erwartet was die Benutzer später tun werden.
3. SELinux Policies erstellen
Nun da ihr euer System schon etwas getestet habt, ist es an der Zeit die Meldungen, die SELinux protokolliert hat in sog. Policies umzuwandeln. Bitte beachtet jedoch: Natürlich kann es sein, dass sich während dem zweiten Schritt schon ein Angreifer Zutritt zu eurem System verschaffen hat. Somit würden wir die vom Angreifer erzeugten Regelverstöße ebenfalls erlauben. Es ist also mehr als ratsam die Regeln nicht nur blind zu kopieren sondern diese auch zu untersuchen.
Genug geredet. Jetzt geht es los.Wie bereits anfangs erwähnt nehmen wir die Logeinträge, die SELinux erstellt hat als Grundlage für unsere neuen Regeln. Doch wo werden diese gespeichert? In meinem Fall habe ich diese direkt aus dmesg bezogen, da sie in keiner anderen Log auftauchten.
Doch nun einmal gleich zum Anfang eine gute Nachricht: Die Entwickler von SELinux haben gute Arbeit geleistet und ein Tool erstellt, welches es erlaubt aus den Logeinträgen fertige Regeln zu bauen. Ich verwende es folgendermaßen:
audit2allow -d -l >> ~/a2a
Nun wird eine Datei namens "a2a" im Homeverzeichnis des aktuellen Benutzers angelegt. Diese enthält alle erforderlichen Informationen die wir zum erstellen von unseren Policies benötigen.
Diese öfnnen wir nun z.B. mit nano:
nano ~/a2a
Dort finden wir nun einige Einträge, die ähnlich wie dieser aussehen:
#============= dmesg_t ==============
allow dmesg_t etc_t:file { read getattr };
allow dmesg_t file_t:file { write getattr };
Jeder Eintrag, der mit #=============... beginnt steht hierbei für einen Dienst. Es empfiehlt sich aus Gründern der Übersichtlichkeit später für jedes dieser Dienste eine eigene Policy zu erstellen. Ich habe unter / ein Verzeichnis namens selinux-policies erstellt. Dort findet sich für jede Policy ein Unterverzeichnis mit dem Namen des Dienstes.
Doch wie sieht nun z.B. die Policy für dmesg aus? Hierzu erstellen wir nun eine Textdatei namens dmesg.te und öffnen diese mit nano. Meine dmesg.te sieht in diesem Fall so aus:
policy_module(dmesg,1.0.0)
require {
type dmesg_t;
type file_t;
}
#============= dmesg_t ==============
allow dmesg_t etc_t:file { read getattr };
allow dmesg_t file_t:file { write getattr };
Nun erklären wir das ganze noch fix. Das 1.0.0 steht für die Versionsnummer der Policy. Ich habe mir angewöhnt bei jeder Änderung an der Policy diese Nummer zu erhöhen und die Änderungen zu dokumentieren. Unter require müssen alle Typen aufgeführt werden, die weiter unten in der Policy auftauchen. Das war es eigentlich auch schon! Eine Policy vollständig zu erklären würde den Rahmen sprengen.
Nun speichern wir das ganze ab und machen uns unsere erste eigene Policy mit folgendem Befehl (hierzu muss man in dem Ordner sein, in dem wir gerade die .te-Datei gespeichert habem):
make -f /usr/share/selinux/strict/include/Makefile
Nun sollten wir im selben Ordner eine .pp Datei haben. Glückwunsch dies ist unsere erste Policy! Nun laden wir das ganze noch mit
semodule -i dmesg.pp
Nun sollte die Policy geladen sein. Jetzt kommt der ultimative Test. Wir schalten SELinux auf "strict" und schauen ob es wirklich funktioniert
setenforce 1
Nun solltet ihr ausprobieren ob alles wie gewünscht funktioniert. Nicht der Fall? Dann schnell wieder in den Permissive Mode!
newrole -r sysadm_r
Nun werdet ihr nach eurem root-Passwort gefragt. Danach könnt ihr die Policy wieder folgendermaßen entfernen
semodule -r dmesg
So geht ihr nun mit allen Policies vor bis alles funktioniert.