SELinux Einführung

Aus xinux.net
Zur Navigation springen Zur Suche springen

Prinzipien

  • SELinux (Security Enhanced Linux) ist ein System mit Mandatory Access Control, das auf der LSM-Schnittstelle (Linux Security Modules) von Linux aufbaut.
  • In der Praxis befragt der Kernel SELinux vor jedem Systemaufruf, um herauszufinden, ob der Prozess autorisiert ist, den jeweiligen Vorgang auszuführen.
  • SELinux verwendet einen Satz von Regeln - in ihrer Gesamtheit als Policy bezeichnet - um Vorgänge zu autorisieren oder zu verbieten.
  • Diese Regeln sind schwierig zu erstellen.
  • Glücklicherweise werden zwei Standardregelwerke (targeted und strict) bereitgestellt, die den Großteil der Konfigurierungsarbeit entbehrlich machen.
  • Mit SELinux ist die Verwaltung der Berechtigungen grundsätzlich verschieden von traditionellen Unix-Systemen.
  • Die Berechtigungen eines Prozesses hängen von seinem Sicherheitskontext ab.
  • Der Kontext wird von der Identität des Benutzers bestimmt, der den Prozess gestartet hat, sowie von der Rolle und der Domain, die dem Benutzer zu dieser Zeit übertragen waren.
  • Die Berechtigungen hängen tatsächlich von der Domain ab, aber die Übergänge zwischen den Domains werden von den Rollen kontrolliert.
  • Und schließlich hängen die möglichen Übergänge zwischen den Rollen von der Identität ab.

Grobbeschreibung

Aus Sicht des Benutzers

  • Ein Benutzer versucht ein Programm aufzurufen.
  • Dem Benutzer ist ein Benutzer Typ zugeordnet.
  • Dem Progamm ist ein Progamm Typ zugeordnet.
  • SELinux checkt nun ob der Benutzer Typ das Programm anhand des Programm Typ aufrufen darf.
  • Dann wird gecheckt ob der Benutzer Typ zu dem Prozess Typ transitieren darf.
  • Wenn dies erlaubt ist transitiert der Benutzer Typ zum Prozess Typ.
  • Der Prozess läuft dann mit den entsprechenden Rechten unter seinem Prozess Typ.

Aus Sicht des Modulerstellers

  • Wir besorgen uns ein Modultemplate.
  • Im Template sind enthalten.
    • Typ des Programmes
    • Typ des Prozesses
    • Transitionsregeln
    • Allowregeln (Hier ist auch das Recht enthalten ob der Benutzer ein Programm ausführen darf)
    • Weitere Typen definieren (Beispielsweise Port Typen)
  • Wir erweitern die Allowregeln
    • Port öffnen
    • Datei öffnen
    • etc...
  • Kompilieren des Modules
  • Installieren des Modules
  • Aktiveren des Modules

Sicherheitskontexte und Unix-Nutzer

Sicherheitskontexte und Unix-Nutzer.png

  • Konkret bekommt der Nutzer während der Anmeldung einen Standard-Sicherheitskontext zugewiesen (in Abhängigkeit von den Rollen, die er bestätigen können soll).
  • Dies bestimmt die geltende Domain und damit auch die Domain, der alle neuen Unterprozesse zugeordnet werden.
  • Wenn man die geltende Rolle und die ihr zugeordnete Domain ändern will, muss man den Befehl newrole -r rolle_r -t domain_t aufrufen (normalerweise ist nur eine einzige Domain für eine bestimmte Rolle erlaubt, deshalb kann der Parameter -t häufig weggelassen werden).
  • Dieser Befehl authentifiziert jemanden, indem er ihn auffordert, sein Passwort einzugeben.
  • Dies hindert Programme daran, selbstständig ihre Rollen zu ändern.
  • Derartige Änderungen sind nur möglich, wenn sie im SELinux-Regelwerk ausdrücklich erlaubt sind.
  • Offensichtlich gelten die Berechtigungen nicht für alle Objekte (Dateien, Verzeichnisse, Sockets, Geräte usw.).
  • Sie können von Objekt zu Objekt unterschiedlich sein.
  • Um dies zu erreichen, ist jedes Objekt einem Typ zugeordnet (dies wird als Kennzeichnung bezeichnet).
  • Die Rechte einer Domain werden somit durch Sätze von Operationen ausgedrückt, die bei diesen Typen erlaubt sind oder nicht (und indirekt bei allen Objekten, die mit dem jeweiligen Typ gekennzeichnet sind).
