Grafische Oberfläche für SELinux

Steuerzentrale

Die Zeiten, in denen die Konfiguration eines SELinux-Systems als Wissenschaft galt, gehen langsam dem Ende zu. Mittlerweile existieren eine ganze Reihe unterschiedlicher Tools, sowohl als Kommandozeilenvariante wie auch als grafisches Frontend. Dieser Artikel stellt die wichtigsten Tools für die Administration und zum Entwickeln eigener Policy-Module vor.

Aktuelle SELinux-Implementationen benutzen die sogenannte Reference-Policy als Regelwerk. Neben einem Standard-Modul für Basis-Einstellungen besteht diese aus einer Vielzahl einzelner Module für die Applikationen die sich unter dem Schutzschild von SELinux befinden. Eine genaue Übersicht der gerade geladenen Modul zeigt das Tool »semodule« an (Listing 1).

Listing 1

 

semodule -l
amavis  1.5.1
amtu    1.1.0
apcupsd 1.3.0
audio_entropy   1.3.0
awstats 1.0.0
bitlbee 1.0.0
calamaris       1.2.0
ccs     1.3.0
cdrecord        1.4.0
certwatch       1.0
cipe    1.4.0
[...]

Mit Hilfe von »semodule« lassen sich dem System auch neue Module hinzufügen beziehungsweise bestehende Module entladen. Ein Blick in die Hilfe-Seiten zeigt alle möglichen Optionen an.

Wer einen allgemeinen Überblick über das gerade eingesetzte Regelwerk sucht, der wird schnell auf »seinfo« stoßen. Ohne weitere Option aufgerufen, zeigt es jede Menge Informationen zur eingesetzten Policy an (Listing 2).

Listing 2

 

seinfo
Statistics for policy file: /etc/selinux/targeted/policy/policy.23
Policy Version & Type: v.23 (binary, mls)
   Classes:            73    Permissions:       223
   Sensitivities:       1    Categories:       1024
   Types:            2204    Attributes:        206
   Users:               8    Roles:              12
   Booleans:          117    Cond. Expr.:       137
   Allow:          165464    Neverallow:          0
   Auditallow:         43    Dontaudit:      136430
   Type_trans:       6446    Type_change:        55
   Type_member:        14    Role allow:         17
   Role_trans:         68    Range_trans:      1216
   Constraints:        59    Validatetrans:       0
   Initial SIDs:       27    Fs_use:             18
   Genfscon:           77    Portcon:           322
   Netifcon:            0    Nodecon:             8

Das Tool »semanage« kann die bestehende Policy um bestimmte Elemente erweitern. Ein Zugriff auf die Policy-Quellen ist hierfür nicht notwendig. Die binäre Policy-Datei »/etc/selinux/targeted/policy/policy.23« wird automatisch beim Aufruf von »semanage« neu kompiliert. Hierzu nun einige Beispiele. Unter SELinux bekommen alle Netzwork-Ports der geschützen Prozesse ein Security-Label zugewiesen, das auf »port_t« endet. Folgender Befehl zeigt alle Ports, auf die der Webserver zugreifen darf:

# semanage port -l | grep http_port_t
http_port_t                    tcp      80, ↩
443, 488, 8008, 8009, 8443

Möchte man nun die passenden Regeln für den Zugriff des Webservers auf die Netzwerk-Ports aus der Policy sehen, hilft das Tool »sesearch« weiter:

# sesearch --allow -d -s httpd_t -t ↩
http_port_t
Found 2 semantic av rules:
   allow httpd_t http_port_t : tcp_socket↩
    { name_bind name_connect };
   allow httpd_t http_port_t : tcp_socket↩
    name_connect ;

Soll nun der Webserver auch auf einem anderen Port starten dürfen, ist dieser zusätzliche Port ebenfalls mit dem Label »http_port_t« zu versehen. Einen zusätzlichen Eintrag in der Policy nimmt »semanage« vor:

semanage port -a -t http_port_t -p tcp 8888

Auch ähnliche Weise lassen sich andere Elemente zur binären SELinux-Policy hinzufügen, ohne Zugriff auf die Sourcen besitzen zu müssen. Dies ist im Vergleich zu älteren Implementierungen ein großer Vorteil.

