SELinux-Policies einrichten

© Agustin Paz, 123RF

Ein Herz für Katzen

Eigene SELinux-Policy-Module zu schreiben, ist nicht weiter schwer. Mit etwas SELinux-Basiswissen ist das schnell erledigt. Nur wie kommen die Module auf alle Maschinen der eigenen Systemlandschaft? Genau darum geht es diesen Monat.
Mit Hardware-Beschleunigung und schnellem Netz hilft Desktop-Virtualisierung, Administrationsaufwand und Kosten sparen, ADMIN 04/2013 verrät, wie die ... (mehr)

Einem öffentlichen Aufruf folgend [1] sollte man Probleme mit SELinux nicht länger durch das Abschalten des Security-Mechanismus beheben. Besser ist es, das Problem zu analysieren und ein entsprechendes Regelwerk zu schreiben. Gleiches gilt natürlich auch, wenn man sein eigenes Programm unter das Schutzschild von SELinux stellen möchte. Auch hier ist erst einmal eine Analyse der Applikation notwendig, bevor es dann an die Entwicklung einer passenden Policy geht.

Für den ersten Fall bietet es sich an, mit Hilfe von »ausearch« und »audit2allow« die Probleme, die bei einer Applikation in Zusammenhang mit SELinux auftreten, zu analysieren und dann die neuen Regelsätze, die zur Problemlösung notwendig sind, in ein eigenes Policy-Modul zu packen. Je nach Art des Problems kann es natürlich auch sein, dass die bereits vorhandene Policy für die Anwendung einen Bug enthält. In diesem Fall sollte man einen entsprechenden Bug-Report beim Distributor der Policy einreichen. Kurzfristig kann das Problem dann natürlich immer noch durch ein eigenes Policy-Modul behoben werden. Es wäre nur schade, wenn das Rad von jederman immer wieder neu erfunden werden müsste.

Eigene Policies

Der zweite Fall, bei dem noch gar keine Policy für die Anwendung existiert, erfordert natürlich etwas mehr Arbeitsaufwand. Hier ist erst einmal ein passendes Grundgerüst für die neue Policy zu entwerfen. Dies kann entweder von Hand oder mit Hilfe entsprechender Tools, beispielsweise »sepolgen« , passieren. In einem iterativen Prozess ist die Policy dann zu optimieren. Das Thema Policy-Entwicklung würde hier jedoch den Rahmen sprengen, zumal es zu dem Thema bereits jede Menge Literatur gibt [2] . An dieser Stelle soll es lediglich darum gehen, welche Methodiken zum Einsatz kommen können, um eine neue Policy zu verteilen.

In beiden Fällen steht am Ende des Entwicklungsprozesses ein neues Policy-Paket. Dieses liegt in einem binären Format vor und ist auf den gewünschten Systemen mittels »semodule« in den Security-Server des Kernels zu laden. Tatsächlich ist es so, dass aus allen aktiven Modulen und einer Basis-Policy eine globale Policy-Datei geschrieben wird und diese dann in den Security-Server geladen wird. Für den Benutzer ist dieser Prozess aber transparent, da dieser lediglich das Modul laden muss, damit die darin definierten Änderungen aktiv werden.

Die vorhandenen SELinux-Policy-Module liegen auf einem Fedora-System im Verzeichnis »/usr/share/selinux/targeted/« . Sollte statt der üblichen Targeted-Policy die MLS-Policy zum Einsatz kommen, befinden sich deren Module natürlich im Verzeichnis »/usr/share/selinux/mls/« . Schaut man sich die Größe der Module einmal näher an, so kann man schön erkennen, dass das Base-Modul mit über 200 KByte bei Weitem den größten Raum einnimmt.

Beim Laden eines Modul, wird es nach »/etc/selinux/targeted/modules/active/modules/« kopiert. Bei jedem Neustart des Systems werden die Module aus diesem Verzeichnis erneut in den Kernel geladen. Die eben erwähnt globale Policy, die sich aus den einzelnen Modulen zusammensetzt, liegt dabei im Verzeichnis »/etc/selinux/targeted/policy/« . Dass diese sich bei jedem Laden beziehungsweise Entladen eines Moduls ändert, lässt sich schön am Modify-Timestamp der Datei erkennen.

Der Ablauf, um diese Datei nun neu zu generieren und die geänderte Version dann in den Security-Server des Kernels zu laden, sieht dabei wie folgt aus:

  • Policy-Dateien erzeugen: »policy.{te,fc,if}« ,
  • Policy kompilieren,
  • Policy-Modul mit »semodule -i« laden.