EXTRA Domains und Typen sind gleichwertig
Intern ist eine Domain nur ein Typ, jedoch ein Typ, der nur für Prozesse gilt. 
Daher tragen Domains das Suffix _t, genau wie Objekttypen.
  • Standardmäßig übernimmt ein Programm die Domain des Nutzers, der es gestartet hat, aber die normalen SELinux-Regeln erwarten, dass viele wichtige Programme in speziell für sie vorgesehenen Domains laufen.
  • Um dies zu erreichen, werden diese ausführbaren Dateien mit einem fest zugeordneten Typ gekennzeichnet (zum Beispiel wird ssh mit ssh_exec_t gekennzeichnet und wenn das Programm startet, wechselt es selbstständig in die Domain ssh_t).
  • Dieser automatische Vorgang des Domainwechsels ermöglicht es, jedem Programm nur die Berechtigungen zu gewähren, die es benötigt.
  • Dies ist ein wesentliches Prinzip von SELinux.

Selbstständige Übergänge zwischen Domains

  • Der alte System-V Boot Prozess

Selbstständige Übergänge zwischen Domains.png

IN DER PRAXIS Den Sicherheitskontext finden

Um in einer Konsole den aktuellen Sicherheitskontext festzustellen, kann man den Befehl id -Z aufrufen.

  • id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
If you receive a message saying id: --context (-Z) works only on an SELinux-enabled kernel instead, then you need to enable SELinux first by running selinux-activate and rebooting.

Um den Sicherheitskontext eines bestimmten Prozesses festzustellen, kann die Option Z des Befehls ps verwendet werden.

  • ps axZ | grep ssh
system_u:system_r:ftpd_t:s0   2094 ?    Ss  0:00 /usr/sbin/vsftpd

Das erste Feld enthält durch Doppelpunkte getrennt die Identität, die Rolle, die Domain und die MCS-Stufe. Die MCS-Stufe (Multi-Category Security) ist ein Parameter, der beim Aufbau einer Regel zum Schutz der Vertraulichkeit eingreift, die den Zugriff auf Dateien in Abhängigkeit von ihrer Sensibilität regelt. Dieses Leistungsmerkmal wird hier nicht erläutert.

Um schließlich auch den Typ festzustellen, der einer Datei zugeordnet ist, kann man den Befehl ls -Z verwenden.

  • ls -Z /usr/bin/ssh
unconfined_u:object_r:user_home_t:s0 test
system_u:object_r:ssh_exec_t:s0 /usr/bin/ssh

Man sollte beachten, dass die Identität und die Rolle, die einer Datei zugewiesen sind, keine besondere Bedeutung haben (sie werden nie benutzt), aber aus Gründen der Einheitlichkeit wird allen Objekten ein vollständiger Sicherheitskontext zugeordnet.

SELinux einrichten

  • Die Unterstützung von SELinux ist in den von Debian bereitgestellten Standard-Kerneln enthalten.
  • Die Kernprogramme von Unix unterstützen SELinux ohne Änderungen.
  • Es ist daher recht einfach, SELinux zu aktivieren.