Grafische Policy-Entwicklung

Ein weiteres Tool, welches in den letzten Monaten enorm an Funktionsumfang zugenommen hat, ist »system-config-selinux« . Hiermit lassen sich sämtliche Einstellungen auf einem SELinux-System bequem an zentraler Stelle vornehmen. Dazu zählt nicht nur das Setzen des SELinux-Modes – beispielsweise Enforcing, um alle Regelsätze durchzusetzen; Permissive, um lediglich ein Logging nicht erlaubter Aktionen zu aktivieren, die Aktionen selbst aber nicht zu unterbinden; oder aber Disabled, was den Schutz durch SELinux komplett deaktiviert.

Auch Booleans lassen sich über »system-config-selinux« konfigurieren. Diese existieren schon seit der ersten Version von SELinux, jedoch ist deren Anzahl im Laufe der letzten Jahre stark angestiegen. Mit Booleans kann der Administrator bestimmte Eigenschaften der Policy aktivieren beziehungsweise deaktivieren ohne hierfür einen neuen Policy-Eintrag zu erzeugen. Der Policy-Eintrag ist bereits vorhanden, er wird jedoch erst beim Setzen des Booleans aktiv. Die Man-Pages der einzelnen Targeted-Daemons beschreiben alle verfügbaren Booleans sehr ausführlich. Für den Webserver empfiehlt sich daher beispielsweise ein Blick in die »httpd_selinux« Hilfe-Seiten (Abbildung 1).

Abbildung 1: system-config-selinux gibt einen guten Überblick über die verfügbaren Booleans.

Das bei weitem interessanteste Feature stellt aber sicherlich die Möglichkeit dar, eigene Policy-Module zu entwickeln. Hierfür bietet »system-config-selinux« einen Wizard an. Er stellt einige grundlegene Fragen zur zu schützenden Applikation, beispielsweise ob diese auf das Netzwerk zugreift, um was für eine Art von Anwendung es sich handelt (init, xinetd, User-Anwendung), wo die Log-Dateien liegen und dergleichen. Sind alle Fragen beantwortet, erzeugt das Tool insgesamt vier Dateien. Eine so genannte Type-Enforcement-, eine File-Context-, eine Interface-Datei sowie ein kleines Shell-Skript, das das neue Modul zum System hinzufügt (Abbildung 2).

Abbildung 2: Mit Hilfe von system-config-selinux lassen sich eigene Policy-Module sehr einfach erzeugen.

Dieser Artikel beschreibt als Beispiel die Entwicklung eines neuen Policy-Moduls für die Kalendarsoftware Ical. Startet man den Wizard aus »system-config-selinux« , ist als Anwendungstyp eine User-Applikation auszuwählen, als Pfad zum eigentlichen Binärprogramm gibt man »/usr/bin/ical« an und als Namen für das Policy-Modul »ical« . Da die Applikation nicht auf das Netzwerk zugreift, lassen sich diese Fragen unbeantwortet überspringen. Mit diesen Informationen kann der Wizard nun ein Art Grundgerüst für das neue Policy-Modul entwerfen. Abschließend ist noch festzulegen, in welchem Ordner die erzeugten Policy-Dateien liegen sollen (Abbildung 3).

Abbildung 3: Sind alle Fragen des Wizards beantwortet, erzeugt dieser die notwendigen Dateien für das neue Policy-Modul.

Der Wizard erzeugt nun die folgenden Dateien:

  • »ical.te« (Listing 3: ical.te) Bei dieser Datei handelt es sich um die Type-Enforcement-Datei, in der die einzelnen SELinux-Typen definiert sind. Sie enthält auch alle Regelsätze, wer was mit welchen Rechten darf. Die Regelsätze bestehen jedoch nicht nur aus Allow-Anweisungen, sondern können auch Interfaces enthalten. Interfaces sind Makros, mit denen man auf Resourcen anderer Module zugreifen kann.

Listing 3

<C>ical.te<C> (Ausschnitt)