Soll dieses auf einer Vielzahl von Systemen stattfinden, ist es sehr umständlich, die binäre Policy-Datei durch die Gegend zu kopieren und sie dann manuell zu laden. Stattdessen sollten die Module lieber als RPM-Pakete auf die Systeme gelangen. Dies stellt eine saubere Variante zur Installation und Deinstallation der Module dar und bietet nebenbei noch den Vorteil einer Versionsverwaltung.

Wie schon Eingangs erwähnt, muss man bei der Entwicklung von RPM-Paketen für die Policy-Module zwei Formen auseinanderhalten. Für Module, die Probleme mit einer bereits existierenden Policy beheben sollen, bietet es sich an, ein eigenes RPM für dieses lokale Regelwerk zu entwickeln. Für eine komplett neue Policy, die zu einer ganz bestimmten Anwendung gehört, kann diese entweder mit dem RPM der Applikation ausgeliefert werden oder als eigenständiges RPM. Beides hat Vor- und Nachteile. Ich selbst habe die Erfahrung gemacht, dass ein einzelnes Specfile, das ein Haupt-RPM für die eigentliche Anwendung und ein Sub-RPM für die dazugehörige Policy enthält, die beste Alternative darstellt.

Das Specfile des RPMs ist dann so aufzubauen, dass sämtliche Schritte, die zur Erzeugung der binären Policy notwendig sind, automatisch bei der Generierung des RPMs passieren. Des Weiteren müssen entsprechende Scriptlets geschrieben werden, die dafür sorgen, dass auf den Zielsystemen bei der Installation des Pakets das Modul geladen und bei der Deinstallation wieder entladen wird. Ist dies erledigt, so muss das RPM nur noch mit einer digitalen Signatur versehen werden, bevor es dann auf die gewünschten Systeme verteilt werden kann. Hierfür können dann die gewünschten Tools zum Einsatz kommen. Beispielsweise bietet sich Pulp oder Fedoras Spacewalk beziehungsweise Red Hats Satellite Server oder aber auch ein Standalone-Software-Repository an.

Eingepackt

Listing 1 zeigt ein beispielhaftes RPM-Specfile für ein SELinux-Policy-Modul, das eine bestehende Policy um weitere Regeln ergängt. Soll die Policy zusammen mit einer Anwendung paketiert werden, ist das Specfile entsprechend zu erweitern. Möchte man sicherstellen, dass das neue Modul nicht nur mit der Targeted-Policy funktioniert, sondern beispielsweise auch unter der MLS-Policy lauffähig ist, muss man das Macro »selinux_pol« im Specfile entsprechend erweitern und das Specfile selbst so abändern, dass an den jeweiligen Stellen mittels einer Schleife über das Macro das Modul in die richtigen Verzeichnisse kopiert wird.

Listing 1

custom-selinux-policy.spec

 

Mit Hilfe von »rpmbuild -ba custom-selinux-policy« erhält man schließlich ein Source- und Binär-RPM. Auf dem Buildhost müssen hierfür die entsprechenden Entwicklungstools zur Verfügung stehen. Durch die Scriptlets im RPM-Specfile wird sichergestellt, dass das Policy-Modul automatisch bei der Installation des RPMs geladen und auch wieder entladen wird, sollte die letzte Version von dem RPM gelöscht werden.

Ich hoffe, der Artikel konnte ein bisschen dazu beitragen, die Abschaltquote von SELinux weiter zu senken. Falls nicht, bitte ich daran zu denken: Every time someone sets setenforce 0, one kitten dies and Daniel Walsh cries [3] .

Infos

  1. Don't make Dan Walsh unhappy: http://stopdisablingselinux.com/
  2. Thorsten Scherf, Mandatory-Access-Control (MAC) mit SELinux, Linux-Magazin Sonderheft, 02/2008, S. 22
  3. Stop disabling SELinux: https://plus.google.com/112917221531140868607/posts/ZiqZVXAjrev

Der Autor

Thorsten Scherf arbeitet als Principal Consultant für Red Hat EMEA. Er ist oft als Vortragender auf Konferenzen anzutreffen. Wenn ihm neben der Arbeit noch Zeit bleibt, nimmt er gerne an Marathonläufen teil.

comments powered by Disqus
Mehr zum Thema

SELinux-Module selber schreiben

In den letzten Jahren hat sich im Bereich SELinux viel getan. Die neuen Features betrafen meistens die Benutzbarkeit. Mit dem aktuellen Release lassen sich SELinux-Policy-Module einfacher selber schreiben.
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023