Installation

  • Das Paket selinux-policy-default enthält einen Satz von Standardregeln.
  • Standardmäßig beschränkt dieses Regelwerk nur den Zugang für einige besonders gefährdete Dienste.
  • Die Nutzersitzungen sind nicht eingeschränkt und es ist daher unwahrscheinlich, dass SELinux legitime Nutzeraktionen blockieren würde.
  • Dieses erhöht jedoch die Sicherheit von Systemdiensten, die auf dem Rechner laufen.
  • Um ein Regelwerk einzurichten, das den alten „strengen“ Regeln entspricht, müssen Sie nur das Modul unconfined deaktivieren (die Modulverwaltung wird in diesem Kapitel ausführlich beschrieben).
  • Sobald das Regelwerk installiert ist, sollten Sie alle verfügbaren Dateien kennzeichnen (das heißt, sie einem Typ zuzuordnen).
  • Dieser Vorgang muss mit dem Befehl fixfiles relabel von Hand gestartet werden.
  • Das SELinux-System ist nun einsatzbereit.
  • Um es zu aktivieren, sollten Sie den Parameter selinux=1 security=selinux zum Linux-Kernel hinzufügen.
  • Der Parameter audit=1 aktiviert bei SELinux das Protokollieren, durch das alle unterbundenen Vorgänge aufgezeichnet werden.
  • Schließlich bringt der Parameter enforcing=1 das Regelwerk zur Anwendung: ohne ihn läuft SELinux in seinem standardmäßigen permissive-Modus, bei dem unterbundene Vorgänge zwar protokolliert, aber dennoch ausgeführt werden.
  • Sie sollten daher die Konfigurationsdatei des GRUB-Bootloaders anpassen, indem Sie die gewünschten Parameter anhängen.
  • Ein einfacher Weg, dies zu tun, besteht darin, die Variable GRUB_CMDLINE_LINUX in der Datei /etc/default/grub zu ändern und dann den Befehl update-grub auszuführen.
  • SELinux ist dann nach einem Neustart aktiv.
  • Es sei darauf hingewiesen, dass das Skript selinux-activate diese Vorgänge automatisiert und das Kennzeichnen der Dateien beim nächsten Rechnerstart erzwingt (wodurch vermieden wird, dass neue nicht gekennzeichnete Dateien erstellt werden, während SELinux noch nicht aktiv ist und das Kennzeichnen noch andauert).

Ein SELinux-System verwalten

  • Das SELinux-Regelwerk ist ein modularer Satz von Regeln und mit seiner Installierung werden automatisch alle relevanten Module entsprechend den bereits installierten Diensten erkannt und aktiviert.
  • Das System ist hierdurch sofort funktionsfähig.
  • Wenn jedoch ein Dienst später als das SELinux-Regelwerk installiert wird, müssen Sie in der Lage sein, das entsprechende Modul manuell zu aktivieren.
  • Hierzu dient der Befehl semodule.
  • Darüber hinaus müssen Sie in der Lage sein, die Rollen festzulegen, die jeder Nutzer bestätigen kann.
  • Dies geschieht mit dem Befehl semanage.
  • Diese beiden Befehle können somit dazu benutzt werden, die aktuelle SELinux-Konfiguration, die in /etc/selinux/default/ gespeichert ist, zu ändern.
  • Im Gegensatz zu anderen Konfigurationsdateien, die Sie in /etc/ finden, dürfen diese Dateien nicht manuell verändert werden.
  • Sie sollten hierzu die für diesen Zweck vorgesehenen Programme verwenden.

WEITERE SCHRITTE Weitere Unterlagen

Da die NSA keine offiziellen Unterlagen bereitstellt, hat die Gemeinschaft zum Ausgleich ein Wiki eingerichtet. 
Es bündelt viele Informationen, jedoch müssen Sie sich bewusst sein, dass die meisten SELinux-Mitwirkenden Fedora-Benutzer sind (bei dem SELinux standardmäßig aktiviert ist).
Die Dokumentation neigt daher dazu, sich vor allem mit dieser Distribution zu beschäftigen.
→ https://selinuxproject.org
You should also have a look at the dedicated Debian wiki page.
→ https://wiki.debian.org/SELinux

SELinux-Module verwalten

  • Verfügbare SELinux-Module sind im Verzeichnis /usr/share/selinux/default/ gespeichert. Um eines dieser Module in der aktuellen Konfiguration zu aktivieren, sollten Sie den Befehl semodule -i Modul.pp.bz2 benutzen. Die Erweiterung pp.bz2 steht für policy package (komprimiert mit bzip2).
  • Das Entfernen eines Moduls aus der aktuellen Konfiguration erfolgt mit semodule -r module. Letztendlich listet der Befehl semodule -l die aktuell installierten Module auf.
  • Es gibt auch deren Versionsnummern aus. Module können selektiv mit semodul -e aktiviert und mit semodul -d deaktiviert werden.

SELinux Handling

Listing der aktiven Module

  • semodule -l

Listing der aller Module

  • semodule -lfull