## internal communication is often done using fifo and unix sockets.
allow ical_t self:fifo_file rw_file_perms;
allow ical_t self:unix_stream_socket create_stream_socket_perms;
files_read_etc_files(ical_t)
libs_use_ld_so(ical_t)
libs_use_shared_libs(ical_t)
miscfiles_read_localization(ical_t)
allow ical_t ical_tmp_t:file manage_file_perms;
allow ical_t ical_tmp_t:dir create_dir_perms;
files_tmp_filetrans(ical_t,ical_tmp_t, { file dir })
logging_send_audit_msgs(ical_t)
  • »ical.fc« (Listing 4: ical.fc) Hier sind die File-Context-Informationen für die einzelnen ical-Dateien gespeichert. Da es sich bei Ical um eine sehr kleine Anwendung handelt, ist hier nur das eigentliche Binärprogramm aufgelistet. Gäbe es auch noch Log-Dateien oder ähnliches, so könnte man diese hier ebenfalls aufführen und mit einem Typ verknüpfen. Wichtig ist, dass das Verknüpfen mit einem Typ immer nur dann klappt, wenn man er in der Type-Enforcement-Datei definiert ist.

Listing 4

<C>ical.fc<C>

/usr/bin/ical                   --      gen_context(system_u:object_r:ical_exec_t,s0)
HOME_DIR/\.calendar             --      gen_context(system_u:object_r:ical_file_t,s0)
  • »ical.if« (Listing 5 ical.if) Hier lassen sich Makros für das eigene Modul definieren. Mit Hilfe dieser Makros können dann wiederum andere Module auf die eigenen Ressourcen zugreifen.

Listing 5

<C>ical.if<C> (Ausschnitt)

