Zum Inhalt springen

Linux/SELinux/Praxis/2: Unterschied zwischen den Versionen

Aus Foxwiki
Die Seite wurde neu angelegt: „ = SCHRITT 2.1: Woher kommt der „richtige“ Kontext (File Contexts) = In der ersten Phase wurden die tatsächlichen Dateilabels betrachtet: was in <code>security.selinux</code> gespeichert ist, wie dies in <code>ls -Z</code> aussieht und warum sich <code>cp</code> und <code>mv</code> unterschiedlich verhalten. In dieser Lektion kommt die nächste Modellebene hinzu: '''SELinux speichert nicht nur das aktuelle Label eines Objekts, sondern auch die Vorst…“
 
 
(13 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
== Woher kommt der „richtige“ Kontext (File Contexts) ==
In der ersten Phase wurden die tatsächlichen Dateilabels betrachtet: was in security.selinux gespeichert ist, wie dies in ls -Z aussieht und warum sich cp und mv unterschiedlich verhalten


= SCHRITT 2.1: Woher kommt der „richtige“ Kontext (File Contexts) =
In dieser Lektion kommt die nächste Modellebene hinzu: '''SELinux speichert nicht nur das aktuelle Label eines Objekts, sondern auch die Vorstellung davon, welcher Kontext einem Pfad gemäß den Regeln der Policy zugewiesen sein soll'''
In der ersten Phase wurden die tatsächlichen Dateilabels betrachtet: was in <code>security.selinux</code> gespeichert ist, wie dies in <code>ls -Z</code> aussieht und warum sich <code>cp</code> und <code>mv</code> unterschiedlich verhalten.
Für das Verständnis der Logik der SELinux-Labeling-Regeln müssen zwei Begriffe strikt voneinander getrennt werden


In dieser Lektion kommt die nächste Modellebene hinzu: '''SELinux speichert nicht nur das aktuelle Label eines Objekts, sondern auch die Vorstellung davon, welcher Kontext einem Pfad gemäß den Regeln der Policy zugewiesen sein soll'''.
# '''Tatsächliches Label (Security Context).''' Das sind die Daten, die physisch in den erweiterten Attributen des Dateisystems (extended attributes — xattr) auf dem Datenträger gespeichert sind
----Für das Verständnis der Logik der SELinux-Labeling-Regeln müssen zwei Begriffe strikt voneinander getrennt werden:
#* Genau dieses Label sehen der Linux-Kernel und das SELinux-Modul beim Zugriff auf eine Datei und verwenden es für die Zugriffsentscheidung
# '''Erwarteter Kontext (File Context).''' Das ist eine Regel, die in der '''SELinux-Policy-Datenbank''' definiert ist
#* Sie legt fest, welches Label einer Datei oder einem Verzeichnis an einem bestimmten Pfad ''zugewiesen werden soll''


# '''Tatsächliches Label (Security Context).''' Das sind die Daten, die physisch in den erweiterten Attributen des Dateisystems (extended attributes — <code>xattr</code>) auf dem Datenträger gespeichert sind. Genau dieses Label sehen der Linux-Kernel und das SELinux-Modul beim Zugriff auf eine Datei und verwenden es für die Zugriffsentscheidung.
=== Wo SELinux Informationen über erwartete Kontexte speichert ===
# '''Erwarteter Kontext (File Context).''' Das ist eine Regel, die in der '''SELinux-Policy-Datenbank''' definiert ist. Sie legt fest, welches Label einer Datei oder einem Verzeichnis an einem bestimmten Pfad ''zugewiesen werden soll''.
In der Default-Policy befinden sich die Änderungen im Zusammenhang mit File Contexts im Verzeichnis
/etc/selinux/default/contexts/files/


----
Die aktuelle Policy kann mit dem Befehl sestatus angezeigt werden


== Wo SELinux Informationen über erwartete Kontexte speichert ==
  # sestatus
In der Default-Policy befinden sich die Änderungen im Zusammenhang mit File Contexts im Verzeichnis:
  ..
<code>/etc/selinux/default/contexts/files/</code>
 
* Die aktuelle Policy kann mit dem Befehl <code>sestatus</code> angezeigt werden:
 
  <code># sestatus
  ...
  SELinux root directory:        /etc/selinux
  SELinux root directory:        /etc/selinux
  Loaded policy name:            default
  Loaded policy name:            default
  ...</code>
  ..
 
=== Struktur der File-Context-Dateien: ===


* <code>file_contexts</code> — Basistabelle der File Contexts der aktiven Policy;
==== Struktur der File-Context-Dateien ====
* <code>file_contexts.local</code> — lokale administrative Ergänzungen;
* file_contexts — Basistabelle der File Contexts der aktiven Policy
* <code>file_contexts.homedirs</code> — separate Einstellungen für Home-Verzeichnisse;
* file_contexts.local — lokale administrative Ergänzungen
* <code>.subs</code> und <code>.subs_dist</code> — Dateien für Pfadsubstitutionen
* file_contexts.homedirs — separate Einstellungen für Home-Verzeichnisse
* .subs und .subs_dist — Dateien für Pfadsubstitutionen


Um zu verstehen, wie das System Pfade und Labels einander zuordnet, öffnen wir die Datei <code>/etc/selinux/default/contexts/file/file_contexts</code>:
Um zu verstehen, wie das System Pfade und Labels einander zuordnet, öffnen wir die Datei /etc/selinux/default/contexts/file/file_contexts
  <code>head /etc/selinux/default/contexts/files/file_contexts</code>
  head /etc/selinux/default/contexts/files/file_contexts


* Ausgabe:
; Ausgabe
 
  /.*                              system_u:object_r:default_t:s0
  <code>/.*                              system_u:object_r:default_t:s0
  /a?quota\.(user|group)    --      system_u:object_r:quota_db_t:s0
  /a?quota\.(user|group)    --      system_u:object_r:quota_db_t:s0
  /sys(/.*)?                        system_u:object_r:sysfs_t:s0
  /sys(/.*)?                        system_u:object_r:sysfs_t:s0
Zeile 44: Zeile 41:
  /etc/.*                          system_u:object_r:etc_t:s0
  /etc/.*                          system_u:object_r:etc_t:s0
  /opt/.*                          system_u:object_r:usr_t:s0
  /opt/.*                          system_u:object_r:usr_t:s0
  /run/.*                 <<none>></code>
  /run/.*                 <<none>>
Jede Zeile in dieser Datei stellt eine feste Anweisung für SELinux dar und besteht aus zwei oder drei Spalten:


# '''Regulärer Ausdruck (Regular Expression).''' Die erste Spalte beschreibt den Pfad. SELinux verwendet reguläre Ausdrücke im PCRE*-Format.
Jede Zeile in dieser Datei stellt eine feste Anweisung für SELinux dar und besteht aus zwei oder drei Spalten
#* Beispielsweise bedeutet der Ausdruck <code>/var/www(/.*)?</code>: sowohl das Verzeichnis <code>/var/www</code> selbst als auch absolut jede Datei oder jedes Unterverzeichnis darin.
# '''Regulärer Ausdruck (Regular Expression).''' Die erste Spalte beschreibt den Pfad
#* Ausführlicher über reguläre Ausdrücke sprechen wir in den nächsten Lektionen.
#* SELinux verwendet reguläre Ausdrücke im PCRE*-Format
# '''Objekttyp (optional).''' Die zweite Spalte kann präzisieren, für welchen Typ von Dateisystemobjekten die Regel gilt.
#* Beispielsweise bedeutet der Ausdruck /var/www(/.*)?: sowohl das Verzeichnis /var/www selbst als auch absolut jede Datei oder jedes Unterverzeichnis darin
#* <code>-d</code> — nur auf Verzeichnisse anwenden.
#* Ausführlicher über reguläre Ausdrücke sprechen wir in den nächsten Lektionen
#* <code>--</code> — nur auf reguläre Dateien anwenden.
# '''Objekttyp (optional).''' Die zweite Spalte kann präzisieren, für welchen Typ von Dateisystemobjekten die Regel gilt
#* -d — nur auf Verzeichnisse anwenden
#* -- — nur auf reguläre Dateien anwenden
#* ''Falls die Spalte fehlt, gilt die Regel für alle Objekte am angegebenen Pfad.''
#* ''Falls die Spalte fehlt, gilt die Regel für alle Objekte am angegebenen Pfad.''
# '''Erwarteter Kontext (Security Context).''' Die letzte Spalte enthält das Referenzlabel, das dem Objekt zugewiesen werden soll. Das wichtigste Element hierbei ist '''Type''' (zum Beispiel <code>httpd_sys_content_t</code>), der die Zugriffsdomänen bestimmt.
# '''Erwarteter Kontext (Security Context).''' Die letzte Spalte enthält das Referenzlabel, das dem Objekt zugewiesen werden soll
#* Das wichtigste Element hierbei ist '''Type''' (zum Beispiel httpd_sys_content_t), der die Zugriffsdomänen bestimmt


(* PCRE - Perl-compatible regular expression)
(* PCRE - Perl-compatible regular expression)


Bei der Initialisierung des Dateisystems oder beim erzwungenen Zurücksetzen der Labels (Relabeling) liest der Kernel diese Datei Zeile für Zeile von oben nach unten. Wenn das Dienstprogramm eine Übereinstimmung zwischen dem Dateipfad und dem regulären Ausdruck findet, weist es dem Objekt den entsprechenden Kontext aus der dritten Spalte zu.
Bei der Initialisierung des Dateisystems oder beim erzwungenen Zurücksetzen der Labels (Relabeling) liest der Kernel diese Datei Zeile für Zeile von oben nach unten
----
* Wenn das Dienstprogramm eine Übereinstimmung zwischen dem Dateipfad und dem regulären Ausdruck findet, weist es dem Objekt den entsprechenden Kontext aus der dritten Spalte zu


= SCHRITT 2.2: Struktur von File-Context-Regeln und ihre Prioritäten =
== Struktur von File-Context-Regeln und ihre Prioritäten ==
Im vorherigen Schritt wurde die Quelle der Dateikontexte analysiert — die Datenbank <code>file_contexts</code>. In dieser Lektion gehen wir tiefer in die Funktionsweise dieser Datenbank: wie das System die Zuordnungstabelle <code>path -> label</code> genau liest und wie es entscheidet, welcher Kontext zugewiesen wird, wenn mehrere Regeln auf denselben Pfad passen.
Im vorherigen Schritt wurde die Quelle der Dateikontexte analysiert — die Datenbank file_contexts
* In dieser Lektion gehen wir tiefer in die Funktionsweise dieser Datenbank: wie das System die Zuordnungstabelle path -> label genau liest und wie es entscheidet, welcher Kontext zugewiesen wird, wenn mehrere Regeln auf denselben Pfad passen


== Format einer File-Context-Regel ==
=== Format einer File-Context-Regel ===
Jeder Eintrag in <code>file_contexts</code>, <code>file_contexts.local</code> und <code>file_contexts.homedirs</code> hat dieselbe Grundform:
Jeder Eintrag in file_contexts, file_contexts.local und file_contexts.homedirs hat dieselbe Grundform
  <code>pathname [file_type] context</code>
  pathname [file_type] context


* <code>pathname</code> — vollständiger Pfad oder regulärer PCRE-Ausdruck, anhand dessen SELinux nach Übereinstimmungen sucht.
* pathname — vollständiger Pfad oder regulärer PCRE-Ausdruck, anhand dessen SELinux nach Übereinstimmungen sucht
* <code>file_type</code> — optionale Einschränkung auf einen Objekttyp.
* file_type — optionale Einschränkung auf einen Objekttyp
* <code>context</code> — der Kontext, der dem Objekt zugewiesen werden soll
* context — der Kontext, der dem Objekt zugewiesen werden soll


=== pathname ===
==== pathname ====
Betrachten wir ein Beispiel für eine Regel:
Betrachten wir ein Beispiel für eine Regel
  <code>/var/www(/.*)?    system_u:object_r:httpd_sys_content_t:s0</code>
  /var/www(/.*)?    system_u:object_r:httpd_sys_content_t:s0


* Die Regel deckt den gesamten Teilbaum <code>/var/www</code> ab, also das Verzeichnis selbst und alle darin enthaltenen Objekte.
* Die Regel deckt den gesamten Teilbaum /var/www ab, also das Verzeichnis selbst und alle darin enthaltenen Objekte


=== file_type ===
==== file_type ====
Die optionale zweite Spalte schränkt die Regel auf einen bestimmten Objekttyp ein. In File Contexts werden folgende Bezeichnungen verwendet:
Die optionale zweite Spalte schränkt die Regel auf einen bestimmten Objekttyp ein
{| class="wikitable"
 
!Wert
In File Contexts werden folgende Bezeichnungen verwendet
!Beschreibung
{| class="wikitable options big col1center"
! Wert !! Beschreibung
|-
|-
|<code>-d</code>
| d
|Verzeichnis
|Verzeichnis
|-
|-
|<code>--</code>
| -
|reguläre Datei
|reguläre Datei
|-
|-
|<code>-l</code>
| l
|symbolischer Link
|symbolischer Link
|-
|-
|<code>-s</code>
| s
|Socket
|Socket
|-
|-
|<code>-p</code>
| p
|Named Pipe
|Named Pipe
|-
|-
|<code>-c</code>
| c
|Zeichengerätedatei
|Zeichengerätedatei
|-
|-
|<code>-b</code>
| b
|Blockgerätedatei
|Blockgerätedatei
|}
|}


=== context ===
==== context ====
Die letzte Spalte enthält genau den '''erwarteten Security Context''', der für einen übereinstimmenden Pfad zurückgegeben werden soll.
Die letzte Spalte enthält genau den '''erwarteten Security Context''', der für einen übereinstimmenden Pfad zurückgegeben werden soll
* Im Normalfall ist das ein vollständiges Label im Format user:role:type:range


* Im Normalfall ist das ein vollständiges Label im Format <code>user:role:type:range</code>.
Zulässig ist auch der spezielle Wert <<none>>
* Zulässig ist auch der spezielle Wert <code><<none>></code>: Er bedeutet, dass beim Relabeling für den übereinstimmenden Pfad kein Kontext gesetzt werden soll und dass ein Lookup kein Ergebnis zurückliefert.
* Er bedeutet, dass beim Relabeling für den übereinstimmenden Pfad kein Kontext gesetzt werden soll und dass ein Lookup kein Ergebnis zurückliefert


----
=== Prioritäten der Regeln ===


== Prioritäten der Regeln ==
==== Basis- und modulare Policy-Definitionen ====
Um Konflikte zu vermeiden, verwendet der SELinux-Parser ein striktes Prioritätssystem


=== Basis- und modulare Policy-Definitionen ===
# '''Eine exakte Übereinstimmung hat die höchste Priorität.''' Eine Regel, die einen Pfad ohne Platzhalter regulärer Ausdrücke beschreibt (zum Beispiel genau /etc/passwd), gewinnt immer gegenüber allgemeineren Ausdrücken
Um Konflikte zu vermeiden, verwendet der SELinux-Parser ein striktes Prioritätssystem:
# '''Die maximale Länge der Übereinstimmung bestimmt die Spezifität.''' Falls es keine exakte Übereinstimmung gibt, gewinnt die spezifischste Regel — also diejenige, bei der der übereinstimmende Teil des Pfads länger ist
#* Eine Regel für /var/www/html(/.*)? sticht eine allgemeinere Regel für /var/www(/.*)?
# '''Eine explizite Angabe der Objektklasse erhöht die Priorität.''' Bei gleicher Länge der Übereinstimmung hat eine Regel mit explizit angegebenem Klassifizierer (zum Beispiel -d für Verzeichnisse oder -- für reguläre Dateien) Vorrang vor einer Regel ohne Klassenangabe


# '''Eine exakte Übereinstimmung hat die höchste Priorität.''' Eine Regel, die einen Pfad ohne Platzhalter regulärer Ausdrücke beschreibt (zum Beispiel genau <code>/etc/passwd</code>), gewinnt immer gegenüber allgemeineren Ausdrücken.
Dank dieser Hierarchie werden Basislabels auf der Ebene der Wurzel des Dateisystems gesetzt und dann beim tieferen Abstieg im Verzeichnisbaum weiter verfeinert und überschrieben
# '''Die maximale Länge der Übereinstimmung bestimmt die Spezifität.''' Falls es keine exakte Übereinstimmung gibt, gewinnt die spezifischste Regel — also diejenige, bei der der übereinstimmende Teil des Pfads länger ist. Eine Regel für <code>/var/www/html(/.*)?</code> sticht eine allgemeinere Regel für <code>/var/www(/.*)?</code>.
# '''Eine explizite Angabe der Objektklasse erhöht die Priorität.''' Bei gleicher Länge der Übereinstimmung hat eine Regel mit explizit angegebenem Klassifizierer (zum Beispiel <code>-d</code> für Verzeichnisse oder <code>--</code> für reguläre Dateien) Vorrang vor einer Regel ohne Klassenangabe.


Dank dieser Hierarchie werden Basislabels auf der Ebene der Wurzel des Dateisystems gesetzt und dann beim tieferen Abstieg im Verzeichnisbaum weiter verfeinert und überschrieben.
==== Lokale Regeln in file_contexts.local ====
Für lokale SELinux-Regeln gilt eine andere Prioritätslogik als für Basis- und modulare Policy-Definitionen


=== Lokale Regeln in <code>file_contexts.local</code> ===
# '''Lokale Regeln haben Vorrang vor der Policy.''' Jeder Eintrag aus file_contexts.local, der zum Beispiel über semanage fcontext hinzugefügt wurde, wird vor den entsprechenden Definitionen aus der Basis-Policy oder aus Modulen berücksichtigt
Für lokale SELinux-Regeln gilt eine andere Prioritätslogik als für Basis- und modulare Policy-Definitionen:
# '''Die Priorisierung erfolgt von neuen zu alten Einträgen.''' Lokale Regeln werden nicht nach dem Prinzip „am spezifischsten“ verarbeitet, sondern in umgekehrter Reihenfolge ihrer Hinzufügung: vom zuletzt hinzugefügten Eintrag bis zum frühesten
# '''Es wird die erste Übereinstimmung verwendet.''' Sobald eine passende lokale Regel gefunden wurde, wird die weitere Suche beendet
#* Das bedeutet, dass ein allgemeinerer, aber später hinzugefügter Ausdruck einen genaueren, aber früher erstellten Ausdruck überdecken kann


# '''Lokale Regeln haben Vorrang vor der Policy.''' Jeder Eintrag aus <code>file_contexts.local</code>, der zum Beispiel über <code>semanage fcontext</code> hinzugefügt wurde, wird vor den entsprechenden Definitionen aus der Basis-Policy oder aus Modulen berücksichtigt.
Daher erfordern lokale Regeln besondere Sorgfalt: Ein zu weit gefasster Ausdruck, der über semanage fcontext hinzugefügt wurde, kann unerwartet genauere Basisdefinitionen der Policy überdecken
# '''Die Priorisierung erfolgt von neuen zu alten Einträgen.''' Lokale Regeln werden nicht nach dem Prinzip „am spezifischsten“ verarbeitet, sondern in umgekehrter Reihenfolge ihrer Hinzufügung: vom zuletzt hinzugefügten Eintrag bis zum frühesten.
# '''Es wird die erste Übereinstimmung verwendet.''' Sobald eine passende lokale Regel gefunden wurde, wird die weitere Suche beendet. Das bedeutet, dass ein allgemeinerer, aber später hinzugefügter Ausdruck einen genaueren, aber früher erstellten Ausdruck überdecken kann.


Daher erfordern lokale Regeln besondere Sorgfalt: Ein zu weit gefasster Ausdruck, der über <code>semanage fcontext</code> hinzugefügt wurde, kann unerwartet genauere Basisdefinitionen der Policy überdecken.
Genau aus diesem Grund sollten lokale reguläre Ausdrücke möglichst eng gefasst und zielgerichtet sein, sodass sie nur den tatsächlich benötigten Abschnitt des Verzeichnisbaums überschreiben


Genau aus diesem Grund sollten lokale reguläre Ausdrücke möglichst eng gefasst und zielgerichtet sein, sodass sie nur den tatsächlich benötigten Abschnitt des Verzeichnisbaums überschreiben.
=== Befehl matchpathcon ===
----
matchpathcon fragt die System-Policy ab und gibt den '''Standardkontext''' aus, der mit dem angegebenen Pfad verknüpft ist
 
* Das Werkzeug ist speziell für die Analyse des erwarteten Kontexts nützlich und nicht für den aktuellen Inhalt von xattr
== Befehl <code>matchpathcon</code> ==
* Dieses Dienstprogramm '''verwaltet keine Regeln''', sondern '''zeigt lediglich das Ergebnis der Pfadprüfung''' gegen die File-Context-Datenbank an
<code>matchpathcon</code> fragt die System-Policy ab und gibt den '''Standardkontext''' aus, der mit dem angegebenen Pfad verknüpft ist. Das Werkzeug ist speziell für die Analyse des erwarteten Kontexts nützlich und nicht für den aktuellen Inhalt von <code>xattr</code>. Dieses Dienstprogramm '''verwaltet keine Regeln''', sondern '''zeigt lediglich das Ergebnis der Pfadprüfung''' gegen die File-Context-Datenbank an.
 
==== Hauptziele bei der Verwendung von <code>matchpathcon</code>: ====


; Hauptziele bei der Verwendung von matchpathcon
* verstehen, '''welches Label ein Pfad haben sollte'''
* verstehen, '''welches Label ein Pfad haben sollte'''
* das '''tatsächliche Label''' mit der '''Policy-Erwartung''' vergleichen
* das '''tatsächliche Label''' mit der '''Policy-Erwartung''' vergleichen
* im Voraus prüfen, welchen Kontext ein neuer Pfad nach dem Ausführen von <code>restorecon</code> erhält
* im Voraus prüfen, welchen Kontext ein neuer Pfad nach dem Ausführen von restorecon erhält


==== Prüfschichten entsprechend der Priorität der Regeln (von der niedrigsten zur höchsten Priorität): ====
===== Prüfschichten  =====
Prüfschichten entsprechend der Priorität der Regeln (von der niedrigsten zur höchsten Priorität)
* Basisregeln der Policy (file_contexts)
* Regeln für Home-Verzeichnisse (file_contexts.homedirs)
* Systemweite Pfad-Aliase der Distribution (file_contexts.subs_dist)
* Lokale Äquivalenzregeln (file_contexts.subs)
* lokale administrative Änderungen (file_contexts.local)


* Basisregeln der Policy (<code>file_contexts</code>)
===== Optionen =====
* Regeln für Home-Verzeichnisse (<code>file_contexts.homedirs</code>)
Zunächst verwenden wir den Befehl ohne Parameter, um das erwartete Label für die Datei /etc/resolv.conf anzusehen
* Systemweite Pfad-Aliase der Distribution (<code>file_contexts.subs_dist</code>)
* Anschließend vergleichen wir es mit dem tatsächlichen Label mittels ls
* Lokale Äquivalenzregeln (<code>file_contexts.subs</code>)
* lokale administrative Änderungen (<code>file_contexts.local</code>)


==== Optionen ====
matchpathcon /etc/resolv.conf
Kommen wir zur Praxis.
ls -Z /etc/resolv.conf
 
* Für die Problemdiagnose — insbesondere um zu prüfen, ob der auf dem Datenträger vorhandene Kontext mit dem Standardkontext aus der Policy übereinstimmt — ist auch der Parameter -V (Verify) praktisch
* Zur Veranschaulichung erzeugen wir eine Situation, in der das aktuelle Label nicht mit dem erwarteten übereinstimmt


* Zunächst verwenden wir den Befehl ohne Parameter, um das erwartete Label für die Datei <code>/etc/resolv.conf</code> anzusehen. Anschließend vergleichen wir es mit dem tatsächlichen Label mittels <code>ls</code>.
cp -a /etc/hosts /var/log/hosts


  <code>matchpathcon /etc/resolv.conf
  matchpathcon -V /var/log/hosts
  ls -Z /etc/resolv.conf</code>
  /var/log/hosts has context system_u:object_r:net_conf_t:s0, should be system_u:object_r:var_log_t:s0


* Für die Problemdiagnose — insbesondere um zu prüfen, ob der auf dem Datenträger vorhandene Kontext mit dem Standardkontext aus der Policy übereinstimmt — ist auch der Parameter <code>-V</code> (Verify) praktisch. Zur Veranschaulichung erzeugen wir eine Situation, in der das aktuelle Label nicht mit dem erwarteten übereinstimmt.
Wichtig ist zu beachten, dass das Dienstprogramm matchpathcon für manche Pfade <<none>> zurückgeben kann (zum Beispiel für Dateien in tmp)
* Das ist ein spezieller interner Wert in der Datenbank file_contexts: Er bedeutet, dass für diesen Pfad und Objekttyp '''kein erwarteter Standardkontext gefunden wurde''' oder dass dieser Pfad '''kein Label über File Context erhalten soll'''


<code>cp -a /etc/hosts /var/log/hosts
* Der Objekttyp kann mit dem Parameter -m (mode) erzwungen angegeben werden
matchpathcon -V /var/log/hosts</code>
* Das ist besonders wichtig für Pfade, die noch nicht existieren, oder wenn ein konkretes Szenario geprüft werden soll: „Was wäre, wenn dies ein Verzeichnis wäre?“ oder „Was wäre, wenn dies eine Datei wäre?“
Ausgabe:
<code># matchpathcon -V /var/log/hosts
/var/log/hosts has context system_u:object_r:net_conf_t:s0, should be system_u:object_r:var_log_t:s0</code>
Wichtig ist zu beachten, dass das Dienstprogramm <code>matchpathcon</code> für manche Pfade <code><<none>></code> zurückgeben kann (zum Beispiel für Dateien in <code>tmp</code>). Das ist ein spezieller interner Wert in der Datenbank <code>file_contexts</code>: Er bedeutet, dass für diesen Pfad und Objekttyp '''kein erwarteter Standardkontext gefunden wurde''' oder dass dieser Pfad '''kein Label über File Context erhalten soll'''.


* Der Objekttyp kann mit dem Parameter <code>-m</code> (mode) erzwungen angegeben werden. Das ist besonders wichtig für Pfade, die noch nicht existieren, oder wenn ein konkretes Szenario geprüft werden soll: „Was wäre, wenn dies ein Verzeichnis wäre?“ oder „Was wäre, wenn dies eine Datei wäre?“
matchpathcon -m dir /etc/dir
matchpathcon -m file /var/log/mylog.log


<code>matchpathcon -m dir /etc/dir
Zuordnung der Objekttypen in file_contexts und der ausgeschriebenen Werte für den Parameter -m
matchpathcon -m file /var/log/mylog.log</code>
{| class="wikitable big options"
----Zuordnung der Objekttypen in <code>file_contexts</code> und der ausgeschriebenen Werte für den Parameter <code>-m</code>:
{| class="wikitable"
!matchpathcon -m
!matchpathcon -m
!file_contexts
!file_contexts
|-
|-
|<code>file</code>
|file
|<code>--</code>
|--
|-
|-
|<code>dir</code>
|dir
|<code>-d</code>
|-d
|-
|-
|<code>lnk_file</code>
|lnk_file
|<code>-l</code>
|-l
|-
|-
|<code>sock_file</code>
|sock_file
|<code>-s</code>
|-s
|-
|-
|<code>pipe</code>
|pipe
|<code>-p</code>
|-p
|-
|-
|<code>chr_file</code>
|chr_file
|<code>-c</code>
|-c
|-
|-
|<code>blk_file</code>
|blk_file
|<code>-b</code>
|-b
|}
|}
Am häufigsten werden die Typen <code>file</code>, <code>dir</code>, <code>lnk_file</code> verwendet.
Am häufigsten werden die Typen file, dir, lnk_file verwendet
----
 
* Für Skripte und Automatisierung ist der Parameter <code>-n</code> (no path) praktisch.
 
<code>matchpathcon -n /etc/hosts</code>
Die Ausgabe enthält dann nicht den Pfad, sondern nur das Ergebnis der Prüfung des erwarteten File Context.


* Schließlich kann statt der aktuellen auch eine alternative Datei <code>file_contexts</code> verwendet werden. Das kann für Testzwecke nützlich sein; dafür dient der Parameter <code>-f</code> (file contexts).
Für Skripte und Automatisierung ist der Parameter -n (no path) praktisch
matchpathcon -n /etc/hosts


<code>matchpathcon -f /tmp/test_file_contexts /srv/myapp</code>
Die Ausgabe enthält dann nicht den Pfad, sondern nur das Ergebnis der Prüfung des erwarteten File Context
Außerdem kann mit dem Parameter <code>-P</code> (Policy) ein alternativer Pfad für einen vollständigen Policy-Satz verwendet werden.
* Schließlich kann statt der aktuellen auch eine alternative Datei file_contexts verwendet werden
* Das kann für Testzwecke nützlich sein; dafür dient der Parameter -f (file contexts)


= SCHRITT 2.3: Spezielle File Contexts für Dateisysteme und Mount-Optionen =
matchpathcon -f /tmp/test_file_contexts /srv/myapp
In den vorherigen Schritten wurde das klassische SELinux-Modell betrachtet:


* Ein Pfad wird mit einer Regel aus <code>file_contexts</code> abgeglichen.
Außerdem kann mit dem Parameter -P (Policy) ein alternativer Pfad für einen vollständigen Policy-Satz verwendet werden
* Danach erhält die Datei den erwarteten Kontext über <code>restorecon</code>, <code>setfiles</code> oder bei der Erstellung eines neuen Objekts.


Dieses Modell arbeitet auf der Ebene '''einzelner Inodes und Pfade'''.
== Spezielle File Contexts für Dateisysteme und Mount-Optionen ==
In den vorherigen Schritten wurde das klassische SELinux-Modell betrachtet
* Ein Pfad wird mit einer Regel aus file_contexts abgeglichen
* Danach erhält die Datei den erwarteten Kontext über restorecon, setfiles oder bei der Erstellung eines neuen Objekts


Beim normalen Einhängen eines Dateisystems wird — sofern es <code>xattrs</code> unterstützt — der Kontext jeder Datei aus dem <code>security.selinux</code>-Attribut der jeweiligen Datei übernommen. Wenn das Dateisystem keine <code>xattrs</code> unterstützt, erhalten die Objekte standardmäßig einen einheitlichen Kontext, der vom Typ des Dateisystems abhängt.
Dieses Modell arbeitet auf der Ebene '''einzelner Inodes und Pfade'''


In dieser Lektion wird der Mount-Mechanismus behandelt, mit dem die VFS (Virtual File System) des Linux-Kernels Kontexte „on the fly“ zuweisen kann, wobei pfadbasierte Labeling-Regeln ignoriert oder ergänzt werden.
Beim normalen Einhängen eines Dateisystems wird — sofern es xattrs unterstützt — der Kontext jeder Datei aus dem security.selinux-Attribut der jeweiligen Datei übernommen
* Wenn das Dateisystem keine xattrs unterstützt, erhalten die Objekte standardmäßig einen einheitlichen Kontext, der vom Typ des Dateisystems abhängt


== Mount Context ==
In dieser Lektion wird der Mount-Mechanismus behandelt, mit dem die VFS (Virtual File System) des Linux-Kernels Kontexte „on the fly“ zuweisen kann, wobei pfadbasierte Labeling-Regeln ignoriert oder ergänzt werden
Wenn ein Dateisystem mit speziellen SELinux-Optionen eingehängt wird, ändert der Kernel die Art der Label-Verarbeitung:


# Das System greift auf eine Datei zu.
=== Mount Context ===
# Der Kernel erkennt, dass für den Mount-Punkt eine feste Regel definiert ist.
Wenn ein Dateisystem mit speziellen SELinux-Optionen eingehängt wird, ändert der Kernel die Art der Label-Verarbeitung
# Das tatsächliche Label auf dem Datenträger wird ignoriert (oder gar nicht erst abgefragt).
# Das System greift auf eine Datei zu
# SELinux verwendet den Kontext, der im Arbeitsspeicher durch die Parameter des Befehls <code>mount</code> festgelegt wurde.
# Der Kernel erkennt, dass für den Mount-Punkt eine feste Regel definiert ist
# Das tatsächliche Label auf dem Datenträger wird ignoriert (oder gar nicht erst abgefragt)
# SELinux verwendet den Kontext, der im Arbeitsspeicher durch die Parameter des Befehls mount festgelegt wurde


----Wichtig ist zu verstehen, dass Mount-Optionen weder die Dateiattribute auf dem Datenträger noch die File-Context-Regeln physisch verändern. Stattdessen erzeugen sie '''eine temporäre virtuelle Projektion der Labels im Arbeitsspeicher'''.
Wichtig ist zu verstehen, dass Mount-Optionen weder die Dateiattribute auf dem Datenträger noch die File-Context-Regeln physisch verändern
* Stattdessen erzeugen sie '''eine temporäre virtuelle Projektion der Labels im Arbeitsspeicher'''


Diese Ersetzung gilt genau so lange, wie das Dateisystem eingehängt ist. Sobald die Ressource ausgehängt wird (mit dem Befehl <code>umount</code>), verschwinden diese Overrides: Die lokale Datenbank <code>file_contexts</code> bleibt unverändert, und auf dem Datenträger bleiben exakt dieselben <code>xattr</code>-Attribute erhalten wie vor dem Mounten.
Diese Ersetzung gilt genau so lange, wie das Dateisystem eingehängt ist
----
* Sobald die Ressource ausgehängt wird (mit dem Befehl umount), verschwinden diese Overrides: Die lokale Datenbank file_contexts bleibt unverändert, und auf dem Datenträger bleiben exakt dieselben xattr-Attribute erhalten wie vor dem Mounten


== Mount-Optionen ==
=== Mount-Optionen ===
==== context (Globale Überschreibung) ====
Die Option context= ist in zwei Hauptfällen nützlich
* das Dateisystem '''unterstützt keine''' xattr, sodass ein normales SELinux-Labeling darauf nicht möglich ist;
* dem Dateisystem '''kann im Hinblick auf bereits vorhandene Attribute nicht vertraut werden''', und beim Mounten muss vorübergehend ein einheitlicher sicherer Kontext erzwungen werden
** Ein praktisches Beispiel sind Wechselmedien (USB-Sticks)


=== context (Globale Überschreibung) ===
Wenn context= gesetzt ist, versucht SELinux nicht mehr, xattr vom Datenträger zu lesen
Die Option <code>context=</code> ist in zwei Hauptfällen nützlich:
* Auch die Datenbank file_contexts wird für diesen Pfad ignoriert
* Es ist dann nicht möglich, das Label einer einzelnen Datei innerhalb einer solchen Ressource mit chcon oder restorecon zu ändern — der Kernel gibt in diesem Fall einen Fehler zurück


* das Dateisystem '''unterstützt keine''' <code>xattr</code>, sodass ein normales SELinux-Labeling darauf nicht möglich ist;
; Befehlsbeispiele
* dem Dateisystem '''kann im Hinblick auf bereits vorhandene Attribute nicht vertraut werden''', und beim Mounten muss vorübergehend ein einheitlicher sicherer Kontext erzwungen werden. Ein praktisches Beispiel sind Wechselmedien (USB-Sticks).
Für Wechselmedien
mount -o context="system_u:object_r:removable_t:s0" /dev/sdb1 /mnt/usb


Wenn <code>context=</code> gesetzt ist, versucht SELinux nicht mehr, <code>xattr</code> vom Datenträger zu lesen. Auch die Datenbank <code>file_contexts</code> wird für diesen Pfad ignoriert. Es ist dann nicht möglich, das Label einer einzelnen Datei innerhalb einer solchen Ressource mit <code>chcon</code> oder <code>restorecon</code> zu ändern — der Kernel gibt in diesem Fall einen Fehler zurück.
Für eine Netzwerkressource, die vom Webserver gelesen werden soll
mount server:/export /srv/www -o context="system_u:object_r:httpd_sys_content_t:s0"


==== Befehlsbeispiele: ====
==== defcontext= (Standardkontext) ====
Die Option defcontext= dient einer anderen Aufgabe: Sie '''ändert den Kontext für unlabeled Dateien'''


* Für Wechselmedien
Sie wirkt nur dort, wo ein Objekt '''kein eigenes SELinux-Label auf dem Datenträger''' hat
* Wenn eine Datei bereits ein Label hat, verwendet SELinux dieses
* Wenn kein Label vorhanden ist (zum Beispiel wenn eine Datei gerade aus einem alten System ohne SELinux-Unterstützung kopiert wurde), wird ihr „on the fly“ der in defcontext= angegebene Kontext zugewiesen


  <code>mount -o context="system_u:object_r:removable_t:s0" /dev/sdb1 /mnt/usb</code>
; Befehlsbeispiel
  mount /dev/sdb2 /test -o defcontext="system_u:object_r:samba_share_t:s0"


* Für eine Netzwerkressource, die vom Webserver gelesen werden soll:
==== rootcontext= (Kontext des Mount-Punkts) ====
Die Option rootcontext= erlaubt es, den Kontext des '''Root-Inodes''' eines Dateisystems explizit festzulegen, '''bevor es im Userspace sichtbar wird'''
* Sie bestimmt den Kontext ausschließlich für das '''Wurzelverzeichnis''' des eingehängten Dateisystems, ohne dessen Inhalt zu beeinflussen


  <code>mount server:/export /srv/www -o context="system_u:object_r:httpd_sys_content_t:s0"</code>
Das ist nützlich, wenn das korrekte Label für das Verzeichnis selbst (zum Beispiel /mnt/backup) gesetzt werden soll, damit Dienste es betreten können, während die individuellen Labels aller enthaltenen Dateien auf dem Datenträger erhalten bleiben
----
  mount -t tmpfs none /srv/chroot -o rootcontext="system_u:object_r:tmp_t:s0"


=== defcontext= (Standardkontext) ===
==== fscontext= (Kontext des Superblocks) ====
Die Option <code>defcontext=</code> dient einer anderen Aufgabe: Sie '''ändert den Kontext für unlabeled Dateien'''. Sie wirkt nur dort, wo ein Objekt '''kein eigenes SELinux-Label auf dem Datenträger''' hat:
Weist der abstrakten Dateisysteminstanz selbst einen Kontext als Objekt zu, nicht den darin enthaltenen Dateien


* Wenn eine Datei bereits ein Label hat, verwendet SELinux dieses.
Dies ist eine Low-Level-Option
* Wenn kein Label vorhanden ist (zum Beispiel wenn eine Datei gerade aus einem alten System ohne SELinux-Unterstützung kopiert wurde), wird ihr „on the fly“ der in <code>defcontext=</code> angegebene Kontext zugewiesen.
* Sie wird von SELinux selbst verwendet, um zu bestimmen, ob ein bestimmter Prozess (zum Beispiel ein Mount-Daemon) das Recht hat, Dateisysteme dieses Typs einzuhängen
* In der täglichen Administration wird sie manuell nur äußerst selten verwendet


==== Befehlsbeispiel: ====
=== Aufgabe ===
  <code>mount /dev/sdb2 /test -o defcontext="system_u:object_r:samba_share_t:s0"</code>
Wir erstellen zwei Mount-Punkte
----
  sudo mkdir -p /mnt/lab_context
sudo mkdir -p /mnt/lab_rootcontext


=== rootcontext= (Kontext des Mount-Punkts) ===
Wir mounten tmpfs mit einem einheitlichen Kontext
Die Option <code>rootcontext=</code> erlaubt es, den Kontext des '''Root-Inodes''' eines Dateisystems explizit festzulegen, '''bevor es im Userspace sichtbar wird'''. Sie bestimmt den Kontext ausschließlich für das '''Wurzelverzeichnis''' des eingehängten Dateisystems, ohne dessen Inhalt zu beeinflussen.
sudo mount -t tmpfs none /mnt/lab_context -o context="system_u:object_r:httpd_sys_content_t:s0"
ls -Zd /mnt/lab_context


* Das ist nützlich, wenn das korrekte Label für das Verzeichnis selbst (zum Beispiel <code>/mnt/backup</code>) gesetzt werden soll, damit Dienste es betreten können, während die individuellen Labels aller enthaltenen Dateien auf dem Datenträger erhalten bleiben.
Nun erstellen wir einige Objekte darin
 
  touch /mnt/lab_context/file1
<code>mount -t tmpfs none /srv/chroot -o rootcontext="system_u:object_r:tmp_t:s0"</code>
----
 
=== fscontext= (Kontext des Superblocks) ===
Weist der abstrakten Dateisysteminstanz selbst einen Kontext als Objekt zu, nicht den darin enthaltenen Dateien.
 
* Dies ist eine Low-Level-Option. Sie wird von SELinux selbst verwendet, um zu bestimmen, ob ein bestimmter Prozess (zum Beispiel ein Mount-Daemon) das Recht hat, Dateisysteme dieses Typs einzuhängen. In der täglichen Administration wird sie manuell nur äußerst selten verwendet.
 
----
 
== Praktische Aufgabe ==
Wir erstellen zwei Mount-Punkte:
<code>sudo mkdir -p /mnt/lab_context
sudo mkdir -p /mnt/lab_rootcontext</code>
 
* Wir mounten <code>tmpfs</code> mit einem einheitlichen Kontext:
 
<code>sudo mount -t tmpfs none /mnt/lab_context -o context="system_u:object_r:httpd_sys_content_t:s0"
ls -Zd /mnt/lab_context</code>
 
* Nun erstellen wir einige Objekte darin:
 
  <code>touch /mnt/lab_context/file1
  mkdir /mnt/lab_context/dir1
  mkdir /mnt/lab_context/dir1
  ls -lZ1 /mnt/lab_context</code>
  ls -lZ1 /mnt/lab_context
 
* Jetzt versuchen wir, den Kontext manuell zu ändern:
 
<code>chcon -t tmp_t /mnt/lab_context/file1</code>
'''Der Kernel gibt einen Fehler zurück, da bei Verwendung des Mount-Parameters''' <code>context=</code> '''eine Kontextänderung nicht möglich ist.'''


* Nun versuchen wir, ein anderes Dateisystem mit dem Parameter <code>defcontext=</code> einzuhängen:
Jetzt versuchen wir, den Kontext manuell zu ändern
chcon -t tmp_t /mnt/lab_context/file1


<code>mount -t tmpfs none /mnt/lab_rootcontext -o rootcontext="system_u:object_r:samba_share_t:s0"
'''Der Kernel gibt einen Fehler zurück, da bei Verwendung des Mount-Parameters''' context= '''eine Kontextänderung nicht möglich ist.'''
ls -Zd /mnt/lab_rootcontext</code>


* Wir erstellen Objekte:
Nun versuchen wir, ein anderes Dateisystem mit dem Parameter defcontext= einzuhängen
mount -t tmpfs none /mnt/lab_rootcontext -o rootcontext="system_u:object_r:samba_share_t:s0"
ls -Zd /mnt/lab_rootcontext


  <code>touch /mnt/lab_rootcontext/file1
Wir erstellen Objekte
  touch /mnt/lab_rootcontext/file1
  mkdir /mnt/lab_rootcontext/dir1
  mkdir /mnt/lab_rootcontext/dir1
  touch /mnt/lab_rootcontext/file2
  touch /mnt/lab_rootcontext/file2
  ls -lZ1 /mnt/lab_rootcontext</code>
  ls -lZ1 /mnt/lab_rootcontext
Wie man sehen kann, wurde der Kontext der Dateien vom <code>root</code>-Verzeichnis geerbt.
 
Wie man sehen kann, wurde der Kontext der Dateien vom root-Verzeichnis geerbt


* Nun versuchen wir, den Kontext zu ändern:
Nun versuchen wir, den Kontext zu ändern
chcon -R -t tmp_t /mnt/lab_rootcontext/*
ls -lZ1 /mnt/lab_rootcontext/


<code>chcon -R -t tmp_t /mnt/lab_rootcontext/*
'''Und der Vorgang wird erfolgreich ausgeführt, da''' rootcontext '''nur den Kontext des Wurzelverzeichnisses des eingehängten Dateisystems ändert.'''
ls -lZ1 /mnt/lab_rootcontext/</code>
'''Und der Vorgang wird erfolgreich ausgeführt, da''' <code>rootcontext</code> '''nur den Kontext des Wurzelverzeichnisses des eingehängten Dateisystems ändert.'''


Das kann nützlich sein, wenn ein temporärer Speicher auf <code>tmpfs</code> benötigt wird, dessen Wurzel jedoch sofort den richtigen Typ haben soll, damit neue Dateien den gewünschten Kontext erben. Gleichzeitig bleibt die Möglichkeit erhalten, andere Dateien mit bereits vorhandenem, vom Wurzelverzeichnis abweichendem Kontext zu schreiben.
Das kann nützlich sein, wenn ein temporärer Speicher auf tmpfs benötigt wird, dessen Wurzel jedoch sofort den richtigen Typ haben soll, damit neue Dateien den gewünschten Kontext erben
* Gleichzeitig bleibt die Möglichkeit erhalten, andere Dateien mit bereits vorhandenem, vom Wurzelverzeichnis abweichendem Kontext zu schreiben


= SCHRITT 2.4. Verwaltung von Kontexten mit <code>semanage</code> =
== Verwaltung von Kontexten mit semanage ==
Nun ist es endlich an der Zeit, die Verwaltung der File-Context-Datenbank zu betrachten.
Nun ist es endlich an der Zeit, die Verwaltung der File-Context-Datenbank zu betrachten


Wie bereits zuvor besprochen, überschreibt <code>chcon</code> direkt die erweiterten Attribute (<code>xattr</code>) auf dem Datenträger, teilt der SELinux-Policy-Datenbank (<code>file_contexts</code>) jedoch absolut nichts darüber mit.
Wie bereits zuvor besprochen, überschreibt chcon direkt die erweiterten Attribute (xattr) auf dem Datenträger, teilt der SELinux-Policy-Datenbank (file_contexts) jedoch absolut nichts darüber mit


Änderungen, die mit <code>chcon</code> vorgenommen werden, sind im Maßstab des Systemlebenszyklus nur temporär. Sie werden bei jedem der folgenden Ereignisse unwiderruflich zerstört (durch Referenzwerte aus der Datenbank überschrieben):
Änderungen, die mit chcon vorgenommen werden, sind im Maßstab des Systemlebenszyklus nur temporär


* der Administrator startet das Dienstprogramm <code>restorecon</code> manuell für dieses Verzeichnis;
Sie werden bei jedem der folgenden Ereignisse unwiderruflich zerstört (durch Referenzwerte aus der Datenbank überschrieben)
* der Administrator startet das Dienstprogramm restorecon manuell für dieses Verzeichnis;
* es erfolgt ein Systemupdate eines Pakets (zum Beispiel des Webservers), dessen Installer eine Prüfung der Kontexte auslöst;
* es erfolgt ein Systemupdate eines Pakets (zum Beispiel des Webservers), dessen Installer eine Prüfung der Kontexte auslöst;
* beim Booten wird ein vollständiges Relabeling des Dateisystems initiiert (durch Erzeugen der Datei <code>/.autorelabel</code>).
* beim Booten wird ein vollständiges Relabeling des Dateisystems initiiert (durch Erzeugen der Datei /.autorelabel)


== <code>semanage fcontext</code> ==
=== semanage fcontext ===
Damit ein Kontext alle Updates und Relabeling-Vorgänge übersteht, muss man dem SELinux-System selbst beibringen, dass ein nicht standardmäßiger Pfad nun ein bestimmtes Label haben soll.
Damit ein Kontext alle Updates und Relabeling-Vorgänge übersteht, muss man dem SELinux-System selbst beibringen, dass ein nicht standardmäßiger Pfad nun ein bestimmtes Label haben soll


Dafür wird das Werkzeug <code>semanage</code> (SELinux Policy Management Tool) verwendet. Es ist das allgemeine Werkzeug zur lokalen Verwaltung von Elementen der SELinux-Policy, darunter: login mappings, SELinux users, ports, interfaces, modules, booleans, permissive types und file contexts. Für den aktuellen Schritt ist insbesondere der Bereich <code>fcontext</code> relevant.
Dafür wird das Werkzeug semanage (SELinux Policy Management Tool) verwendet
* Es ist das allgemeine Werkzeug zur lokalen Verwaltung von Elementen der SELinux-Policy, darunter: login mappings, SELinux users, ports, interfaces, modules, booleans, permissive types und file contexts
* Für den aktuellen Schritt ist insbesondere der Bereich fcontext relevant


=== Verwendung ===
==== Verwendung ====
Zur Demonstration versuchen wir, ein nicht standardmäßiges Verzeichnis mit hochsensiblen Daten zu schützen.
Zur Demonstration versuchen wir, ein nicht standardmäßiges Verzeichnis mit hochsensiblen Daten zu schützen


Stellen wir uns folgende Situation vor: Entwickler haben ein internes Authentifizierungssystem ausgerollt, das Sicherungskopien der Passwort-Hashes von Benutzern in einem nicht standardmäßigen Verzeichnis speichert — <code>/opt/app_auth/vault/</code>
Stellen wir uns folgende Situation vor: Entwickler haben ein internes Authentifizierungssystem ausgerollt, das Sicherungskopien der Passwort-Hashes von Benutzern in einem nicht standardmäßigen Verzeichnis speichert — /opt/app_auth/vault/
  <code>mkdir -p /opt/app_auth/vault
  mkdir -p /opt/app_auth/vault
  ls -Zd /opt/app_auth/vault/</code>
  ls -Zd /opt/app_auth/vault/
Wenn wir uns an die Analyse der Datei <code>file_contexts</code> aus den vorherigen Schritten erinnern, erhalten das Verzeichnis <code>/opt/</code> und sein gesamter Inhalt standardmäßig den Kontext <code>usr_t</code>. Das ist ein öffentlicher Kontext: '''Die meisten laufenden Dienste und Benutzer dürfen Dateien mit diesem Label lesen.''' '''Passwörter dort zu speichern ist unzulässig.'''


* Daher muss für dieses Verzeichnis eine grundlegende Regel erstellt werden. Verwenden wir dazu die Parameter <code>-a</code> (add) und <code>-t</code> (Feld <code>type</code>).
Wenn wir uns an die Analyse der Datei file_contexts aus den vorherigen Schritten erinnern, erhalten das Verzeichnis /opt/ und sein gesamter Inhalt standardmäßig den Kontext usr_t


<code>semanage fcontext -a -t shadow_t "/opt/app_auth/vault(/.*)?"</code>
; Das ist ein öffentlicher Kontext
<code>"/opt/app_auth/vault(/.*)?"</code> — ein regulärer Ausdruck, der das Verzeichnis selbst und absolut alle darin enthaltenen Dateien umfasst.
* '''Die meisten laufenden Dienste und Benutzer dürfen Dateien mit diesem Label lesen.'''
* '''Passwörter dort zu speichern ist unzulässig.'''
* Daher muss für dieses Verzeichnis eine grundlegende Regel erstellt werden


Nun prüfen wir den Kontext des Verzeichnisses:
Verwenden wir dazu die Parameter -a (add) und -t (Feld type)
<code>ls -Zd /opt/app_auth/vault/</code>
  semanage fcontext -a -t shadow_t "/opt/app_auth/vault(/.*)?"
...und sehen, dass sich nichts geändert hat. Das liegt daran, dass wir zwar einen Eintrag in die Datenbank hinzugefügt haben, das bloße Hinzufügen eines Eintrags jedoch kein Relabeling auslöst. Um die Änderungen anzuwenden, wird das uns bereits bekannte Werkzeug <code>restorecon</code> verwendet:
  <code>restorecon -Rv /opt/app_auth/vault/
ls -Zd /opt/app_auth/vault/</code>


* Ergebnis:
"/opt/app_auth/vault(/.*)?" — ein regulärer Ausdruck, der das Verzeichnis selbst und absolut alle darin enthaltenen Dateien umfasst


  <code># ls -Zd /opt/app_auth/vault/
Nun prüfen wir den Kontext des Verzeichnisses
  unconfined_u:object_r:shadow_t:s0 /opt/app_auth/vault/</code>
  ls -Zd /opt/app_auth/vault/
...und sehen, dass sich nichts geändert hat
* Das liegt daran, dass wir zwar einen Eintrag in die Datenbank hinzugefügt haben, das bloße Hinzufügen eines Eintrags jedoch kein Relabeling auslöst
* Um die Änderungen anzuwenden, wird das uns bereits bekannte Werkzeug restorecon verwendet
  restorecon -Rv /opt/app_auth/vault/
ls -Zd /opt/app_auth/vault/


* Prüfen wir, ob der Eintrag in der File-Context-Datenbank vorhanden ist:
Ergebnis
# ls -Zd /opt/app_auth/vault/
unconfined_u:object_r:shadow_t:s0 /opt/app_auth/vault/
 
Prüfen wir, ob der Eintrag in der File-Context-Datenbank vorhanden ist
cat /etc/selinux/default/contexts/files/file_contexts.local


<code>cat /etc/selinux/default/contexts/files/file_contexts.local</code>
Ausgabe:
<code># cat /etc/selinux/default/contexts/files/file_contexts.local
  # This file is auto-generated by libsemanage
  # This file is auto-generated by libsemanage
  # Do not edit directly.
  # Do not edit directly
/opt/app_auth/vault(/.*)?    system_u:object_r:shadow_t:s0</code>
'''Jetzt sind die vertraulichen Daten zuverlässig geschützt!'''


=== Optionen ===
/opt/app_auth/vault(/.*)?    system_u:object_r:shadow_t:s0
Das Werkzeug <code>semanage</code> verfügt über verschiedene nützliche Optionen; konzentrieren wir uns auf die wichtigsten:


* Welche nicht standardmäßigen Regeln manuell hinzugefügt wurden, kann mit der Option <code>-l</code> (list) zusammen mit dem Modifikator <code>-C</code> (Custom) angezeigt werden:
'''Jetzt sind die vertraulichen Daten zuverlässig geschützt!'''


<code>semanage fcontext -lC</code>
==== Optionen ====
Das Werkzeug semanage verfügt über verschiedene nützliche Optionen; konzentrieren wir uns auf die wichtigsten


* Den Kontexttyp für den bereits in der lokalen Datenbank registrierten Pfad <code>/srv/myweb(/.*)?</code> kann man mit der Option <code>-m</code> (modify) aktualisieren:
Welche nicht standardmäßigen Regeln manuell hinzugefügt wurden, kann mit der Option -l (list) zusammen mit dem Modifikator -C (Custom) angezeigt werden
semanage fcontext -lC


  <code>semanage fcontext -m -t httpd_sys_rw_content_t "/srv/myweb(/.*)?"</code>
Den Kontexttyp für den bereits in der lokalen Datenbank registrierten Pfad /srv/myweb(/.*)? kann man mit der Option -m (modify) aktualisieren
Wichtig ist, dass der reguläre Ausdruck genau mit dem Eintrag in der Datenbank übereinstimmt, dessen Kontext wir ändern wollen.
  semanage fcontext -m -t httpd_sys_rw_content_t "/srv/myweb(/.*)?"


* Wenn ein Dienst außer Betrieb genommen wurde und das nicht standardmäßige Verzeichnis nicht mehr benötigt wird, kann die Regel mit der Option <code>-d</code> gelöscht werden:
Wichtig ist, dass der reguläre Ausdruck genau mit dem Eintrag in der Datenbank übereinstimmt, dessen Kontext wir ändern wollen


  <code>semanage fcontext -d "/opt/app_auth/vault(/.*)?"</code>
Wenn ein Dienst außer Betrieb genommen wurde und das nicht standardmäßige Verzeichnis nicht mehr benötigt wird, kann die Regel mit der Option -d gelöscht werden
----
  semanage fcontext -d "/opt/app_auth/vault(/.*)?"
 
== Äquivalente Pfade (Equivalence Rules) ==
Bei der Arbeit mit mehreren Verzeichnissen entsteht häufig die Situation, dass:


=== Äquivalente Pfade (Equivalence Rules) ===
Bei der Arbeit mit mehreren Verzeichnissen entsteht häufig die Situation, dass
* bereits eine korrekt gekennzeichnete Struktur existiert
* bereits eine korrekt gekennzeichnete Struktur existiert
* eine Kopie dieser Struktur an einem anderen Ort erstellt werden muss
* eine Kopie dieser Struktur an einem anderen Ort erstellt werden muss


=== Beispielaufgabe ===
==== Beispielaufgabe ====
Es gibt den Standardpfad des Webservers <code>/var/www</code>, wir haben jedoch beschlossen, die Dateien unserer neuen Website in einem nicht standardmäßigen Verzeichnis abzulegen, zum Beispiel auf einer separaten Festplatte, die unter <code>/srv/myweb</code> eingehängt ist.
Es gibt den Standardpfad des Webservers /var/www, wir haben jedoch beschlossen, die Dateien unserer neuen Website in einem nicht standardmäßigen Verzeichnis abzulegen, zum Beispiel auf einer separaten Festplatte, die unter /srv/myweb eingehängt ist


* Wir erstellen zur Veranschaulichung mehrere Ordner im ursprünglichen Verzeichnis <code>/var/www</code> und bereiten das neue Verzeichnis <code>/srv/myweb</code> vor.
Wir erstellen zur Veranschaulichung mehrere Ordner im ursprünglichen Verzeichnis /var/www und bereiten das neue Verzeichnis /srv/myweb vor
mkdir -p /var/www/sessions && mkdir -p /var/www/cgi-binrestorecon -v -R /var/wwwls -Z1 /var/wwwmkdir -p /srv/mywebcp -r /var/www/* /srv/myweb/ls -Z1 /srv/myweb


<code>mkdir -p /var/www/sessions && mkdir -p /var/www/cgi-binrestorecon -v -R /var/wwwls -Z1 /var/wwwmkdir -p /srv/mywebcp -r /var/www/* /srv/myweb/ls -Z1 /srv/myweb</code>
Standardmäßig sind für das Verzeichnis /var/www und alle seine Unterverzeichnisse (html, cgi-bin usw.) im System bereits Dutzende komplexer regulärer Ausdrücke definiert, die die korrekten Kontexte zuweisen (zum Beispiel httpd_cache_t für /var/www/uploads(/.*)?)
Standardmäßig sind für das Verzeichnis <code>/var/www</code> und alle seine Unterverzeichnisse (html, cgi-bin usw.) im System bereits Dutzende komplexer regulärer Ausdrücke definiert, die die korrekten Kontexte zuweisen (zum Beispiel <code>httpd_cache_t</code> für <code>/var/www/uploads(/.*)?</code>). Alle regulären Ausdrücke aus <code>/var/www</code> manuell für das neue Verzeichnis <code>/srv/myweb</code> umzuschreiben, wäre aufwendig, unhandlich und fehleranfällig.
* Alle regulären Ausdrücke aus /var/www manuell für das neue Verzeichnis /srv/myweb umzuschreiben, wäre aufwendig, unhandlich und fehleranfällig


* Für die Lösung solcher Aufgaben werden Äquivalenzregeln verwendet (Parameter <code>-e</code> des Befehls <code>semanage fcontext</code>):
Für die Lösung solcher Aufgaben werden Äquivalenzregeln verwendet (Parameter -e des Befehls semanage fcontext)
semanage fcontext -a -e /var/www /srv/myweb


<code>semanage fcontext -a -e /var/www /srv/myweb</code>
Änderungen anwenden


* Änderungen anwenden
restorecon -v -R /srv/myweb


  <code>restorecon -v -R /srv/myweb</code>
Sehen wir uns an, wie das in der Datenbank aussieht
  # semanage fcontext -lCSELinux fcontext                                   type               Context​/opt/app_auth/vault(/.*)?                          all files          system_u:object_r:shadow_t:s0​SELinux Local fcontext Equivalence​/srv/myweb = /var/www


* Sehen wir uns an, wie das in der Datenbank aussieht
Eine Äquivalenzregel funktioniert wie ein transparenter Alias: Wenn SELinux irgendeine Datei innerhalb von /srv/myweb/ prüft, ersetzt es in deren Pfad virtuell /srv/myweb durch /var/www und sucht erst danach Übereinstimmungen in seiner umfangreichen Datenbank regulärer Ausdrücke


  <code># semanage fcontext -lCSELinux fcontext                                   type               Context​/opt/app_auth/vault(/.*)?                          all files          system_u:object_r:shadow_t:s0​SELinux Local fcontext Equivalence​/srv/myweb = /var/www</code>
Wenn es erforderlich ist, die Äquivalenzregel zu entfernen, geschieht dies mit dem bereits bekannten Parameter -d; man muss ihn lediglich anstelle des Parameters -a aus dem ursprünglichen Befehl verwenden
Eine Äquivalenzregel funktioniert wie ein transparenter Alias: Wenn SELinux irgendeine Datei innerhalb von <code>/srv/myweb/</code> prüft, ersetzt es in deren Pfad virtuell <code>/srv/myweb</code> durch <code>/var/www</code> und sucht erst danach Übereinstimmungen in seiner umfangreichen Datenbank regulärer Ausdrücke.
  semanage fcontext -d -e /var/www /srv/mywebsemanage fcontext -lC


* Wenn es erforderlich ist, die Äquivalenzregel zu entfernen, geschieht dies mit dem bereits bekannten Parameter <code>-d</code>; man muss ihn lediglich anstelle des Parameters <code>-a</code> aus dem ursprünglichen Befehl verwenden:
=== Export und Import lokaler Policies ===
Das Dienstprogramm semanage kann Policies mit den Befehlen semanage export und semanage import in eine Datei exportieren beziehungsweise aus einer Datei importieren
* In der Praxis wird das zum Beispiel verwendet, wenn ein Administrator plant, Policies von einem Testserver auf die Produktionsumgebung zu übertragen


  <code>semanage fcontext -d -e /var/www /srv/mywebsemanage fcontext -lC</code>
==== Export ====
Verwendungsbeispiel
  semanage export -f /tmp/selinux_local_rules.txt


== Export und Import lokaler Policies ==
Prüfen wir, was sich darin befindet
Das Dienstprogramm <code>semanage</code> kann Policies mit den Befehlen <code>semanage export</code> und <code>semanage import</code> in eine Datei exportieren beziehungsweise aus einer Datei importieren. In der Praxis wird das zum Beispiel verwendet, wenn ein Administrator plant, Policies von einem Testserver auf die Produktionsumgebung zu übertragen.
cat /tmp/selinux_local_rules.txt
boolean -Dlogin -Dinterface -D...fcontext -a -f a -t shadow_t -r 's0' '/opt/app_auth/vault(/.*)?'module -d acpimodule -d aisexecmodule -d amtu..


=== Export ===
Wie man sehen kann, ist die Datei logisch in drei Teile gegliedert


* Verwendungsbeispiel:
* '''Bereinigungsblock''' (Einträge mit dem Schlüssel -D) – beim Import der Datei auf einem neuen Server (über semanage import) soll das Policy-System zu einer ''exakten Kopie'' des Quellservers werden
* Daher müssen alle lokalen Einstellungen gelöscht werden
* Der Schlüssel -D wird als Delete interpretiert
* '''Lokale Regeln''' (im Beispiel die einzige Regel fcontext)
* '''Block deaktivierter Policy-Module''' (Einträge mit dem Schlüssel -d) – das Policy-Set default policy in Debian ist gehärtet (hardened) und deaktiviert ungenutzte Module
* In RHEL macht die Policy targeted genau das Gegenteil: Dort sind standardmäßig von Anfang an alle Module aktiviert, unabhängig davon, ob die entsprechende Software installiert ist oder nicht


  <code>semanage export -f /tmp/selinux_local_rules.txt</code>
==== Import ====
Für den Import wird der Befehl semanage import verwendet; seine Syntax sieht identisch zum Export aus
  semanage import -f /tmp/selinux_local_rules.txt


* Prüfen wir, was sich darin befindet:
Wenn uns die importierten Policies zusagen und alles Erforderliche mit matchpathcon -V geprüft wurde, wenden wir die Änderungen an
restorecon -Rv /


<code># cat /tmp/selinux_local_rules.txtboolean -Dlogin -Dinterface -D...fcontext -a -f a -t shadow_t -r 's0' '/opt/app_auth/vault(/.*)?'module -d acpimodule -d aisexecmodule -d amtu...</code>
== Wiederherstellung korrekter Labels ==
Wie man sehen kann, ist die Datei logisch in drei Teile gegliedert:
; Relabeling mit restorecon


* '''Bereinigungsblock''' (Einträge mit dem Schlüssel <code>-D</code>) – beim Import der Datei auf einem neuen Server (über <code>semanage import</code>) soll das Policy-System zu einer ''exakten Kopie'' des Quellservers werden. Daher müssen alle lokalen Einstellungen gelöscht werden. Der Schlüssel <code>-D</code> wird als <code>Delete</code> interpretiert.
Der Arbeitsablauf von restorecon lässt sich vereinfacht wie folgt beschreiben
* '''Lokale Regeln''' (im Beispiel die einzige Regel <code>fcontext</code>)
# Das Werkzeug übernimmt einen Zielpfad und liest die aktive SELinux-Policy bzw.&nbsp;die zugehörige File-Context-Datenbasis
* '''Block deaktivierter Policy-Module''' (Einträge mit dem Schlüssel <code>-d</code>) – das Policy-Set <code>default policy</code> in Debian ist gehärtet (<code>hardened</code>) und deaktiviert ungenutzte Module. In RHEL macht die Policy <code>targeted</code> genau das Gegenteil: Dort sind standardmäßig von Anfang an alle Module aktiviert, unabhängig davon, ob die entsprechende Software installiert ist oder nicht.
# Der Zielpfad wird gegen die regulären Ausdrücke aus der Policy-Datenbasis abgeglichen
# Das Werkzeug liest den tatsächlich gesetzten erweiterten Dateiattributwert (xattr) des Objekts direkt aus dem Dateisystem
# Anschließend erfolgt ein Vergleich zwischen dem laut Policy erwarteten Kontext und dem tatsächlich gesetzten Label (Attribut) des Objekts
# Falls die Prüfung rekursiv für ein Verzeichnis ausgeführt wurde, berechnet restorecon einen Hash über die dabei verwendeten regulären Ausdrücke und speichert ihn im versteckten Attribut des Verzeichnisses security.sehash
#* Beim nächsten Lauf beginnt Schritt 2 dann mit dem Vergleich dieses Hashes, um Zeit zu sparen


=== Import ===
==== Verwendung ====
Für den Import wird der Befehl <code>semanage import</code> verwendet; seine Syntax sieht identisch zum Export aus:
In der Praxis werden drei Betriebsarten verwendet
<code>semanage import -f /tmp/selinux_local_rules.txt</code>


* Wenn uns die importierten Policies zusagen und alles Erforderliche mit <code>matchpathcon -V</code> geprüft wurde, wenden wir die Änderungen an:
; Passive Prüfung ohne Änderungen
restorecon -nv /var/www/html/index.html


<code>restorecon -Rv /</code>
Die Option -n verhindert das Schreiben neuer Labels und versetzt das Werkzeug in den Prüfmodus
* Der Parameter -v zeigt Objekte an, deren Labels vom erwarteten Zustand abweichen


= SCHRITT 2.6. Wiederherstellung korrekter Labels (Relabeling) mit <code>restorecon</code> =
; Korrektur eines einzelnen Objekts
Hier wird das Werkzeug <code>restorecon</code> näher betrachtet.
restorecon -v /var/www/html/index.html


Der Arbeitsablauf von <code>restorecon</code> lässt sich vereinfacht wie folgt beschreiben:
Korrigiert den Kontext der angegebenen Datei
* Praktisch werden dabei genau die Änderungen angewendet, die im vorherigen Beispiel lediglich angezeigt wurden


# Das Werkzeug übernimmt einen Zielpfad und liest die aktive SELinux-Policy bzw. die zugehörige File-Context-Datenbasis.
; Massenhafte rekursive Korrektur eines Verzeichnisbaums
# Der Zielpfad wird gegen die regulären Ausdrücke aus der Policy-Datenbasis abgeglichen.
restorecon -Rv /var
# Das Werkzeug liest den tatsächlich gesetzten erweiterten Dateiattributwert (xattr) des Objekts direkt aus dem Dateisystem.
# Anschließend erfolgt ein Vergleich zwischen dem laut Policy erwarteten Kontext und dem tatsächlich gesetzten Label (Attribut) des Objekts.
# Falls die Prüfung rekursiv für ein Verzeichnis ausgeführt wurde, berechnet <code>restorecon</code> einen Hash über die dabei verwendeten regulären Ausdrücke und speichert ihn im versteckten Attribut des Verzeichnisses <code>security.sehash</code>. Beim nächsten Lauf beginnt Schritt 2 dann mit dem Vergleich dieses Hashes, um Zeit zu sparen.


=== Verwendung ===
Die Optionen -R und -r aktivieren den rekursiven Verzeichnisdurchlauf
In der Praxis werden drei Betriebsarten verwendet.
* Genau dieser Modus wird typischerweise nach dem Hinzufügen neuer Regeln mit semanage fcontext oder nach einer beschädigten Teil-Relabeling-Situation verwendet


* '''Passive Prüfung ohne Änderungen'''
=== customizable types ===
In SELinux existiert ein Ausnahme-Mechanismus für Relabeling mit der Bezeichnung customizable types


<code>restorecon -nv /var/www/html/index.html</code>
Dabei handelt es sich um eine vordefinierte Liste von Kontexten (Typen), die vom System als manuell administrierbar betrachtet werden
Die Option <code>-n</code> verhindert das Schreiben neuer Labels und versetzt das Werkzeug in den Prüfmodus. Der Parameter <code>-v</code> zeigt Objekte an, deren Labels vom erwarteten Zustand abweichen.
* Entsprechend werden solche Dateien bei der Prüfung und beim Relabeling durch SELinux-Werkzeuge und -Mechanismen (einschließlich restorecon, .autorelabel, setfiles, fixfiles) ignoriert


* '''Korrektur eines einzelnen Objekts'''
Die Liste der customizable types wird aus folgender Datei gelesen
/etc/selinux/{SELINUXPOLICY}/contexts/customizable_types


  <code>restorecon -v /var/www/html/index.html</code>
  Obwohl der Mechanismus der customizable types in modernen Distributionen weiterhin existiert und funktioniert, gilt er in der Administratoren-Community heute als '''veraltender Ansatz'''
Korrigiert den Kontext der angegebenen Datei. Praktisch werden dabei genau die Änderungen angewendet, die im vorherigen Beispiel lediglich angezeigt wurden.
* Der Grund ist, dass die Datei lediglich Informationen darüber enthält, welche Typen ignoriert werden, nicht jedoch, welchen konkreten Dateien diese Typen zugewiesen wurden
* In einer Störungssituation kann diese Information unwiederbringlich verloren gehen
* Die File-Context-Datenbank enthält dagegen alle erforderlichen Informationen, um den gewünschten Label-Zustand im Dateisystem reproduzierbar wiederherzustellen


* '''Massenhafte rekursive Korrektur eines Verzeichnisbaums'''
Um Dateien mit customizable types dennoch zwangsweise auf den vollständig erwarteten Kontext zurückzusetzen, muss restorecon mit dem Parameter -F (Force) ausgeführt werden
* In diesem Fall werden '''alle Felder des Kontexts wiederhergestellt'''
restorecon -F -v /srv/custom_app


<code>restorecon -Rv /var</code>
=== Beschleunigung durch Digest-Prüfung ===
Die Optionen <code>-R</code> und <code>-r</code> aktivieren den rekursiven Verzeichnisdurchlauf. Genau dieser Modus wird typischerweise nach dem Hinzufügen neuer Regeln mit <code>semanage fcontext</code> oder nach einer beschädigten Teil-Relabeling-Situation verwendet.
; Das Werkzeug restorecon_xattr
Beim rekursiven Relabeling mit restorecon -D durchläuft das Werkzeug den Verzeichnisbaum nicht nur und korrigiert Kontexte, sondern '''schreibt zusätzlich einen internen Digest in das xattr des Verzeichnisses'''.  


== customizable types ==
; Digest wird im erweiterten Attribut ''security.sehash'' gespeichert
In SELinux existiert ein Ausnahme-Mechanismus für Relabeling mit der Bezeichnung <code>customizable types</code>.


Dabei handelt es sich um eine vordefinierte Liste von Kontexten (Typen), die vom System als manuell administrierbar betrachtet werden. Entsprechend werden solche Dateien bei der Prüfung und beim Relabeling durch SELinux-Werkzeuge und -Mechanismen (einschließlich <code>restorecon</code>, <code>.autorelabel</code>, <code>setfiles</code>, <code>fixfiles</code>) ignoriert.
Die Aufgabe dieses Digests besteht darin festzuhalten, dass dieses Verzeichnis bereits gegen einen bestimmten Satz von file_contexts-Dateien geprüft wurde, die für die Zuordnung von Pfaden zu erwarteten Kontexten verwendet werden
* Beim nächsten Lauf von restorecon -D wird dieser Hash zur Prüfung herangezogen und bei Bedarf aktualisiert, falls er veraltet ist
In modernen RHEL-Versionen wird zur Berechnung dieses Werts '''der kryptographische Algorithmus SHA-256''' verwendet (in älteren Systemen kam SHA-1 zum Einsatz).
'''Red Hat/Fedora''' verwenden seit RHEL 9 bzw.&nbsp;Fedora 34+ beim Paket-Build einen eigenen Patch für den Quellcode
* In den Paketquellen findet sich dazu direkt eine Datei mit dem Namen 0001-Use-SHA-2-instead-of-SHA-1.patch


Die Liste der <code>customizable types</code> wird aus folgender Datei gelesen:
Debian verwendet weiterhin SHA-1
<code>/etc/selinux/{SELINUXPOLICY}/contexts/customizable_types</code>
* Das ist in diesem Kontext jedoch unkritisch, da der Hash im Verzeichnis-xattr nicht für Sicherheitsfunktionen oder Verschlüsselung verwendet wird
----Obwohl der Mechanismus der <code>customizable types</code> in modernen Distributionen weiterhin existiert und funktioniert, gilt er in der Administratoren-Community heute als '''veraltender Ansatz'''. Der Grund ist, dass die Datei lediglich Informationen darüber enthält, welche Typen ignoriert werden, nicht jedoch, welchen konkreten Dateien diese Typen zugewiesen wurden. In einer Störungssituation kann diese Information unwiederbringlich verloren gehen. Die File-Context-Datenbank enthält dagegen alle erforderlichen Informationen, um den gewünschten Label-Zustand im Dateisystem reproduzierbar wiederherzustellen.
----Um Dateien mit <code>customizable types</code> dennoch zwangsweise auf den vollständig erwarteten Kontext zurückzusetzen, muss <code>restorecon</code> mit dem Parameter <code>-F</code> (Force) ausgeführt werden. In diesem Fall werden '''alle Felder des Kontexts wiederhergestellt'''
<code>restorecon -F -v /srv/custom_app</code>


== Beschleunigung durch Digest-Prüfung. Das Werkzeug <code>restorecon_xattr</code> ==
==== restorecon_xattr ====
Beim rekursiven Relabeling mit <code>restorecon -D</code> durchläuft das Werkzeug den Verzeichnisbaum nicht nur und korrigiert Kontexte, sondern '''schreibt zusätzlich einen internen Digest in das xattr des Verzeichnisses'''. '''Dieser Digest wird im erweiterten Attribut''' <code>security.sehash</code> '''gespeichert'''.
Für die Arbeit mit diesen internen Digest-Einträgen (Anzeigen/Bereinigen) stehen folgende Kommandos zur Verfügung
* restorecon -D (Hashes erzeugen / Dateien unter Verwendung vorhandener Hashes prüfen)
* restorecon -I (Hashes erzeugen / neu erzeugen, wobei vorhandene ignoriert werden)
* sowie das separate Werkzeug restorecon_xattr (Hashes anzeigen / löschen)


Die Aufgabe dieses Digests besteht darin festzuhalten, dass dieses Verzeichnis bereits gegen einen bestimmten Satz von <code>file_contexts</code>-Dateien geprüft wurde, die für die Zuordnung von Pfaden zu erwarteten Kontexten verwendet werden. Beim nächsten Lauf von <code>restorecon -D</code> wird dieser Hash zur Prüfung herangezogen und bei Bedarf aktualisiert, falls er veraltet ist.
; Funktionen von restorecon_xattr
----In modernen RHEL-Versionen wird zur Berechnung dieses Werts '''der kryptographische Algorithmus SHA-256''' verwendet (in älteren Systemen kam SHA-1 zum Einsatz). '''Red Hat / Fedora''' verwenden seit RHEL 9 bzw. Fedora 34+ beim Paket-Build einen eigenen Patch für den Quellcode. In den Paketquellen findet sich dazu direkt eine Datei mit dem Namen <code>0001-Use-SHA-2-instead-of-SHA-1.patch</code>.
* '''Verzeichnisse anzeigen''', in denen security.sehash vorhanden ist
 
Debian verwendet weiterhin SHA-1. Das ist in diesem Kontext jedoch unkritisch, da der Hash im Verzeichnis-xattr nicht für Sicherheitsfunktionen oder Verschlüsselung verwendet wird.
----
 
=== <code>restorecon_xattr</code> ===
Für die Arbeit mit diesen internen Digest-Einträgen (Anzeigen/Bereinigen) stehen folgende Kommandos zur Verfügung:
 
* <code>restorecon -D</code> (Hashes erzeugen / Dateien unter Verwendung vorhandener Hashes prüfen)
* <code>restorecon -I</code> (Hashes erzeugen / neu erzeugen, wobei vorhandene ignoriert werden)
* sowie das separate Werkzeug <code>restorecon_xattr</code> (Hashes anzeigen / löschen)
 
'''Funktionen von''' <code>restorecon_xattr</code>:
 
* '''Verzeichnisse anzeigen''', in denen <code>security.sehash</code> vorhanden ist
* '''Digest und dessen Status''' im Vergleich zum aktuellen Policy-Satz anzeigen
* '''Digest und dessen Status''' im Vergleich zum aktuellen Policy-Satz anzeigen
* '''nur veraltete Digest-Einträge löschen'''
* '''nur veraltete Digest-Einträge löschen'''
* '''alle Digest-Einträge''' in einem angegebenen Verzeichnisbaum löschen
* '''alle Digest-Einträge''' in einem angegebenen Verzeichnisbaum löschen


Nun folgt ein Praxisbeispiel mit einigen Hashes:
; Praxisbeispiel mit einigen Hashes
Start von restorecon mit dem Flag -D und rekursivem Modus -R
restorecon -RDv /var/log


* Start von <code>restorecon</code> mit dem Flag <code>-D</code> und rekursivem Modus <code>-R</code>
Anzeige des Ergebnisses mit restorecon_xattr (zusätzlich mit -r für rekursive Ausgabe)
restorecon_xattr -r /var/log


<code>restorecon -RDv /var/log</code>
Zum Entfernen von Hashes, die nicht mehr zum aktuellen Policy-Satz passen, wird der Parameter -d verwendet


* Anzeige des Ergebnisses mit <code>restorecon_xattr</code> (zusätzlich mit <code>-r</code> für rekursive Ausgabe):
Das Werkzeug berechnet einen neuen Hash und entfernt den alten Hash bei Nichtübereinstimmung (neue Hashes werden dabei nicht geschrieben)
restorecon_xattr -d -r /var/www


  <code>restorecon_xattr -r /var/log</code>
Vollständiges Entfernen aller Digests
  restorecon_xattr -D -r /var/www


* Zum Entfernen von Hashes, die nicht mehr zum aktuellen Policy-Satz passen, wird der Parameter <code>-d</code> verwendet. Das Werkzeug berechnet einen neuen Hash und entfernt den alten Hash bei Nichtübereinstimmung (neue Hashes werden dabei nicht geschrieben).
Dabei werden alle security.sehash-Einträge aus dem Verzeichnisbaum entfernt, unabhängig davon, ob sie noch aktuell sind oder nicht
* Der nächste Lauf von restorecon -D muss die Digests anschließend vollständig neu erzeugen


<code>restorecon_xattr -d -r /var/www</code>
Wichtig ist, dass sich der Nutzen von restorecon -D erst bei '''rekursiver Verarbeitung''' (-R / -r) entfaltet
* Nach einem erfolgreichen rekursiven Relabeling wird beim erneuten Ausführen von restorecon -D (mit denselben Parametern und demselben Policy-Satz) der gespeicherte Digest zur Beschleunigung des Verzeichnisdurchlaufs verwendet
* Das ist insbesondere bei der Prüfung großer Verzeichnisbäume oder sogar des gesamten Dateisystems ab / nützlich


* Vollständiges Entfernen aller Digests
Das bedeutet: '''Wenn der Parameter''' -D '''gesetzt ist''', wird für '''Verzeichnisse ohne vorhandenen Hash''' ein neuer Digest berechnet und in den Attributen gespeichert
* Falls '''für ein Verzeichnis bereits ein Hash existiert''', prüft restorecon dessen Gültigkeit, indem es ihn mit dem neu aus der File-Context-Datenbank berechneten Wert vergleicht. '''Bei Übereinstimmung wird das Verzeichnis beschleunigt verarbeitet.''' '''Bei Nichtübereinstimmung erfolgt die Prüfung des aktuellen Verzeichnisses und aller Unterverzeichnisse im normalen Modus''', also so, als wäre -D nicht gesetzt


<code>restorecon_xattr -D -r /var/www</code>
Wird der Parameter -D nicht verwendet, nutzt restorecon den Mechanismus security.sehash bei der Prüfung überhaupt nicht
Dabei werden alle <code>security.sehash</code>-Einträge aus dem Verzeichnisbaum entfernt, unabhängig davon, ob sie noch aktuell sind oder nicht. Der nächste Lauf von <code>restorecon -D</code> muss die Digests anschließend vollständig neu erzeugen.
----Wichtig ist, dass sich der Nutzen von <code>restorecon -D</code> erst bei '''rekursiver Verarbeitung''' (<code>-R</code> / <code>-r</code>) entfaltet. Nach einem erfolgreichen rekursiven Relabeling wird beim erneuten Ausführen von <code>restorecon -D</code> (mit denselben Parametern und demselben Policy-Satz) der gespeicherte Digest zur Beschleunigung des Verzeichnisdurchlaufs verwendet. Das ist insbesondere bei der Prüfung großer Verzeichnisbäume oder sogar des gesamten Dateisystems ab <code>/</code> nützlich.


Das bedeutet: '''Wenn der Parameter''' <code>-D</code> '''gesetzt ist''', wird für '''Verzeichnisse ohne vorhandenen Hash''' ein neuer Digest berechnet und in den Attributen gespeichert. Falls '''für ein Verzeichnis bereits ein Hash existiert''', prüft <code>restorecon</code> dessen Gültigkeit, indem es ihn mit dem neu aus der File-Context-Datenbank berechneten Wert vergleicht. '''Bei Übereinstimmung wird das Verzeichnis beschleunigt verarbeitet.''' '''Bei Nichtübereinstimmung erfolgt die Prüfung des aktuellen Verzeichnisses und aller Unterverzeichnisse im normalen Modus''', also so, als wäre <code>-D</code> nicht gesetzt.
Wird restorecon -I verwendet, wird ein bereits gespeicherter Digest ignoriert
* Selbst wenn security.sehash formal übereinstimmt, vertraut restorecon diesem Eintrag nicht und '''führt im rekursiven Modus zwangsweise eine erneute vollständige Label-Prüfung durch; anschließend wird der Digest aktualisiert'''
* Voraussetzung ist, dass das Flag -n nicht gesetzt ist und während der Ausführung keine Fehler auftreten


Wird der Parameter <code>-D</code> nicht verwendet, nutzt <code>restorecon</code> den Mechanismus <code>security.sehash</code> bei der Prüfung überhaupt nicht.
; Anwendungsbeispiel
----Wird <code>restorecon -I</code> verwendet, wird ein bereits gespeicherter Digest ignoriert. Selbst wenn <code>security.sehash</code> formal übereinstimmt, vertraut <code>restorecon</code> diesem Eintrag nicht und '''führt im rekursiven Modus zwangsweise eine erneute vollständige Label-Prüfung durch; anschließend wird der Digest aktualisiert'''. Voraussetzung ist, dass das Flag <code>-n</code> nicht gesetzt ist und während der Ausführung keine Fehler auftreten.
restorecon -RIv /var/log


* Anwendungsbeispiel:
Das Verzeichnis wird rekursiv geprüft, und jeder Hash wird unabhängig davon, ob bereits ein Digest in den Attributen vorhanden ist, neu erzeugt


<code>restorecon -RIv /var/log</code>
== Relabeling-Werkzeuge ==
Das Verzeichnis wird rekursiv geprüft, und jeder Hash wird unabhängig davon, ob bereits ein Digest in den Attributen vorhanden ist, neu erzeugt.
; Die Werkzeuge für Relabeling lassen sich in drei Ebenen unterteilen


= SCHRITT 2.7: Relabeling-Werkzeuge =
* setfiles
'''Die Werkzeuge für Relabeling lassen sich in drei Ebenen unterteilen:'''
** Das grundlegende, low-level ausführbare Binärprogramm (in C geschrieben)
** Es bildet den Kernmechanismus zur Anwendung der Policy
** restorecon arbeitet auf Basis von setfiles
* restorecon
** Ein Werkzeug auf Benutzerebene, das für gezielte administrative Eingriffe vorgesehen ist
** restorecon findet, lädt und verwendet automatisch die '''aktuell aktive SELinux-Policy'''
** Das Werkzeug restorecon wird durch dieselbe ausführbare Datei implementiert wie setfiles
** Der Betriebsmodus wird über argv[0] gewählt, also über den Namen, unter dem das Programm aufgerufen wird
* fixfiles
** Dabei handelt es sich nicht um eine Binärdatei, sondern um ein Shell-Skript, das den Aufruf von setfiles und restorecon für globale Systemaufgaben automatisiert
** Es ist eine skriptbasierte Wrapper-Schicht für typische Wartungsoperationen wie check, verify, restore, relabel, onboot sowie für paketbezogene und inkrementelle Betriebsarten
** Das Werkzeug kann mit der Datenbank des Paketmanagers (RPM) arbeiten
** So kann es beispielsweise alle Dateien ermitteln, die zu einem bestimmten Paket gehören, und ausschließlich diese neu labeln
** Außerdem steuert es den Ablauf eines vollständigen System-Relabelings beim Booten


* <code>setfiles</code>
=== Betriebsarten von fixfiles ===
** Das grundlegende, low-level ausführbare Binärprogramm (in C geschrieben). Es bildet den Kernmechanismus zur Anwendung der Policy.
==== fixfiles check / fixfiles verify ====
** <code>restorecon</code> arbeitet auf Basis von <code>setfiles</code>.
check und verify sind Betriebsarten ohne Änderung der Labels
* <code>restorecon</code>
* Sie geben alle inkorrekten Labels aus und zeigen dabei den alten sowie den neuen Kontext an, schreiben jedoch nichts zurück
** Ein Werkzeug auf Benutzerebene, das für gezielte administrative Eingriffe vorgesehen ist.
* Das ist ein praktischer administrativer Audit-Modus vor einem Relabeling oder nach Änderungen an den Regeln
** <code>restorecon</code> findet, lädt und verwendet automatisch die '''aktuell aktive SELinux-Policy'''.
** Das Werkzeug <code>restorecon</code> wird durch dieselbe ausführbare Datei implementiert wie <code>setfiles</code>. Der Betriebsmodus wird über <code>argv[0]</code> gewählt, also über den Namen, unter dem das Programm aufgerufen wird.
* <code>fixfiles</code>
** Dabei handelt es sich nicht um eine Binärdatei, sondern um ein Shell-Skript, das den Aufruf von <code>setfiles</code> und <code>restorecon</code> für globale Systemaufgaben automatisiert.
** Es ist eine skriptbasierte Wrapper-Schicht für typische Wartungsoperationen wie <code>check</code>, <code>verify</code>, <code>restore</code>, <code>relabel</code>, <code>onboot</code> sowie für paketbezogene und inkrementelle Betriebsarten.
** Das Werkzeug kann mit der Datenbank des Paketmanagers (RPM) arbeiten. So kann es beispielsweise alle Dateien ermitteln, die zu einem bestimmten Paket gehören, und ausschließlich diese neu labeln. Außerdem steuert es den Ablauf eines vollständigen System-Relabelings beim Booten.


----
; Beispiel
chcon -R -t tmp_t /var/wwwchcon -R -t shadow_t /srvfixfiles check /var/www /srv


== Betriebsarten von <code>fixfiles</code> ==
==== fixfiles restore ====
restore stellt inkorrekte Labels wieder her


=== <code>fixfiles check</code> / <code>fixfiles verify</code> ===
; Beispiel
<code>check</code> und <code>verify</code> sind Betriebsarten ohne Änderung der Labels.
fixfiles restore /var/www /srv/app


* Sie geben alle inkorrekten Labels aus und zeigen dabei den alten sowie den neuen Kontext an, schreiben jedoch nichts zurück.
==== fixfiles relabel ====
* Das ist ein praktischer administrativer Audit-Modus vor einem Relabeling oder nach Änderungen an den Regeln.
relabel ist für ein vollständiges Relabeling des gesamten Dateisystems vorgesehen
* Das Werkzeug schlägt vor, den Inhalt von /tmp zu löschen
* Anschließend werden alle inkorrekten Dateilabels so korrigiert, dass sie den installierten file_contexts entsprechen


Beispiel:
; Beispiel
  <code>chcon -R -t tmp_t /var/wwwchcon -R -t shadow_t /srvfixfiles check /var/www /srv</code>
  fixfiles relabel


=== <code>fixfiles restore</code> ===
==== fixfiles onboot ====
<code>restore</code> stellt inkorrekte Labels wieder her.
onboot führt das Relabeling nicht sofort aus, sondern bereitet das System so vor, dass das Relabeling beim nächsten Systemstart erfolgt
fixfiles onboot


Beispiel:
=== Optionen ===
<code>fixfiles restore /var/www /srv/app</code>
; Wichtige Optionen
 
{| class="wikitable options big"
=== <code>fixfiles relabel</code> ===
|-
<code>relabel</code> ist für ein vollständiges Relabeling des gesamten Dateisystems vorgesehen:
! Unix !! Beschreibung
 
|-
* Das Werkzeug schlägt vor, den Inhalt von <code>/tmp</code> zu löschen.
| -F || (Force) Setzt den Kontext auch bei Dateien mit customizable types zwangsweise zurück
* Anschließend werden alle inkorrekten Dateilabels so korrigiert, dass sie den installierten <code>file_contexts</code> entsprechen.
|-
 
| -f || (force clear) Leert die temporären Verzeichnisse /tmp und /var/tmp automatisch vor Beginn der Ausführung, ohne interaktive Rückfragen
Beispiel:
* Das ist besonders nützlich für Automatisierungsskripte
  <code>fixfiles relabel</code>
|-
 
| -C PREVIOUS_FILECONTEXT  || (Compare) Vergleicht einen alten file_contexts-Stand mit dem aktuellen und stellt Kontexte nur dort wieder her, wo dies erforderlich ist
=== <code>fixfiles onboot</code> ===
|-
<code>onboot</code> führt das Relabeling nicht sofort aus, sondern bereitet das System so vor, dass das Relabeling beim nächsten Systemstart erfolgt.
| -N "YYYY-MM-DD HH:MM" || (Newer) Beschränkt die Verarbeitung auf Dateien, die nach dem angegebenen Zeitpunkt erstellt wurden
<code>fixfiles onboot</code>
|-
----
| -B  ||  Im Modus restore werden nur Dateien berücksichtigt, die heute verändert wurden
 
* Im Modus onboot schreibt derselbe Schalter das aktuelle Datum in /.autorelabel, wodurch das Relabeling beschleunigt werden kann
== Optionen von <code>fixfiles</code> ==
|-
Zu den wichtigsten Optionen gehören:
| -M  || (Mounts) Führt vor dem Relabeling Bind-Mounts für Dateisysteme aus, sodass auch Kontexte von Objekten korrekt repariert werden können, über denen etwas eingehängt ist
|-
| -T nthreads  || (Threads) Konfiguriert die parallele Verarbeitung mit mehreren Threads oder deaktiviert diese bei -T 1
|-
| -l LOGPATH  || (Log) Leitet die gesamte Ausgabe, also sowohl Standardausgabe als auch Fehlermeldungen, in die angegebene Logdatei statt auf den Bildschirm um
|}


* <code>-F</code> (Force): Setzt den Kontext auch bei Dateien mit <code>customizable types</code> zwangsweise zurück.
[[Kategorie:Linux/SELinux/Praxis]]
* <code>-f</code> (force clear): Leert die temporären Verzeichnisse <code>/tmp</code> und <code>/var/tmp</code> automatisch vor Beginn der Ausführung, ohne interaktive Rückfragen. Das ist besonders nützlich für Automatisierungsskripte.
* <code>-C PREVIOUS_FILECONTEXT</code> (Compare): Vergleicht einen alten <code>file_contexts</code>-Stand mit dem aktuellen und stellt Kontexte nur dort wieder her, wo dies erforderlich ist.
* <code>-N "YYYY-MM-DD HH:MM"</code> (Newer): Beschränkt die Verarbeitung auf Dateien, die nach dem angegebenen Zeitpunkt erstellt wurden.
* <code>-B</code>: Im Modus <code>restore</code> werden nur Dateien berücksichtigt, die heute verändert wurden. Im Modus <code>onboot</code> schreibt derselbe Schalter das aktuelle Datum in <code>/.autorelabel</code>, wodurch das Relabeling beschleunigt werden kann.
* <code>-M</code> (Mounts): Führt vor dem Relabeling Bind-Mounts für Dateisysteme aus, sodass auch Kontexte von Objekten korrekt repariert werden können, über denen etwas eingehängt ist.
* <code>-T nthreads</code> (Threads): Konfiguriert die parallele Verarbeitung mit mehreren Threads oder deaktiviert diese bei <code>-T 1</code>.
* <code>-l LOGPATH</code> (Log): Leitet die gesamte Ausgabe, also sowohl Standardausgabe als auch Fehlermeldungen, in die angegebene Logdatei statt auf den Bildschirm um.

Aktuelle Version vom 27. März 2026, 23:09 Uhr

Woher kommt der „richtige“ Kontext (File Contexts)

In der ersten Phase wurden die tatsächlichen Dateilabels betrachtet: was in security.selinux gespeichert ist, wie dies in ls -Z aussieht und warum sich cp und mv unterschiedlich verhalten

In dieser Lektion kommt die nächste Modellebene hinzu: SELinux speichert nicht nur das aktuelle Label eines Objekts, sondern auch die Vorstellung davon, welcher Kontext einem Pfad gemäß den Regeln der Policy zugewiesen sein soll Für das Verständnis der Logik der SELinux-Labeling-Regeln müssen zwei Begriffe strikt voneinander getrennt werden

  1. Tatsächliches Label (Security Context). Das sind die Daten, die physisch in den erweiterten Attributen des Dateisystems (extended attributes — xattr) auf dem Datenträger gespeichert sind
    • Genau dieses Label sehen der Linux-Kernel und das SELinux-Modul beim Zugriff auf eine Datei und verwenden es für die Zugriffsentscheidung
  2. Erwarteter Kontext (File Context). Das ist eine Regel, die in der SELinux-Policy-Datenbank definiert ist
    • Sie legt fest, welches Label einer Datei oder einem Verzeichnis an einem bestimmten Pfad zugewiesen werden soll

Wo SELinux Informationen über erwartete Kontexte speichert

In der Default-Policy befinden sich die Änderungen im Zusammenhang mit File Contexts im Verzeichnis

/etc/selinux/default/contexts/files/

Die aktuelle Policy kann mit dem Befehl sestatus angezeigt werden

# sestatus
..
SELinux root directory:         /etc/selinux
Loaded policy name:             default
..

Struktur der File-Context-Dateien

  • file_contexts — Basistabelle der File Contexts der aktiven Policy
  • file_contexts.local — lokale administrative Ergänzungen
  • file_contexts.homedirs — separate Einstellungen für Home-Verzeichnisse
  • .subs und .subs_dist — Dateien für Pfadsubstitutionen

Um zu verstehen, wie das System Pfade und Labels einander zuordnet, öffnen wir die Datei /etc/selinux/default/contexts/file/file_contexts

head /etc/selinux/default/contexts/files/file_contexts
Ausgabe
/.*                               system_u:object_r:default_t:s0
/a?quota\.(user|group)    --      system_u:object_r:quota_db_t:s0
/sys(/.*)?                        system_u:object_r:sysfs_t:s0
/xen(/.*)?                        system_u:object_r:xen_image_t:s0
/mnt(/[^/]*)   			      -l      system_u:object_r:mnt_t:s0
/mnt(/[^/]*)?   		        -d      system_u:object_r:mnt_t:s0
/dev/.*                           system_u:object_r:device_t:s0
/etc/.*                           system_u:object_r:etc_t:s0
/opt/.*                           system_u:object_r:usr_t:s0
/run/.* 						                <<none>>

Jede Zeile in dieser Datei stellt eine feste Anweisung für SELinux dar und besteht aus zwei oder drei Spalten

  1. Regulärer Ausdruck (Regular Expression). Die erste Spalte beschreibt den Pfad
    • SELinux verwendet reguläre Ausdrücke im PCRE*-Format
    • Beispielsweise bedeutet der Ausdruck /var/www(/.*)?: sowohl das Verzeichnis /var/www selbst als auch absolut jede Datei oder jedes Unterverzeichnis darin
    • Ausführlicher über reguläre Ausdrücke sprechen wir in den nächsten Lektionen
  2. Objekttyp (optional). Die zweite Spalte kann präzisieren, für welchen Typ von Dateisystemobjekten die Regel gilt
    • -d — nur auf Verzeichnisse anwenden
    • -- — nur auf reguläre Dateien anwenden
    • Falls die Spalte fehlt, gilt die Regel für alle Objekte am angegebenen Pfad.
  3. Erwarteter Kontext (Security Context). Die letzte Spalte enthält das Referenzlabel, das dem Objekt zugewiesen werden soll
    • Das wichtigste Element hierbei ist Type (zum Beispiel httpd_sys_content_t), der die Zugriffsdomänen bestimmt

(* PCRE - Perl-compatible regular expression)

Bei der Initialisierung des Dateisystems oder beim erzwungenen Zurücksetzen der Labels (Relabeling) liest der Kernel diese Datei Zeile für Zeile von oben nach unten

  • Wenn das Dienstprogramm eine Übereinstimmung zwischen dem Dateipfad und dem regulären Ausdruck findet, weist es dem Objekt den entsprechenden Kontext aus der dritten Spalte zu

Struktur von File-Context-Regeln und ihre Prioritäten

Im vorherigen Schritt wurde die Quelle der Dateikontexte analysiert — die Datenbank file_contexts

  • In dieser Lektion gehen wir tiefer in die Funktionsweise dieser Datenbank: wie das System die Zuordnungstabelle path -> label genau liest und wie es entscheidet, welcher Kontext zugewiesen wird, wenn mehrere Regeln auf denselben Pfad passen

Format einer File-Context-Regel

Jeder Eintrag in file_contexts, file_contexts.local und file_contexts.homedirs hat dieselbe Grundform

pathname [file_type] context
  • pathname — vollständiger Pfad oder regulärer PCRE-Ausdruck, anhand dessen SELinux nach Übereinstimmungen sucht
  • file_type — optionale Einschränkung auf einen Objekttyp
  • context — der Kontext, der dem Objekt zugewiesen werden soll

pathname

Betrachten wir ein Beispiel für eine Regel

/var/www(/.*)?    system_u:object_r:httpd_sys_content_t:s0
  • Die Regel deckt den gesamten Teilbaum /var/www ab, also das Verzeichnis selbst und alle darin enthaltenen Objekte

file_type

Die optionale zweite Spalte schränkt die Regel auf einen bestimmten Objekttyp ein

In File Contexts werden folgende Bezeichnungen verwendet

Wert Beschreibung
d Verzeichnis
- reguläre Datei
l symbolischer Link
s Socket
p Named Pipe
c Zeichengerätedatei
b Blockgerätedatei

context

Die letzte Spalte enthält genau den erwarteten Security Context, der für einen übereinstimmenden Pfad zurückgegeben werden soll

  • Im Normalfall ist das ein vollständiges Label im Format user:role:type:range

Zulässig ist auch der spezielle Wert <<none>>

  • Er bedeutet, dass beim Relabeling für den übereinstimmenden Pfad kein Kontext gesetzt werden soll und dass ein Lookup kein Ergebnis zurückliefert

Prioritäten der Regeln

Basis- und modulare Policy-Definitionen

Um Konflikte zu vermeiden, verwendet der SELinux-Parser ein striktes Prioritätssystem

  1. Eine exakte Übereinstimmung hat die höchste Priorität. Eine Regel, die einen Pfad ohne Platzhalter regulärer Ausdrücke beschreibt (zum Beispiel genau /etc/passwd), gewinnt immer gegenüber allgemeineren Ausdrücken
  2. Die maximale Länge der Übereinstimmung bestimmt die Spezifität. Falls es keine exakte Übereinstimmung gibt, gewinnt die spezifischste Regel — also diejenige, bei der der übereinstimmende Teil des Pfads länger ist
    • Eine Regel für /var/www/html(/.*)? sticht eine allgemeinere Regel für /var/www(/.*)?
  3. Eine explizite Angabe der Objektklasse erhöht die Priorität. Bei gleicher Länge der Übereinstimmung hat eine Regel mit explizit angegebenem Klassifizierer (zum Beispiel -d für Verzeichnisse oder -- für reguläre Dateien) Vorrang vor einer Regel ohne Klassenangabe

Dank dieser Hierarchie werden Basislabels auf der Ebene der Wurzel des Dateisystems gesetzt und dann beim tieferen Abstieg im Verzeichnisbaum weiter verfeinert und überschrieben

Lokale Regeln in file_contexts.local

Für lokale SELinux-Regeln gilt eine andere Prioritätslogik als für Basis- und modulare Policy-Definitionen

  1. Lokale Regeln haben Vorrang vor der Policy. Jeder Eintrag aus file_contexts.local, der zum Beispiel über semanage fcontext hinzugefügt wurde, wird vor den entsprechenden Definitionen aus der Basis-Policy oder aus Modulen berücksichtigt
  2. Die Priorisierung erfolgt von neuen zu alten Einträgen. Lokale Regeln werden nicht nach dem Prinzip „am spezifischsten“ verarbeitet, sondern in umgekehrter Reihenfolge ihrer Hinzufügung: vom zuletzt hinzugefügten Eintrag bis zum frühesten
  3. Es wird die erste Übereinstimmung verwendet. Sobald eine passende lokale Regel gefunden wurde, wird die weitere Suche beendet
    • Das bedeutet, dass ein allgemeinerer, aber später hinzugefügter Ausdruck einen genaueren, aber früher erstellten Ausdruck überdecken kann

Daher erfordern lokale Regeln besondere Sorgfalt: Ein zu weit gefasster Ausdruck, der über semanage fcontext hinzugefügt wurde, kann unerwartet genauere Basisdefinitionen der Policy überdecken

Genau aus diesem Grund sollten lokale reguläre Ausdrücke möglichst eng gefasst und zielgerichtet sein, sodass sie nur den tatsächlich benötigten Abschnitt des Verzeichnisbaums überschreiben

Befehl matchpathcon

matchpathcon fragt die System-Policy ab und gibt den Standardkontext aus, der mit dem angegebenen Pfad verknüpft ist

  • Das Werkzeug ist speziell für die Analyse des erwarteten Kontexts nützlich und nicht für den aktuellen Inhalt von xattr
  • Dieses Dienstprogramm verwaltet keine Regeln, sondern zeigt lediglich das Ergebnis der Pfadprüfung gegen die File-Context-Datenbank an
Hauptziele bei der Verwendung von matchpathcon
  • verstehen, welches Label ein Pfad haben sollte
  • das tatsächliche Label mit der Policy-Erwartung vergleichen
  • im Voraus prüfen, welchen Kontext ein neuer Pfad nach dem Ausführen von restorecon erhält
Prüfschichten

Prüfschichten entsprechend der Priorität der Regeln (von der niedrigsten zur höchsten Priorität)

  • Basisregeln der Policy (file_contexts)
  • Regeln für Home-Verzeichnisse (file_contexts.homedirs)
  • Systemweite Pfad-Aliase der Distribution (file_contexts.subs_dist)
  • Lokale Äquivalenzregeln (file_contexts.subs)
  • lokale administrative Änderungen (file_contexts.local)
Optionen

Zunächst verwenden wir den Befehl ohne Parameter, um das erwartete Label für die Datei /etc/resolv.conf anzusehen

  • Anschließend vergleichen wir es mit dem tatsächlichen Label mittels ls
matchpathcon /etc/resolv.conf
ls -Z /etc/resolv.conf
  • Für die Problemdiagnose — insbesondere um zu prüfen, ob der auf dem Datenträger vorhandene Kontext mit dem Standardkontext aus der Policy übereinstimmt — ist auch der Parameter -V (Verify) praktisch
  • Zur Veranschaulichung erzeugen wir eine Situation, in der das aktuelle Label nicht mit dem erwarteten übereinstimmt
cp -a /etc/hosts /var/log/hosts
matchpathcon -V /var/log/hosts
/var/log/hosts has context system_u:object_r:net_conf_t:s0, should be system_u:object_r:var_log_t:s0

Wichtig ist zu beachten, dass das Dienstprogramm matchpathcon für manche Pfade <<none>> zurückgeben kann (zum Beispiel für Dateien in tmp)

  • Das ist ein spezieller interner Wert in der Datenbank file_contexts: Er bedeutet, dass für diesen Pfad und Objekttyp kein erwarteter Standardkontext gefunden wurde oder dass dieser Pfad kein Label über File Context erhalten soll
  • Der Objekttyp kann mit dem Parameter -m (mode) erzwungen angegeben werden
  • Das ist besonders wichtig für Pfade, die noch nicht existieren, oder wenn ein konkretes Szenario geprüft werden soll: „Was wäre, wenn dies ein Verzeichnis wäre?“ oder „Was wäre, wenn dies eine Datei wäre?“
matchpathcon -m dir /etc/dir
matchpathcon -m file /var/log/mylog.log

Zuordnung der Objekttypen in file_contexts und der ausgeschriebenen Werte für den Parameter -m

matchpathcon -m file_contexts
file
dir
lnk_file
sock_file
pipe
chr_file
blk_file

Am häufigsten werden die Typen file, dir, lnk_file verwendet

Für Skripte und Automatisierung ist der Parameter -n (no path) praktisch

matchpathcon -n /etc/hosts

Die Ausgabe enthält dann nicht den Pfad, sondern nur das Ergebnis der Prüfung des erwarteten File Context

  • Schließlich kann statt der aktuellen auch eine alternative Datei file_contexts verwendet werden
  • Das kann für Testzwecke nützlich sein; dafür dient der Parameter -f (file contexts)
matchpathcon -f /tmp/test_file_contexts /srv/myapp

Außerdem kann mit dem Parameter -P (Policy) ein alternativer Pfad für einen vollständigen Policy-Satz verwendet werden

Spezielle File Contexts für Dateisysteme und Mount-Optionen

In den vorherigen Schritten wurde das klassische SELinux-Modell betrachtet

  • Ein Pfad wird mit einer Regel aus file_contexts abgeglichen
  • Danach erhält die Datei den erwarteten Kontext über restorecon, setfiles oder bei der Erstellung eines neuen Objekts

Dieses Modell arbeitet auf der Ebene einzelner Inodes und Pfade

Beim normalen Einhängen eines Dateisystems wird — sofern es xattrs unterstützt — der Kontext jeder Datei aus dem security.selinux-Attribut der jeweiligen Datei übernommen

  • Wenn das Dateisystem keine xattrs unterstützt, erhalten die Objekte standardmäßig einen einheitlichen Kontext, der vom Typ des Dateisystems abhängt

In dieser Lektion wird der Mount-Mechanismus behandelt, mit dem die VFS (Virtual File System) des Linux-Kernels Kontexte „on the fly“ zuweisen kann, wobei pfadbasierte Labeling-Regeln ignoriert oder ergänzt werden

Mount Context

Wenn ein Dateisystem mit speziellen SELinux-Optionen eingehängt wird, ändert der Kernel die Art der Label-Verarbeitung

  1. Das System greift auf eine Datei zu
  2. Der Kernel erkennt, dass für den Mount-Punkt eine feste Regel definiert ist
  3. Das tatsächliche Label auf dem Datenträger wird ignoriert (oder gar nicht erst abgefragt)
  4. SELinux verwendet den Kontext, der im Arbeitsspeicher durch die Parameter des Befehls mount festgelegt wurde

Wichtig ist zu verstehen, dass Mount-Optionen weder die Dateiattribute auf dem Datenträger noch die File-Context-Regeln physisch verändern

  • Stattdessen erzeugen sie eine temporäre virtuelle Projektion der Labels im Arbeitsspeicher

Diese Ersetzung gilt genau so lange, wie das Dateisystem eingehängt ist

  • Sobald die Ressource ausgehängt wird (mit dem Befehl umount), verschwinden diese Overrides: Die lokale Datenbank file_contexts bleibt unverändert, und auf dem Datenträger bleiben exakt dieselben xattr-Attribute erhalten wie vor dem Mounten

Mount-Optionen

context (Globale Überschreibung)

Die Option context= ist in zwei Hauptfällen nützlich

  • das Dateisystem unterstützt keine xattr, sodass ein normales SELinux-Labeling darauf nicht möglich ist;
  • dem Dateisystem kann im Hinblick auf bereits vorhandene Attribute nicht vertraut werden, und beim Mounten muss vorübergehend ein einheitlicher sicherer Kontext erzwungen werden
    • Ein praktisches Beispiel sind Wechselmedien (USB-Sticks)

Wenn context= gesetzt ist, versucht SELinux nicht mehr, xattr vom Datenträger zu lesen

  • Auch die Datenbank file_contexts wird für diesen Pfad ignoriert
  • Es ist dann nicht möglich, das Label einer einzelnen Datei innerhalb einer solchen Ressource mit chcon oder restorecon zu ändern — der Kernel gibt in diesem Fall einen Fehler zurück
Befehlsbeispiele

Für Wechselmedien

mount -o context="system_u:object_r:removable_t:s0" /dev/sdb1 /mnt/usb

Für eine Netzwerkressource, die vom Webserver gelesen werden soll

mount server:/export /srv/www -o context="system_u:object_r:httpd_sys_content_t:s0"

defcontext= (Standardkontext)

Die Option defcontext= dient einer anderen Aufgabe: Sie ändert den Kontext für unlabeled Dateien

Sie wirkt nur dort, wo ein Objekt kein eigenes SELinux-Label auf dem Datenträger hat

  • Wenn eine Datei bereits ein Label hat, verwendet SELinux dieses
  • Wenn kein Label vorhanden ist (zum Beispiel wenn eine Datei gerade aus einem alten System ohne SELinux-Unterstützung kopiert wurde), wird ihr „on the fly“ der in defcontext= angegebene Kontext zugewiesen
Befehlsbeispiel
mount /dev/sdb2 /test -o defcontext="system_u:object_r:samba_share_t:s0"

rootcontext= (Kontext des Mount-Punkts)

Die Option rootcontext= erlaubt es, den Kontext des Root-Inodes eines Dateisystems explizit festzulegen, bevor es im Userspace sichtbar wird

  • Sie bestimmt den Kontext ausschließlich für das Wurzelverzeichnis des eingehängten Dateisystems, ohne dessen Inhalt zu beeinflussen

Das ist nützlich, wenn das korrekte Label für das Verzeichnis selbst (zum Beispiel /mnt/backup) gesetzt werden soll, damit Dienste es betreten können, während die individuellen Labels aller enthaltenen Dateien auf dem Datenträger erhalten bleiben

mount -t tmpfs none /srv/chroot -o rootcontext="system_u:object_r:tmp_t:s0"

fscontext= (Kontext des Superblocks)

Weist der abstrakten Dateisysteminstanz selbst einen Kontext als Objekt zu, nicht den darin enthaltenen Dateien

Dies ist eine Low-Level-Option

  • Sie wird von SELinux selbst verwendet, um zu bestimmen, ob ein bestimmter Prozess (zum Beispiel ein Mount-Daemon) das Recht hat, Dateisysteme dieses Typs einzuhängen
  • In der täglichen Administration wird sie manuell nur äußerst selten verwendet

Aufgabe

Wir erstellen zwei Mount-Punkte

sudo mkdir -p /mnt/lab_context
sudo mkdir -p /mnt/lab_rootcontext

Wir mounten tmpfs mit einem einheitlichen Kontext

sudo mount -t tmpfs none /mnt/lab_context -o context="system_u:object_r:httpd_sys_content_t:s0"
ls -Zd /mnt/lab_context

Nun erstellen wir einige Objekte darin

touch /mnt/lab_context/file1
mkdir /mnt/lab_context/dir1
ls -lZ1 /mnt/lab_context

Jetzt versuchen wir, den Kontext manuell zu ändern

chcon -t tmp_t /mnt/lab_context/file1

Der Kernel gibt einen Fehler zurück, da bei Verwendung des Mount-Parameters context= eine Kontextänderung nicht möglich ist.

Nun versuchen wir, ein anderes Dateisystem mit dem Parameter defcontext= einzuhängen

mount -t tmpfs none /mnt/lab_rootcontext -o rootcontext="system_u:object_r:samba_share_t:s0"
ls -Zd /mnt/lab_rootcontext

Wir erstellen Objekte

touch /mnt/lab_rootcontext/file1
mkdir /mnt/lab_rootcontext/dir1
touch /mnt/lab_rootcontext/file2
ls -lZ1 /mnt/lab_rootcontext

Wie man sehen kann, wurde der Kontext der Dateien vom root-Verzeichnis geerbt

Nun versuchen wir, den Kontext zu ändern

chcon -R -t tmp_t /mnt/lab_rootcontext/*
ls -lZ1 /mnt/lab_rootcontext/

Und der Vorgang wird erfolgreich ausgeführt, da rootcontext nur den Kontext des Wurzelverzeichnisses des eingehängten Dateisystems ändert.

Das kann nützlich sein, wenn ein temporärer Speicher auf tmpfs benötigt wird, dessen Wurzel jedoch sofort den richtigen Typ haben soll, damit neue Dateien den gewünschten Kontext erben

  • Gleichzeitig bleibt die Möglichkeit erhalten, andere Dateien mit bereits vorhandenem, vom Wurzelverzeichnis abweichendem Kontext zu schreiben

Verwaltung von Kontexten mit semanage

Nun ist es endlich an der Zeit, die Verwaltung der File-Context-Datenbank zu betrachten

Wie bereits zuvor besprochen, überschreibt chcon direkt die erweiterten Attribute (xattr) auf dem Datenträger, teilt der SELinux-Policy-Datenbank (file_contexts) jedoch absolut nichts darüber mit

Änderungen, die mit chcon vorgenommen werden, sind im Maßstab des Systemlebenszyklus nur temporär

Sie werden bei jedem der folgenden Ereignisse unwiderruflich zerstört (durch Referenzwerte aus der Datenbank überschrieben)

  • der Administrator startet das Dienstprogramm restorecon manuell für dieses Verzeichnis;
  • es erfolgt ein Systemupdate eines Pakets (zum Beispiel des Webservers), dessen Installer eine Prüfung der Kontexte auslöst;
  • beim Booten wird ein vollständiges Relabeling des Dateisystems initiiert (durch Erzeugen der Datei /.autorelabel)

semanage fcontext

Damit ein Kontext alle Updates und Relabeling-Vorgänge übersteht, muss man dem SELinux-System selbst beibringen, dass ein nicht standardmäßiger Pfad nun ein bestimmtes Label haben soll

Dafür wird das Werkzeug semanage (SELinux Policy Management Tool) verwendet

  • Es ist das allgemeine Werkzeug zur lokalen Verwaltung von Elementen der SELinux-Policy, darunter: login mappings, SELinux users, ports, interfaces, modules, booleans, permissive types und file contexts
  • Für den aktuellen Schritt ist insbesondere der Bereich fcontext relevant

Verwendung

Zur Demonstration versuchen wir, ein nicht standardmäßiges Verzeichnis mit hochsensiblen Daten zu schützen

Stellen wir uns folgende Situation vor: Entwickler haben ein internes Authentifizierungssystem ausgerollt, das Sicherungskopien der Passwort-Hashes von Benutzern in einem nicht standardmäßigen Verzeichnis speichert — /opt/app_auth/vault/

mkdir -p /opt/app_auth/vault
ls -Zd /opt/app_auth/vault/

Wenn wir uns an die Analyse der Datei file_contexts aus den vorherigen Schritten erinnern, erhalten das Verzeichnis /opt/ und sein gesamter Inhalt standardmäßig den Kontext usr_t

Das ist ein öffentlicher Kontext
  • Die meisten laufenden Dienste und Benutzer dürfen Dateien mit diesem Label lesen.
  • Passwörter dort zu speichern ist unzulässig.
  • Daher muss für dieses Verzeichnis eine grundlegende Regel erstellt werden

Verwenden wir dazu die Parameter -a (add) und -t (Feld type)

semanage fcontext -a -t shadow_t "/opt/app_auth/vault(/.*)?"

"/opt/app_auth/vault(/.*)?" — ein regulärer Ausdruck, der das Verzeichnis selbst und absolut alle darin enthaltenen Dateien umfasst

Nun prüfen wir den Kontext des Verzeichnisses

ls -Zd /opt/app_auth/vault/

...und sehen, dass sich nichts geändert hat

  • Das liegt daran, dass wir zwar einen Eintrag in die Datenbank hinzugefügt haben, das bloße Hinzufügen eines Eintrags jedoch kein Relabeling auslöst
  • Um die Änderungen anzuwenden, wird das uns bereits bekannte Werkzeug restorecon verwendet
restorecon -Rv /opt/app_auth/vault/
ls -Zd /opt/app_auth/vault/

Ergebnis

# ls -Zd /opt/app_auth/vault/
unconfined_u:object_r:shadow_t:s0 /opt/app_auth/vault/

Prüfen wir, ob der Eintrag in der File-Context-Datenbank vorhanden ist

cat /etc/selinux/default/contexts/files/file_contexts.local
# This file is auto-generated by libsemanage
# Do not edit directly
/opt/app_auth/vault(/.*)?    system_u:object_r:shadow_t:s0

Jetzt sind die vertraulichen Daten zuverlässig geschützt!

Optionen

Das Werkzeug semanage verfügt über verschiedene nützliche Optionen; konzentrieren wir uns auf die wichtigsten

Welche nicht standardmäßigen Regeln manuell hinzugefügt wurden, kann mit der Option -l (list) zusammen mit dem Modifikator -C (Custom) angezeigt werden

semanage fcontext -lC

Den Kontexttyp für den bereits in der lokalen Datenbank registrierten Pfad /srv/myweb(/.*)? kann man mit der Option -m (modify) aktualisieren

semanage fcontext -m -t httpd_sys_rw_content_t "/srv/myweb(/.*)?"
Wichtig ist, dass der reguläre Ausdruck genau mit dem Eintrag in der Datenbank übereinstimmt, dessen Kontext wir ändern wollen

Wenn ein Dienst außer Betrieb genommen wurde und das nicht standardmäßige Verzeichnis nicht mehr benötigt wird, kann die Regel mit der Option -d gelöscht werden

semanage fcontext -d "/opt/app_auth/vault(/.*)?"

Äquivalente Pfade (Equivalence Rules)

Bei der Arbeit mit mehreren Verzeichnissen entsteht häufig die Situation, dass

  • bereits eine korrekt gekennzeichnete Struktur existiert
  • eine Kopie dieser Struktur an einem anderen Ort erstellt werden muss

Beispielaufgabe

Es gibt den Standardpfad des Webservers /var/www, wir haben jedoch beschlossen, die Dateien unserer neuen Website in einem nicht standardmäßigen Verzeichnis abzulegen, zum Beispiel auf einer separaten Festplatte, die unter /srv/myweb eingehängt ist

Wir erstellen zur Veranschaulichung mehrere Ordner im ursprünglichen Verzeichnis /var/www und bereiten das neue Verzeichnis /srv/myweb vor

mkdir -p /var/www/sessions && mkdir -p /var/www/cgi-binrestorecon -v -R /var/wwwls -Z1 /var/wwwmkdir -p /srv/mywebcp -r /var/www/* /srv/myweb/ls -Z1 /srv/myweb

Standardmäßig sind für das Verzeichnis /var/www und alle seine Unterverzeichnisse (html, cgi-bin usw.) im System bereits Dutzende komplexer regulärer Ausdrücke definiert, die die korrekten Kontexte zuweisen (zum Beispiel httpd_cache_t für /var/www/uploads(/.*)?)

  • Alle regulären Ausdrücke aus /var/www manuell für das neue Verzeichnis /srv/myweb umzuschreiben, wäre aufwendig, unhandlich und fehleranfällig

Für die Lösung solcher Aufgaben werden Äquivalenzregeln verwendet (Parameter -e des Befehls semanage fcontext)

semanage fcontext -a -e /var/www /srv/myweb

Änderungen anwenden

restorecon -v -R /srv/myweb

Sehen wir uns an, wie das in der Datenbank aussieht

# semanage fcontext -lCSELinux fcontext                                   type               Context​/opt/app_auth/vault(/.*)?                          all files          system_u:object_r:shadow_t:s0​SELinux Local fcontext Equivalence​/srv/myweb = /var/www

Eine Äquivalenzregel funktioniert wie ein transparenter Alias: Wenn SELinux irgendeine Datei innerhalb von /srv/myweb/ prüft, ersetzt es in deren Pfad virtuell /srv/myweb durch /var/www und sucht erst danach Übereinstimmungen in seiner umfangreichen Datenbank regulärer Ausdrücke

Wenn es erforderlich ist, die Äquivalenzregel zu entfernen, geschieht dies mit dem bereits bekannten Parameter -d; man muss ihn lediglich anstelle des Parameters -a aus dem ursprünglichen Befehl verwenden

semanage fcontext -d -e /var/www /srv/mywebsemanage fcontext -lC

Export und Import lokaler Policies

Das Dienstprogramm semanage kann Policies mit den Befehlen semanage export und semanage import in eine Datei exportieren beziehungsweise aus einer Datei importieren

  • In der Praxis wird das zum Beispiel verwendet, wenn ein Administrator plant, Policies von einem Testserver auf die Produktionsumgebung zu übertragen

Export

Verwendungsbeispiel

semanage export -f /tmp/selinux_local_rules.txt

Prüfen wir, was sich darin befindet

cat /tmp/selinux_local_rules.txt
boolean -Dlogin -Dinterface -D...fcontext -a -f a -t shadow_t -r 's0' '/opt/app_auth/vault(/.*)?'module -d acpimodule -d aisexecmodule -d amtu..

Wie man sehen kann, ist die Datei logisch in drei Teile gegliedert

  • Bereinigungsblock (Einträge mit dem Schlüssel -D) – beim Import der Datei auf einem neuen Server (über semanage import) soll das Policy-System zu einer exakten Kopie des Quellservers werden
  • Daher müssen alle lokalen Einstellungen gelöscht werden
  • Der Schlüssel -D wird als Delete interpretiert
  • Lokale Regeln (im Beispiel die einzige Regel fcontext)
  • Block deaktivierter Policy-Module (Einträge mit dem Schlüssel -d) – das Policy-Set default policy in Debian ist gehärtet (hardened) und deaktiviert ungenutzte Module
  • In RHEL macht die Policy targeted genau das Gegenteil: Dort sind standardmäßig von Anfang an alle Module aktiviert, unabhängig davon, ob die entsprechende Software installiert ist oder nicht

Import

Für den Import wird der Befehl semanage import verwendet; seine Syntax sieht identisch zum Export aus

semanage import -f /tmp/selinux_local_rules.txt

Wenn uns die importierten Policies zusagen und alles Erforderliche mit matchpathcon -V geprüft wurde, wenden wir die Änderungen an

restorecon -Rv /

Wiederherstellung korrekter Labels

Relabeling mit restorecon

Der Arbeitsablauf von restorecon lässt sich vereinfacht wie folgt beschreiben

  1. Das Werkzeug übernimmt einen Zielpfad und liest die aktive SELinux-Policy bzw. die zugehörige File-Context-Datenbasis
  2. Der Zielpfad wird gegen die regulären Ausdrücke aus der Policy-Datenbasis abgeglichen
  3. Das Werkzeug liest den tatsächlich gesetzten erweiterten Dateiattributwert (xattr) des Objekts direkt aus dem Dateisystem
  4. Anschließend erfolgt ein Vergleich zwischen dem laut Policy erwarteten Kontext und dem tatsächlich gesetzten Label (Attribut) des Objekts
  5. Falls die Prüfung rekursiv für ein Verzeichnis ausgeführt wurde, berechnet restorecon einen Hash über die dabei verwendeten regulären Ausdrücke und speichert ihn im versteckten Attribut des Verzeichnisses security.sehash
    • Beim nächsten Lauf beginnt Schritt 2 dann mit dem Vergleich dieses Hashes, um Zeit zu sparen

Verwendung

In der Praxis werden drei Betriebsarten verwendet

Passive Prüfung ohne Änderungen
restorecon -nv /var/www/html/index.html

Die Option -n verhindert das Schreiben neuer Labels und versetzt das Werkzeug in den Prüfmodus

  • Der Parameter -v zeigt Objekte an, deren Labels vom erwarteten Zustand abweichen
Korrektur eines einzelnen Objekts
restorecon -v /var/www/html/index.html

Korrigiert den Kontext der angegebenen Datei

  • Praktisch werden dabei genau die Änderungen angewendet, die im vorherigen Beispiel lediglich angezeigt wurden
Massenhafte rekursive Korrektur eines Verzeichnisbaums
restorecon -Rv /var

Die Optionen -R und -r aktivieren den rekursiven Verzeichnisdurchlauf

  • Genau dieser Modus wird typischerweise nach dem Hinzufügen neuer Regeln mit semanage fcontext oder nach einer beschädigten Teil-Relabeling-Situation verwendet

customizable types

In SELinux existiert ein Ausnahme-Mechanismus für Relabeling mit der Bezeichnung customizable types

Dabei handelt es sich um eine vordefinierte Liste von Kontexten (Typen), die vom System als manuell administrierbar betrachtet werden

  • Entsprechend werden solche Dateien bei der Prüfung und beim Relabeling durch SELinux-Werkzeuge und -Mechanismen (einschließlich restorecon, .autorelabel, setfiles, fixfiles) ignoriert

Die Liste der customizable types wird aus folgender Datei gelesen

/etc/selinux/{SELINUXPOLICY}/contexts/customizable_types
Obwohl der Mechanismus der customizable types in modernen Distributionen weiterhin existiert und funktioniert, gilt er in der Administratoren-Community heute als veraltender Ansatz
  • Der Grund ist, dass die Datei lediglich Informationen darüber enthält, welche Typen ignoriert werden, nicht jedoch, welchen konkreten Dateien diese Typen zugewiesen wurden
  • In einer Störungssituation kann diese Information unwiederbringlich verloren gehen
  • Die File-Context-Datenbank enthält dagegen alle erforderlichen Informationen, um den gewünschten Label-Zustand im Dateisystem reproduzierbar wiederherzustellen

Um Dateien mit customizable types dennoch zwangsweise auf den vollständig erwarteten Kontext zurückzusetzen, muss restorecon mit dem Parameter -F (Force) ausgeführt werden

  • In diesem Fall werden alle Felder des Kontexts wiederhergestellt
restorecon -F -v /srv/custom_app

Beschleunigung durch Digest-Prüfung

Das Werkzeug restorecon_xattr

Beim rekursiven Relabeling mit restorecon -D durchläuft das Werkzeug den Verzeichnisbaum nicht nur und korrigiert Kontexte, sondern schreibt zusätzlich einen internen Digest in das xattr des Verzeichnisses.

Digest wird im erweiterten Attribut security.sehash gespeichert

Die Aufgabe dieses Digests besteht darin festzuhalten, dass dieses Verzeichnis bereits gegen einen bestimmten Satz von file_contexts-Dateien geprüft wurde, die für die Zuordnung von Pfaden zu erwarteten Kontexten verwendet werden

  • Beim nächsten Lauf von restorecon -D wird dieser Hash zur Prüfung herangezogen und bei Bedarf aktualisiert, falls er veraltet ist

In modernen RHEL-Versionen wird zur Berechnung dieses Werts der kryptographische Algorithmus SHA-256 verwendet (in älteren Systemen kam SHA-1 zum Einsatz). Red Hat/Fedora verwenden seit RHEL 9 bzw. Fedora 34+ beim Paket-Build einen eigenen Patch für den Quellcode

  • In den Paketquellen findet sich dazu direkt eine Datei mit dem Namen 0001-Use-SHA-2-instead-of-SHA-1.patch

Debian verwendet weiterhin SHA-1

  • Das ist in diesem Kontext jedoch unkritisch, da der Hash im Verzeichnis-xattr nicht für Sicherheitsfunktionen oder Verschlüsselung verwendet wird

restorecon_xattr

Für die Arbeit mit diesen internen Digest-Einträgen (Anzeigen/Bereinigen) stehen folgende Kommandos zur Verfügung

  • restorecon -D (Hashes erzeugen / Dateien unter Verwendung vorhandener Hashes prüfen)
  • restorecon -I (Hashes erzeugen / neu erzeugen, wobei vorhandene ignoriert werden)
  • sowie das separate Werkzeug restorecon_xattr (Hashes anzeigen / löschen)
Funktionen von restorecon_xattr
  • Verzeichnisse anzeigen, in denen security.sehash vorhanden ist
  • Digest und dessen Status im Vergleich zum aktuellen Policy-Satz anzeigen
  • nur veraltete Digest-Einträge löschen
  • alle Digest-Einträge in einem angegebenen Verzeichnisbaum löschen
Praxisbeispiel mit einigen Hashes

Start von restorecon mit dem Flag -D und rekursivem Modus -R

restorecon -RDv /var/log

Anzeige des Ergebnisses mit restorecon_xattr (zusätzlich mit -r für rekursive Ausgabe)

restorecon_xattr -r /var/log

Zum Entfernen von Hashes, die nicht mehr zum aktuellen Policy-Satz passen, wird der Parameter -d verwendet

Das Werkzeug berechnet einen neuen Hash und entfernt den alten Hash bei Nichtübereinstimmung (neue Hashes werden dabei nicht geschrieben)

restorecon_xattr -d -r /var/www

Vollständiges Entfernen aller Digests

restorecon_xattr -D -r /var/www

Dabei werden alle security.sehash-Einträge aus dem Verzeichnisbaum entfernt, unabhängig davon, ob sie noch aktuell sind oder nicht

  • Der nächste Lauf von restorecon -D muss die Digests anschließend vollständig neu erzeugen

Wichtig ist, dass sich der Nutzen von restorecon -D erst bei rekursiver Verarbeitung (-R / -r) entfaltet

  • Nach einem erfolgreichen rekursiven Relabeling wird beim erneuten Ausführen von restorecon -D (mit denselben Parametern und demselben Policy-Satz) der gespeicherte Digest zur Beschleunigung des Verzeichnisdurchlaufs verwendet
  • Das ist insbesondere bei der Prüfung großer Verzeichnisbäume oder sogar des gesamten Dateisystems ab / nützlich

Das bedeutet: Wenn der Parameter -D gesetzt ist, wird für Verzeichnisse ohne vorhandenen Hash ein neuer Digest berechnet und in den Attributen gespeichert

  • Falls für ein Verzeichnis bereits ein Hash existiert, prüft restorecon dessen Gültigkeit, indem es ihn mit dem neu aus der File-Context-Datenbank berechneten Wert vergleicht. Bei Übereinstimmung wird das Verzeichnis beschleunigt verarbeitet. Bei Nichtübereinstimmung erfolgt die Prüfung des aktuellen Verzeichnisses und aller Unterverzeichnisse im normalen Modus, also so, als wäre -D nicht gesetzt

Wird der Parameter -D nicht verwendet, nutzt restorecon den Mechanismus security.sehash bei der Prüfung überhaupt nicht

Wird restorecon -I verwendet, wird ein bereits gespeicherter Digest ignoriert

  • Selbst wenn security.sehash formal übereinstimmt, vertraut restorecon diesem Eintrag nicht und führt im rekursiven Modus zwangsweise eine erneute vollständige Label-Prüfung durch; anschließend wird der Digest aktualisiert
  • Voraussetzung ist, dass das Flag -n nicht gesetzt ist und während der Ausführung keine Fehler auftreten
Anwendungsbeispiel
restorecon -RIv /var/log
Das Verzeichnis wird rekursiv geprüft, und jeder Hash wird unabhängig davon, ob bereits ein Digest in den Attributen vorhanden ist, neu erzeugt

Relabeling-Werkzeuge

Die Werkzeuge für Relabeling lassen sich in drei Ebenen unterteilen
  • setfiles
    • Das grundlegende, low-level ausführbare Binärprogramm (in C geschrieben)
    • Es bildet den Kernmechanismus zur Anwendung der Policy
    • restorecon arbeitet auf Basis von setfiles
  • restorecon
    • Ein Werkzeug auf Benutzerebene, das für gezielte administrative Eingriffe vorgesehen ist
    • restorecon findet, lädt und verwendet automatisch die aktuell aktive SELinux-Policy
    • Das Werkzeug restorecon wird durch dieselbe ausführbare Datei implementiert wie setfiles
    • Der Betriebsmodus wird über argv[0] gewählt, also über den Namen, unter dem das Programm aufgerufen wird
  • fixfiles
    • Dabei handelt es sich nicht um eine Binärdatei, sondern um ein Shell-Skript, das den Aufruf von setfiles und restorecon für globale Systemaufgaben automatisiert
    • Es ist eine skriptbasierte Wrapper-Schicht für typische Wartungsoperationen wie check, verify, restore, relabel, onboot sowie für paketbezogene und inkrementelle Betriebsarten
    • Das Werkzeug kann mit der Datenbank des Paketmanagers (RPM) arbeiten
    • So kann es beispielsweise alle Dateien ermitteln, die zu einem bestimmten Paket gehören, und ausschließlich diese neu labeln
    • Außerdem steuert es den Ablauf eines vollständigen System-Relabelings beim Booten

Betriebsarten von fixfiles

fixfiles check / fixfiles verify

check und verify sind Betriebsarten ohne Änderung der Labels

  • Sie geben alle inkorrekten Labels aus und zeigen dabei den alten sowie den neuen Kontext an, schreiben jedoch nichts zurück
  • Das ist ein praktischer administrativer Audit-Modus vor einem Relabeling oder nach Änderungen an den Regeln
Beispiel
chcon -R -t tmp_t /var/wwwchcon -R -t shadow_t /srvfixfiles check /var/www /srv

fixfiles restore

restore stellt inkorrekte Labels wieder her

Beispiel
fixfiles restore /var/www /srv/app

fixfiles relabel

relabel ist für ein vollständiges Relabeling des gesamten Dateisystems vorgesehen

  • Das Werkzeug schlägt vor, den Inhalt von /tmp zu löschen
  • Anschließend werden alle inkorrekten Dateilabels so korrigiert, dass sie den installierten file_contexts entsprechen
Beispiel
fixfiles relabel

fixfiles onboot

onboot führt das Relabeling nicht sofort aus, sondern bereitet das System so vor, dass das Relabeling beim nächsten Systemstart erfolgt

fixfiles onboot

Optionen

Wichtige Optionen
Unix Beschreibung
-F (Force) Setzt den Kontext auch bei Dateien mit customizable types zwangsweise zurück
-f (force clear) Leert die temporären Verzeichnisse /tmp und /var/tmp automatisch vor Beginn der Ausführung, ohne interaktive Rückfragen
  • Das ist besonders nützlich für Automatisierungsskripte
-C PREVIOUS_FILECONTEXT (Compare) Vergleicht einen alten file_contexts-Stand mit dem aktuellen und stellt Kontexte nur dort wieder her, wo dies erforderlich ist
-N "YYYY-MM-DD HH:MM" (Newer) Beschränkt die Verarbeitung auf Dateien, die nach dem angegebenen Zeitpunkt erstellt wurden
-B Im Modus restore werden nur Dateien berücksichtigt, die heute verändert wurden
  • Im Modus onboot schreibt derselbe Schalter das aktuelle Datum in /.autorelabel, wodurch das Relabeling beschleunigt werden kann
-M (Mounts) Führt vor dem Relabeling Bind-Mounts für Dateisysteme aus, sodass auch Kontexte von Objekten korrekt repariert werden können, über denen etwas eingehängt ist
-T nthreads (Threads) Konfiguriert die parallele Verarbeitung mit mehreren Threads oder deaktiviert diese bei -T 1
-l LOGPATH (Log) Leitet die gesamte Ausgabe, also sowohl Standardausgabe als auch Fehlermeldungen, in die angegebene Logdatei statt auf den Bildschirm um