...
100 zarafa            pp          
100 zebra             pp 
100 zoneminder        pp          
100 zosremote         pp  
...

Deaktiviern des zebra Moduls

  • semodule -d zebra

Listing der aktiven Module

  • semodule -l

Listing der aller Module

  • semodule -lfull
...
100 zarafa            pp          
100 zebra             pp disabled
100 zoneminder        pp          
100 zosremote         pp  
...

Aktiviern des zebra Moduls

  • semodule -e zebra

Installation eines Dummy Moduls

Downloaden
Installation (Es dauert ein bisschen)
  • semodule -i dummy.pp
Listing
  • semodule -lfull | grep dummy
400 dummy             pp  

Entfernen des Moduls

  • semodule -r dummy
libsemanage.semanage_direct_remove_key: Removing last dummy module (no other dummy module exists at another priority).
Kontrolle
  • semodule -lfull | grep dummy
semodule lädt die neue Konfiguration unmittelbar, es sei denn, Sie verwenden seine Option -n.
  • Es sei darauf hingewiesen, dass das Programm standardmäßig auf die aktuelle Konfiguration wirkt (die unter der Variablen SELINUXTYPE in der Datei /etc/selinux/config angegeben ist), aber Sie können eine andere ändern, indem Sie sie mit der Option -s vorgeben.