interface(`ical_run',`
        gen_require(`
                type ical_t;
        ')
        ical_domtrans($1)
        role $2 types ical_t;
        dontaudit ical_t $3:chr_file rw_term_perms;
')
  • »ical.sh« (Listing 6 ical.sh) Dieses Skript baut aus den drei einzelnen Policy-Dateien ein binäres Policy-Modul. Hat das geklappt, fügt es das neue Modul auch gleich zum System hinzu; die aufgeführten Dateien bekommen das Security-Label aus der File-Context-Datei gesetzt.

Listing 6

<C>ical.sh<C> (Ausschnitt)

...
echo "Building and Loading Policy"
set -x
make -f /usr/share/selinux/devel/Makefile
/usr/sbin/semodule -i ical.pp
# Fixing the file context on /usr/bin/ical
/sbin/restorecon -F -R -v /usr/bin/ical
...

Im nächsten Schritt ist nun das Skript »ical.sh« aufzurufen, um das neue Policy-Modul aus den einzelnen Dateien zu erzeugen.

Ruft man nun »ical« auf, so wird man feststellen, dass die Anwendung noch nicht einwandfrei funktioniert. Der Grund dafür: »system-config-selinux« hat bisher nur eine Art Grundgerüst für das Policy-Modul entwickelt. Dieses ist nun entsprechend an die Applikation anzupassen. Hierfür versetzt man das System, mittels »setenforce 0« , temporär in den SELinux-Permissive Mode. Dieser Mode setzt die bestehenden Regeln nicht durch, loggt jedoch alle eigentlich verbotenen Zugriffe. Hiermit lässt sich sehr schön nachvollziehen, welche Zugriffe die Ical-Applikation ausführen möchte. Ob man dann wirklich alle Zugriffe erlaubt ,ist im Einzelfall zu entscheiden. Manchmal möchten Applikationen Aktionen ausführen, die gar nicht notwendig sind, damit die Anwendung problemfrei arbeitet. Solche unnötigen Aktionen sind zu erkennen und mit einer »dontaudit« -Regel zu versehen, damit nicht bei jedem nicht erlaubtem Zugriff ein Log-Eintrag ensteht.

Befindet sich das System im Permissive-Mode, so lässt sich die Ical-Anwendung starten. Schaut man sich nun das Log des Audit-Daemons, »/var/log/audit/audit.log« , an, findet man hier noch jede Menge SELinux-Fehlermeldungen. Anhand dieser Fehlermeldungen lassen sich mittels »audit2allow« nun neue Allow-Anweisungen erzeugen. Ruft man »audit2allow« mit der Option »-R« auf, sucht das Tool nach passenden Makros und verwendet diese. Dies ist wesentlich übersichtlicher als für jeden Logeintrag eine eigene Allow-Regel anzulegen. Wie bereits erwähnt sollte man jedoch nur die wirklich notwendigen Zugriffe erlauben und für alles andere Dontaudit-Regeln verwenden. Um anhand der Logeinträge nun zusätzliche Regeln zu erzeugen, ruft man »audit2allow« wie folgt auf:

# grep ical /var/log/audit/audit.log↩
|audit2allow -l -R > new_rules.te

Anhand der Datei »new_rules.te« kann man nun entscheiden, welche dieser Regeln wirklich notwendig sind und man zur Datei »ical.te« hinzufügen möchte. (Listing5: new_rules.te). Schaut man sich die Regeln an, greift Ical beispielsweise auf das Home-Verzeichnis des aufrufenden Benutzers zu, um an die Datei ».calendar« zu kommen. Nun soll die Applikation aber nicht uneingeschränkten Zugriff auf das Home-Verzeichnis bekommen. Stattdessen erzeugen wir einen neuen File-Type für diese Datei, »ical_file_t« . Diesen nehmen wir bei den Anpassungen mit in die Type-Enforcement-Datei auf. Damit die Datei ».calendar« auch das passende Label bekommt, ist hierfür ein weiterer Eintrag in der Policy vorzunehmen. Dies kann kann beispielsweise als Teil der Datei »ical.fc« erfolgen. Hier wäre dann die folgende zusätzliche Zeile einzutragen:

HOME_DIR/\.calendar   --  gen_context↩
(system_u:object_r:ical_file_t,s0)

Alternativ lassen sich Eigenschaften der Policy auch ändern, ohne dafür Zugriff auf die Quellen zu besitzen, das wurde bereits weiter oben im Artikel beschrieben. Genauso könnte man nun auch eine Datei mit einem Security-Label verknüpfen:

# semanage fcontext -a -t ical_file_t ↩
'/home/[^/]*/\.calendar'

Sind schließlich alle Änderungen umgesetzt, sollte die neue »ical.te« aussehen wie in Listing 7. Nun kann man »ical.sh« erneut aufrufen, um ein neues Policy-Modul zu generieren und zu laden. Ein abschließender Aufruf von »restorecon« setzt nun auch das passende Label von ».calendar« :

# restorecon -v /home/tscherf/.calendar
restorecon reset /home/tscherf/.calendar ↩
context system_u:object_r:user_home_t:s0->↩
system_u:object_r:ical_file_t:s0

Versetzt man die Maschine anschließend mittels »setenforce 1« wieder in den Enforcing-Mode und startet »ical« , so sollte die Applikation diesmal problemfrei funktionieren und, dank der »dontaudit« -Regeln, auch keine Fehlermeldungen mehr generieren. Das »ical« nun wirklich in einer eigenen SELinux-Domäne läuft, bestätigt ein abschließender Blick in die Prozessliste:

ps -AZ | grep ical
unconfined_u:unconfined_r:ical_t ? 00:00:00 ↩
ical

Fazit

Mit den heute verfügbaren Tools ist es wirklich keine Hexerei mehr, eine eigene SELinux-Policy zu erzeugen. Gerade »system-config-selinux« bietet mit seinem Wizard eine sehr umfangreiche Hilfestellung. Um ein genaues Auseinandersetzen mit der Applikation, die es zu schützen gilt, wird man aber auch in Zukunft nicht herum kommen.

comments powered by Disqus
Mehr zum Thema

Mandatory-Access-Control (MAC) mit SE Linux

Gelangen Eindringlinge erst einmal auf den eigenen Server, steht das angeblich so sichere Linux schnell nicht mehr so gut da. Haben sie erst einmal Root-Rechte, haben sie uneingeschänkten Zugang zu allem. SE Linux schiebt einen zusätzlichen Riegel vor.

Artikel der Woche

Registry für Docker-Images

Wer selber Docker-Images herstellt, braucht auch eine eigene Registry. Diese gibt es ebenfalls als Docker-Image, aber nur mit eingeschränkter Funktionalität. Mit einem Auth-Server wird daraus ein brauchbares Repository für Images. (mehr)
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

Google+

Ausgabe /2018