Identitäten verwalten

  • Jedes Mal, wenn sich ein Benutzer anmeldet, wird ihm eine SELinux-Identität zugewiesen.
  • Diese bestimmt die Rollen, die er bestätigen kann.
  • Diese beiden Zuordnungen (des Benutzers zur Identität und der Identität zu den Rollen) können mit dem Befehl semanage konfiguriert werden.
  • Sie sollten unbedingt die Handbuchseite von semanage(8) lesen.
  • Alle verwalteten Konzepte haben ihre eigene Handbuchseite; zum Beispiel semanage-login(8).
  • Auch wenn die Syntax des Befehls für alle verwalteten Konzepte ähnlich ist, wird empfohlen, seine Handbuchseite zu lesen.
  • Für die meisten Unterbefehle finden Sie gemeinsame Optionen: -a zum Hinzufügen, -d zum Löschen, -m zum Ändern, -l zum Auflisten und -t zum Angeben eines Typs (oder einer Domäne).
  • semanage login -l führt die aktuellen Zuordnungen zwischen Benutzerkennungen und SELinux-Identitäten auf.
  • Benutzer, die keinen ausdrücklichen Eintrag haben, erhalten die Identität, die im Eintrag __default__ angegeben ist.
  • Der Befehl semanage login -a -s user_u benutzer ordnet die Identität user_u dem angegebenen Benutzer zu.
  • Schließlich entfernt der Befehl semanage login -d benutzer den Zuordnungseintrag, der an diesen Benutzer vergeben war.
  • semanage login -a -s user_u rhertzog
  • semanage login -l
Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
rhertzog             user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *
  • semanage login -d rhertzog
  • semanage user -l führt die Zuordnungen zwischen den SELinux-Benutzeridentitäten und den erlaubten Rollen auf.
  • Um eine neue Identität hinzuzufügen, ist es erforderlich, sowohl die entsprechenden Rollen als auch ein kennzeichnendes Präfix festzulegen, das dazu benutzt wird, einem Typ persönliche Dateien (/home/benutzer/*) zuzuordnen.
  • Als Präfix muss user, staff oder sysadm gewählt werden.
  • Das Präfix „staff“ ergibt Dateien des Typs „staff_home_dir_t“.
  • Das Erstellen einer neuen SELinux-Benutzeridentität geschieht mit dem Befehl semanage user -a -R rollen -P präfix identität.
  • Schließlich kann eine SELinux-Benutzeridentität mit dem Befehl semanage user -d identität entfernt werden.
  • semanage user -a -R 'staff_r user_r' -P staff test_u

SELinux Identitäten Zusammenfassung

Verfügbare Identitäten auflisten

  • semanage user -l
                Kennzeichnung MLS/       MLS/                          
SELinux-Benutzer Präfix     MCS-Stufe  MCS-Bereich                    SELinux-Rollen

guest_u         user       s0         s0                             guest_r
root            user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
staff_u         user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
sysadm_u        user       s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r unconfined_r
unconfined_u    user       s0         s0-s0:c0.c1023                 system_r unconfined_r
user_u          user       s0         s0                             user_r
xguest_u        user       s0         s0                             xguest_r

Linux Benutzer einem SELinux Benutzer zuweisen

Der User xinux wird dem SELinux Benutzer user_u zugewiessen
  • semanage login -a -s user_u xinux

Kontrolle

  • semanage login -l
Benutzername:        SELinux-Benutzer     MLS/MCS-Bereich      Dienst 

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *
xinux                user_u               s0                   *

Verknüpfung wieder löschen

  • semanage login -d xinux

Kontrolle

  • semanage login -l
Benutzername:        SELinux-Benutzer     MLS/MCS-Bereich      Dienst 

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *

Verknüpfung wieder löschen

  • semanage login -d xinux

Kontrolle

  • semanage login -l
Benutzername:        SELinux-Benutzer     MLS/MCS-Bereich      Dienst 

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *

Dateikontexte, Ports und Boolesche Optionen verwalten

  • Jedes SELinux-Modul stellt einen Satz von Dateibezeichnungsregeln zur Verfügung, aber es ist auch möglich, eigene Bezeichnungsregeln hinzuzufügen, um einen speziellen Fall abzudecken.
  • Wenn Sie zum Beispiel möchten, dass der Webserver in der Lage ist, Dateien innerhalb der /srv/www/-Dateihierarchie zu lesen, könnten Sie semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?" gefolgt von restorecon -R /srv/www/ ausführen.
  • Der erste Befehl registriert die neue Bezeichnungsregel und der zweite gleicht die Dateitypen gemäß den derzeitigen Bezeichnungsregeln an.
  • Ebenso sind die TCP/UDP-Ports in einer Weise gekennzeichnet, die sicherstellt, dass nur die entsprechenden Daemons an ihnen Verbindungen annehmen können.
  • Wenn Sie zum Beispiel möchten, dass der Web-Server am Port 8080 Verbindungen annehmen kann, sollten Sie den Befehl semanage port -m -t http_port_t -p tcp 8080 ausführen.
  • Einige SELinux-Module exportieren boolesche Optionen, die Sie optimieren können, um das Verhalten der Standardregeln zu ändern.
  • Das Dienstprogramm getsebool kann verwendet werden, um diese Optionen zu untersuchen (getsebool boolean zeigt eine Option an und getsebool -a alle).
  • Der Befehl setsebool boolescher Wert ändert den aktuellen Wert einer booleschen Option.
  • Die Option -P macht die Änderung dauerhaft, das bedeutet, dass der neue Wert zum Standardwert wird und über Neustarts hinweg beibehalten wird.
  • Das folgende Beispiel gewährt Webservern Zugriff auf Home-Verzeichnisse (dies ist nützlich, wenn Benutzer persönliche Websites in ~/public_html/).
  • getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
  • setsebool -P httpd_enable_homedirs on
  • getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on

Die Regeln anpassen

  • Da das SELinux-Regelwerk modular ist, könnte es interessant sein, neue Module für (möglicherweise maßgefertigte) Anwendungen zu entwickeln, für die es diese noch nicht gibt.
  • Diese neuen Module würden dann die Referenzrichtlinien ergänzen.
  • Zur Erstellung neuer Module werden die Pakete selinux-policy-dev und selinux-policy-doc benötigt.
  • Letzteres enthält die Dokumentation der Standardregeln (/usr/share/doc/selinux-policy-doc/html/) und Beispieldateien, die als Vorlagen für die Erstellung neuer Module verwendet werden können.
  • Installieren Sie diese Dateien und untersuchen Sie sie genauer:
    • cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile
    • cp /usr/share/doc/selinux-policy-doc/example.fc ./
    • cp /usr/share/doc/selinux-policy-doc/example.if ./
    • cp /usr/share/doc/selinux-policy-doc/example.te ./
  • Die Datei .te ist die wichtigste.
  • Sie legt die Regeln fest.
  • Die Datei .fc bestimmt die „Dateikontexte“, das heißt, die Typen, die den auf diese Module bezogenen Dateien zugeordnet sind.
  • Die in der Datei .fc befindlichen Daten werden während des Dateikennzeichnungsschrittes benutzt.
  • Schließlich legt die Datei .if die Schnittstelle der Module fest: es ist ein Satz „öffentlicher Funktionen“, die andere Module verwenden können, um ordnungsgemäß mit dem Modul, das Sie erstellen, zu interagieren.

Eine .fc-Datei schreiben

Das Lesen des unten stehenden Beispiels sollte genügen, um die Struktur einer derartigen Datei zu verstehen. Sie können reguläre Ausdrücke verwenden, um denselben Sicherheitskontext mehreren Dateien zuzuordnen oder auch einem ganzen Verzeichnisbaum.

Beispiel 14.2. beispiel.fc-Datei

# myapp executable will have:
# label: system_u:object_r:myapp_exec_t
# MLS sensitivity: s0
# MCS categories: <none>

/*usr/sbin/myapp -- gen_context(system_u:object_r:myapp_exec_t,s0)

Eine .if-Datei schreiben

In unten stehendem Beispiel kontrolliert die erste Schnittstelle („myapp_domtrans“), wer die Anwendung ausführen kann. Die zweite („myapp_read_log“) gewährt Schreibzugriff auf die Protokolldateien der Anwendung. Jede Schnittstelle muss einen gültigen Regelsatz erzeugen, der in eine .te-Datei eingegliedert werden kann. Sie sollten daher alle Typen, die Sie verwenden, festlegen (mit dem Makro gen_require) und Standardanweisungen benutzen, um Berechtigungen zu vergeben. Beachten Sie jedoch, dass Sie auch Schnittstellen benutzen können, die von anderen Modulen bereitgestellt werden. Der nächste Abschnitt gibt weitere Erläuterungen darüber, wie diese Berechtigungen ausgedrückt werden können. Beispiel 14.3. beispiel.if-Datei

## <summary>Myapp example policy</summary>
## <desc>
##      <p>
##              More descriptive text about myapp.  The desc
##              tag can also use p, ul, and ol
##              html tags for formatting.
##      </p>
##      <p>
##              This policy supports the following myapp features:
##              <ul>
##              <li>Feature A</li>
##              <li>Feature B</li>
##              <li>Feature C</li>
##              </ul>
##      </p>
## </desc>
#

########################################
## <summary>
##      Execute a domain transition to run myapp.
## </summary>
## <param name="domain">
##      <summary>
##      Domain allowed to transition.
##      </summary>
## </param>
#
interface(`myapp_domtrans',`
        gen_require(`
                type myapp_t, myapp_exec_t;
        ')

        domtrans_pattern($1,myapp_exec_t,myapp_t)
')

########################################
## <summary>
##      Read myapp log files.
## </summary>
## <param name="domain">
##      <summary>
##      Domain allowed to read the log files.
##      </summary>
## </param>
#
interface(`myapp_read_log',`
        gen_require(`
                type myapp_log_t;
        ')

        logging_search_logs($1)
        allow $1 myapp_log_t:file read_file_perms;
')

DOKUMENTATION Erläuterungen zu den Referenzrichtlinien


Die Referenzrichtlinien entwickeln sich wie jedes freie Softwareprojekt: auf der Grundlage freiwilliger Beiträge. Das Projekt wird von Tresys gehostet, einem der aktivsten Unternehmen im Bereich SELinux. Sein Wiki enthält Erläuterungen darüber, wie die Regeln strukturiert sind und wie Sie neue erstellen können.
→ https://github.com/SELinuxProject/refpolicy/wiki/GettingStarted

Eine .te-Datei schreiben

Sehen Sie sich die example.te-Datei an:

WEITERE SCHRITTE Die Makrosprache m4

Die SELinux-Entwickler verwendeten einen Makro-Befehlsprozessor, um die Richtlinien ordentlich zu strukturieren. Anstatt viele ähnliche allow-Anweisungen zu duplizieren, haben sie „Makrofunktionen“ erstellt, um eine Logik auf höherer Ebene zu verwenden, die auch zu viel leichter lesbaren Richtlinien führt.

Konkret wird m4 benutzt, um diese Regeln zu kompilieren. Es führt den umgekehrten Vorgang durch: es erweitert alle diese auf hoher Ebene befindlichen Anweisungen zu einer großen Datenbank von allow-Anweisungen.

Die SELinux-„Schnittstellen“ sind lediglich Makrofunktionen, die bei der Kompilierung durch einen Regelsatz ersetzt werden. Desgleichen sind einige Berechtigungen in Wirklichkeit Sätze von Berechtigungen, die bei der Kompilierung durch ihre Werte ersetzt werden.
policy_module(example,1.0.0) 1 # a non-base module name must match the file name

########################################
#
# Declarations
#

type myapp_t; 2
type myapp_exec_t;
domain_type(myapp_t)
domain_entry_file(myapp_t, myapp_exec_t) 3

type myapp_log_t;
logging_log_file(myapp_log_t) 4

type myapp_tmp_t;
files_tmp_file(myapp_tmp_t)

########################################
#
# Myapp local policy
#

allow myapp_t myapp_log_t:file { read_file_perms append_file_perms }; 5

allow myapp_t myapp_tmp_t:file manage_file_perms;
files_tmp_filetrans(myapp_t,myapp_tmp_t,file)
  • Das Modul muss mit seinem Namen und seiner Versionsnummer gekennzeichnet sein.
  • Falls das Modul neue Typen einführt, muss es sie mit Anweisungen wie dieser festlegen.
  • Zögern Sie nicht, so viele Typen zu erstellen, wie erforderlich sind, anstatt zu viele nutzlose Berechtigungen zu erteilen.
  • Diese Schnittstellen legen den Typ myapp_t als Prozess-Domain fest, die von jeder mit myapp_exec_t gekennzeichneten ausführbaren Datei benutzt werden sollte.
  • Dies fügt diesen Objekten stillschweigend auch ein exec_type-Attribut hinzu, das seinerseits anderen Modulen ermöglicht, Berechtigungen zur Ausführung dieser Programme zu gewähren: zum Beispiel erlaubt das userdomain-Modul Prozessen mit den Domains user_t, staff_t und sysadm_t, sie auszuführen.
  • Die Domains anderer eingeschränkter Anwendungen sind nicht berechtigt, sie auszuführen, es sei denn, die Regeln gewähren ihnen ähnliche Berechtigungen (dies trifft zum Beispiel auf dpkg mit seiner dpkg_t-Domain zu).
  • logging_log_file ist eine von den Referenzrichtlinien bereitgestellte Schnittstelle.
  • Sie zeigt an, dass mit diesem Typ gekennzeichnete Dateien Protokolldateien sind, die die entsprechenden Regeln wahrnehmen können sollten (zum Beispiel dem Befehl logrotate Berechtigungen erteilen, sodass er sie handhaben kann).
  • Die allow-Anweisung ist die grundlegende Anweisung zur Genehmigung eines Vorgangs.
  • Der erste Parameter ist die Prozess-Domain, der es erlaubt ist, den Vorgang auszuführen.
  • Der zweite legt das Objekt fest, das ein Prozess der zuvor genannten Domain handhaben darf.
  • Dieser Parameter hat die Form „type:class“, wobei type sein SELinux-Typ ist und class die Art des Objekts beschreibt (Datei, Verzeichnis, Socket, FIFO usw.).
  • Schließlich beschreibt der letzte Parameter die Berechtigungen (die erlaubten Vorgänge).
  • Berechtigungen sind als Satz erlaubter Vorgänge festgelegt und entsprechen diesem Schema: { vorgang1 vorgang2 }.
  • Jedoch können Sie auch Makros verwenden, die die nützlichsten Berechtigungen darstellen.
  • Die Datei /usr/share/selinux/devel/include/support/obj_perm_sets.spt listet sie auf.
  • https://selinuxproject.org/page/ObjectClassesPerms bietet eine recht vollständige Liste von Objektklassen und von Berechtigungen, die gewährt werden können.
  • Jetzt müssen Sie lediglich den kleinsten Regelsatz finden, der erforderlich ist, damit die Anwendung oder der Dienst, auf die er abzielt, ordnungsgemäß funktionieren.
  • Um dies zu erreichen, sollten Sie sich gut damit auskennen, wie die Anwendung funktioniert und welche Art von Daten sie verarbeitet oder erzeugt.
  • Jedoch ist auch eine auf Erfahrung beruhende Vorgehensweise möglich.
  • Nachdem die relevanten Objekte richtig gekennzeichnet sind, können Sie die Anwendung im permissive-Modus benutzen: die Vorgänge, die verboten würden, werden protokolliert, werden aber weiterhin ausgeführt.
  • Durch eine Analyse der Protokolle können Sie nun die Vorgänge identifizieren, die erlaubt werden sollen.
  • Hier ist ein Beispiel eines derartigen Protokolleintrags:
avc:  denied  { read write } for  pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 
tclass=fifo_file permissive=1

Um diese Mitteilung besser verstehen zu können, gehen wir sie Schritt für Schritt durch.

Analyse eines SELinux-Ablaufs

Meldung Beschreibung
avc: denied Ein Vorgang wurde abgelehnt.
{ read write } Dieser Vorgang erforderte die Berechtigungen read und write.
pid=1876 Der Prozess mit der PID 1876 hat den Vorgang ausgeführt (oder hat versucht, ihn auszuführen).
comm="syslogd" Der Prozess war eine Ausführung des Programms syslogd.
name="xconsole" Das Zielobjekt wurde xconsole genannt. Manchmal kann man stattdessen eine "path"-Variable - mit dem vollen Pfad - haben.
dev=tmpfs das Objekt enthält (zum Beispiel „sda3“).
ino=5510 Das Objekt ist mit der Inode-Nummer 5510 bezeichnet.
scontext=system_u:system_r:syslogd_t:s0 Dies ist der Sicherheitskontext des Prozesses, der den Vorgang ausgeführt hat.
tcontext=system_u:object_r:device_t:s0 Dies ist der Sicherheitskontext des Zielobjekts.
tclass=fifo_file Das Zielobjekt ist eine FIFO-Datei.
  • Durch Betrachtung dieses Protokolleintrags ist es möglich, eine Regel zu erstellen, die diesen Vorgang erlauben würde.
  • Zum Beispiel: allow syslogd_t device_t:fifo_file { read write }.
  • Dieser Prozess kann automatisiert werden und genau dies bietet der Befehl audit2allow (aus dem Paket policycoreutils).
  • Diese Herangehensweise ist nur sinnvoll, wenn die verschiedenen Objekte bereits in Übereinstimmung mit den erforderlichen Einschränkungen richtig gekennzeichnet sind.
  • In jedem Fall müssen Sie die erzeugten Regeln sorgfältig überprüfen und sie auf der Grundlage ihrer Kenntnis der Anwendung bewerten.
  • Faktisch tendiert diese Herangehensweise dazu, mehr Berechtigungen zu erteilen als tatsächlich erforderlich sind.
  • Die richtige Lösung besteht häufig darin, neue Typen zu erstellen und dann nur diesen Typen Berechtigungen zu gewähren.
  • Es kommt auch vor, dass ein verweigerter Vorgang für die Anwendung keine Folgen hat.
  • In diesem Fall kann es besser sein, einfach eine „dontaudit“-Regel hinzuzufügen, um einen Protokolleintrag zu vermeiden, obwohl eine Verweigerung stattgefunden hat.
  • ERGÄNZUNGEN Keine Rollen in den Richtlinien
  • Es mag seltsam erscheinen, dass bei der Erstellung neuer Regeln Rollen überhaupt nicht auftreten.
  • SELinux verwendet nur die Domains um herauszufinden, welche Vorgänge erlaubt sind.
  • Die Rolle kommt nur indirekt zum Tragen, indem sie es dem Benutzer erlaubt, zu einer anderen Domain zu wechseln.
  • SELinux basiert auf Type Enforcement, d.h. der Typ ist das einzige Element, welches bei der Gewährung von Berechtigungen berücksichtigt wird.

Die Dateien kompilieren

  • Sobald die 3 Dateien (example.if, example.fc und example.te) Ihren Erwartungen für die neuen Regeln entsprechen, benennen Sie sie in myappEndung um und führen Sie make NAME=devel aus, um ein Modul in der Datei myapp.pp zu erzeugen (Sie können es sofort mit semodule -i myapp.pp laden).
  • Wenn mehrere Module definiert sind, erzeugt make alle entsprechenden .pp-Dateien.

Quelle