SELinux Einführung
Prinzipien
SELinux (Security Enhanced Linux) ist ein System mit Mandatory Access Control, das auf der LSM-Schnittstelle (Linux Security Modules) von Linux aufbaut. In der Praxis befragt der Kernel SELinux vor jedem Systemaufruf, um herauszufinden, ob der Prozess autorisiert ist, den jeweiligen Vorgang auszuführen.
SELinux verwendet einen Satz von Regeln - in ihrer Gesamtheit als Policy bezeichnet - um Vorgänge zu autorisieren oder zu verbieten. Diese Regeln sind schwierig zu erstellen. Glücklicherweise werden zwei Standardregelwerke (targeted und strict) bereitgestellt, die den Großteil der Konfigurierungsarbeit entbehrlich machen.
Mit SELinux ist die Verwaltung der Berechtigungen grundsätzlich verschieden von traditionellen Unix-Systemen. Die Berechtigungen eines Prozesses hängen von seinem Sicherheitskontext ab. Der Kontext wird von der Identität des Benutzers bestimmt, der den Prozess gestartet hat, sowie von der Rolle und der Domain, die dem Benutzer zu dieser Zeit übertragen waren. Die Berechtigungen hängen tatsächlich von der Domain ab, aber die Übergänge zwischen den Domains werden von den Rollen kontrolliert. Und schließlich hängen die möglichen Übergänge zwischen den Rollen von der Identität ab.
Sicherheitskontexte und Unix-Nutzer
Konkret bekommt der Nutzer während der Anmeldung einen Standard-Sicherheitskontext zugewiesen (in Abhängigkeit von den Rollen, die er bestätigen können soll). Dies bestimmt die geltende Domain und damit auch die Domain, der alle neuen Unterprozesse zugeordnet werden. Wenn man die geltende Rolle und die ihr zugeordnete Domain ändern will, muss man den Befehl newrole -r rolle_r -t domain_t aufrufen (normalerweise ist nur eine einzige Domain für eine bestimmte Rolle erlaubt, deshalb kann der Parameter -t häufig weggelassen werden). Dieser Befehl authentifiziert jemanden, indem er ihn auffordert, sein Passwort einzugeben. Dies hindert Programme daran, selbstständig ihre Rollen zu ändern. Derartige Änderungen sind nur möglich, wenn sie im SELinux-Regelwerk ausdrücklich erlaubt sind.
Offensichtlich gelten die Berechtigungen nicht für alle Objekte (Dateien, Verzeichnisse, Sockets, Geräte usw.). Sie können von Objekt zu Objekt unterschiedlich sein. Um dies zu erreichen, ist jedes Objekt einem Typ zugeordnet (dies wird als Kennzeichnung bezeichnet). Die Rechte einer Domain werden somit durch Sätze von Operationen ausgedrückt, die bei diesen Typen erlaubt sind oder nicht (und indirekt bei allen Objekten, die mit dem jeweiligen Typ gekennzeichnet sind).
- EXTRA Domains und Typen sind gleichwertig
Intern ist eine Domain nur ein Typ, jedoch ein Typ, der nur für Prozesse gilt. Daher tragen Domains das Suffix _t, genau wie Objekttypen.
Standardmäßig übernimmt ein Programm die Domain des Nutzers, der es gestartet hat, aber die normalen SELinux-Regeln erwarten, dass viele wichtige Programme in speziell für sie vorgesehenen Domains laufen. Um dies zu erreichen, werden diese ausführbaren Dateien mit einem fest zugeordneten Typ gekennzeichnet (zum Beispiel wird ssh mit ssh_exec_t gekennzeichnet und wenn das Programm startet, wechselt es selbstständig in die Domain ssh_t). Dieser automatische Vorgang des Domainwechsels ermöglicht es, jedem Programm nur die Berechtigungen zu gewähren, die es benötigt. Dies ist ein wesentliches Prinzip von SELinux.
Selbstständige Übergänge zwischen Domains
IN DER PRAXIS Den Sicherheitskontext finden
Um in einer Konsole den aktuellen Sicherheitskontext festzustellen, kann man den Befehl id -Z aufrufen.
- id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 If you receive a message saying id: --context (-Z) works only on an SELinux-enabled kernel instead, then you need to enable SELinux first by running selinux-activate and rebooting.
Um den Sicherheitskontext eines bestimmten Prozesses festzustellen, kann die Option Z des Befehls ps verwendet werden.
- ps axZ | grep vstfpd
system_u:system_r:ftpd_t:s0 2094 ? Ss 0:00 /usr/sbin/vsftpd
Das erste Feld enthält durch Doppelpunkte getrennt die Identität, die Rolle, die Domain und die MCS-Stufe. Die MCS-Stufe (Multi-Category Security) ist ein Parameter, der beim Aufbau einer Regel zum Schutz der Vertraulichkeit eingreift, die den Zugriff auf Dateien in Abhängigkeit von ihrer Sensibilität regelt. Dieses Leistungsmerkmal wird in diesem Buch nicht erläutert.
Um schließlich auch den Typ festzustellen, der einer Datei zugeordnet ist, kann man den Befehl ls -Z verwenden.
- ls -Z test /usr/bin/ssh
unconfined_u:object_r:user_home_t:s0 test system_u:object_r:ssh_exec_t:s0 /usr/bin/ssh
Man sollte beachten, dass die Identität und die Rolle, die einer Datei zugewiesen sind, keine besondere Bedeutung haben (sie werden nie benutzt), aber aus Gründen der Einheitlichkeit wird allen Objekten ein vollständiger Sicherheitskontext zugeordnet.
SELinux einrichten
Die Unterstützung von SELinux ist in den von Debian bereitgestellten Standard-Kerneln enthalten. Die Kernprogramme von Unix unterstützen SELinux ohne Änderungen. Es ist daher recht einfach, SELinux zu aktivieren.
The apt install selinux-basics selinux-policy-defaulti auditd command will automatically install the packages required to configure an SELinux system.
Das Paket selinux-policy-default enthält einen Satz von Standardregeln. Standardmäßig beschränkt dieses Regelwerk nur den Zugang für einige besonders gefährdete Dienste. Die Nutzersitzungen sind nicht eingeschränkt und es ist daher unwahrscheinlich, dass SELinux legitime Nutzeraktionen blockieren würde. Dieses erhöht jedoch die Sicherheit von Systemdiensten, die auf dem Rechner laufen. Um ein Regelwerk einzurichten, das den alten „strengen“ Regeln entspricht, müssen Sie nur das Modul unconfined deaktivieren (die Modulverwaltung wird in diesem Kapitel ausführlich beschrieben).
Sobald das Regelwerk installiert ist, sollten Sie alle verfügbaren Dateien kennzeichnen (das heißt, sie einem Typ zuzuordnen). Dieser Vorgang muss mit dem Befehl fixfiles relabel von Hand gestartet werden.
Das SELinux-System ist nun einsatzbereit. Um es zu aktivieren, sollten Sie den Parameter selinux=1 security=selinux zum Linux-Kernel hinzufügen. Der Parameter audit=1 aktiviert bei SELinux das Protokollieren, durch das alle unterbundenen Vorgänge aufgezeichnet werden. Schließlich bringt der Parameter enforcing=1 das Regelwerk zur Anwendung: ohne ihn läuft SELinux in seinem standardmäßigen permissive-Modus, bei dem unterbundene Vorgänge zwar protokolliert, aber dennoch ausgeführt werden. Sie sollten daher die Konfigurationsdatei des GRUB-Bootloaders anpassen, indem Sie die gewünschten Parameter anhängen. Ein einfacher Weg, dies zu tun, besteht darin, die Variable GRUB_CMDLINE_LINUX in der Datei /etc/default/grub zu ändern und dann den Befehl update-grub auszuführen. SELinux ist dann nach einem Neustart aktiv.
Es sei darauf hingewiesen, dass das Skript selinux-activate diese Vorgänge automatisiert und das Kennzeichnen der Dateien beim nächsten Rechnerstart erzwingt (wodurch vermieden wird, dass neue nicht gekennzeichnete Dateien erstellt werden, während SELinux noch nicht aktiv ist und das Kennzeichnen noch andauert).
Ein SELinux-System verwalten
Das SELinux-Regelwerk ist ein modularer Satz von Regeln und mit seiner Installierung werden automatisch alle relevanten Module entsprechend den bereits installierten Diensten erkannt und aktiviert. Das System ist hierdurch sofort funktionsfähig. Wenn jedoch ein Dienst später als das SELinux-Regelwerk installiert wird, müssen Sie in der Lage sein, das entsprechende Modul manuell zu aktivieren. Hierzu dient der Befehl semodule. Darüber hinaus müssen Sie in der Lage sein, die Rollen festzulegen, die jeder Nutzer bestätigen kann. Dies geschieht mit dem Befehl semanage.
Diese beiden Befehle können somit dazu benutzt werden, die aktuelle SELinux-Konfiguration, die in /etc/selinux/default/ gespeichert ist, zu ändern. Im Gegensatz zu anderen Konfigurationsdateien, die Sie in /etc/ finden, dürfen diese Dateien nicht manuell verändert werden. Sie sollten hierzu die für diesen Zweck vorgesehenen Programme verwenden.
WEITERE SCHRITTE Weitere Unterlagen
Da die NSA keine offiziellen Unterlagen bereitstellt, hat die Gemeinschaft zum Ausgleich ein Wiki eingerichtet. Es bündelt viele Informationen, jedoch müssen Sie sich bewusst sein, dass die meisten SELinux-Mitwirkenden Fedora-Benutzer sind (bei dem SELinux standardmäßig aktiviert ist). Die Dokumentation neigt daher dazu, sich vor allem mit dieser Distribution zu beschäftigen. → https://selinuxproject.org You should also have a look at the dedicated Debian wiki page. → https://wiki.debian.org/SELinux
SELinux-Module verwalten
Verfügbare SELinux-Module sind im Verzeichnis /usr/share/selinux/default/ gespeichert. Um eines dieser Module in der aktuellen Konfiguration zu aktivieren, sollten Sie den Befehl semodule -i Modul.pp.bz2 benutzen. Die Erweiterung pp.bz2 steht für policy package (komprimiert mit bzip2).
Das Entfernen eines Moduls aus der aktuellen Konfiguration erfolgt mit semodule -r module. Letztendlich listet der Befehl semodule -l die aktuell installierten Module auf.
Es gibt auch deren Versionsnummern aus. Module können selektiv mit semodul -e aktiviert und mit semodul -d deaktiviert werden.
- semodule -i /usr/share/selinux/default/abrt.pp.bz2
libsemanage.semanage_direct_install_info: abrt module will be disabled after install as there is a disabled instance of this module present in the system.
- semodule -l
accountsd acct [...]
- semodule -e abrt
- semodule -d accountsd
- semodule -l
abrt acct [...]
- semodule -r abrt
libsemanage.semanage_direct_remove_key: abrt module at priority 100 is now active.
semodule lädt die neue Konfiguration unmittelbar, es sei denn, Sie verwenden seine Option -n. Es sei darauf hingewiesen, dass das Programm standardmäßig auf die aktuelle Konfiguration wirkt (die unter der Variablen SELINUXTYPE in der Datei /etc/selinux/config angegeben ist), aber Sie können eine andere ändern, indem Sie sie mit der Option -s vorgeben.
Identitäten verwalten
Jedes Mal, wenn sich ein Benutzer anmeldet, wird ihm eine SELinux-Identität zugewiesen. Diese bestimmt die Rollen, die er bestätigen kann. Diese beiden Zuordnungen (des Benutzers zur Identität und der Identität zu den Rollen) können mit dem Befehl semanage konfiguriert werden.
You should definitely read the semanage(8) manual page. All the managed concepts have their own manual page; for instance, semanage-login(8). Even if the command's syntax tends to be similar for all the concepts which are managed, it is recommended to read its manual page. You will find common options to most subcommands: -a to add, -d to delete, -m to modify, -l to list, and -t to indicate a type (or domain).
semanage login -l führt die aktuellen Zuordnungen zwischen Benutzerkennungen und SELinux-Identitäten auf. Benutzer, die keinen ausdrücklichen Eintrag haben, erhalten die Identität, die im Eintrag __default__ angegeben ist. Der Befehl semanage login -a -s user_u benutzer ordnet die Identität user_u dem angegebenen Benutzer zu. Schließlich entfernt der Befehl semanage login -d benutzer den Zuordnungseintrag, der an diesen Benutzer vergeben war.
- semanage login -a -s user_u rhertzog
- semanage login -l
Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * rhertzog user_u s0 * root unconfined_u s0-s0:c0.c1023 *
- semanage login -d rhertzog
semanage user -l führt die Zuordnungen zwischen den SELinux-Benutzeridentitäten und den erlaubten Rollen auf. Um eine neue Identität hinzuzufügen, ist es erforderlich, sowohl die entsprechenden Rollen als auch ein kennzeichnendes Präfix festzulegen, das dazu benutzt wird, einem Typ persönliche Dateien (/home/benutzer/*) zuzuordnen. Als Präfix muss user, staff oder sysadm gewählt werden. Das Präfix „staff“ ergibt Dateien des Typs „staff_home_dir_t“. Das Erstellen einer neuen SELinux-Benutzeridentität geschieht mit dem Befehl semanage user -a -R rollen -P präfix identität. Schließlich kann eine SELinux-Benutzeridentität mit dem Befehl semanage user -d identität entfernt werden.
- semanage user -a -R 'staff_r user_r' -P staff test_u
- semanage user -l
Labeling MLS/ MLS/
SELinux User Prefix MCS Level MCS Range SELinux Roles
root sysadm s0 s0-s0:c0.c1023 staff_r sysadm_r system_r
staff_u staff s0 s0-s0:c0.c1023 staff_r sysadm_r
sysadm_u sysadm s0 s0-s0:c0.c1023 sysadm_r
system_u user s0 s0-s0:c0.c1023 system_r
test_u staff s0 s0 staff_r user_r
unconfined_u unconfined s0 s0-s0:c0.c1023 system_r unconfined_r
user_u user s0 s0 user_r
*semanage user -d test_u
Dateikontexte, Ports und Boolesche Optionen verwalten
Jedes SELinux-Modul stellt einen Satz von Dateibezeichnungsregeln zur Verfügung, aber es ist auch möglich, eigene Bezeichnungsregeln hinzuzufügen, um einen speziellen Fall abzudecken. Wenn Sie zum Beispiel möchten, dass der Webserver in der Lage ist, Dateien innerhalb der /srv/www/-Dateihierarchie zu lesen, könnten Sie semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?" gefolgt von restorecon -R /srv/www/ ausführen. Der erste Befehl registriert die neue Bezeichnungsregel und der zweite gleicht die Dateitypen gemäß den derzeitigen Bezeichnungsregeln an.
Ebenso sind die TCP/UDP-Ports in einer Weise gekennzeichnet, die sicherstellt, dass nur die entsprechenden Daemons an ihnen Verbindungen annehmen können. Wenn Sie zum Beispiel möchten, dass der Web-Server am Port 8080 Verbindungen annehmen kann, sollten Sie den Befehl semanage port -m -t http_port_t -p tcp 8080 ausführen.
Some SELinux modules export Boolean options that you can tweak to alter the behavior of the default rules. The getsebool utility can be used to inspect those options (getsebool boolean displays one option, and getsebool -a them all). The setsebool boolean value command changes the current value of a Boolean option. The -P option makes the change permanent, it means that the new value becomes the default and will be kept across reboots. The example below grants web servers an access to home directories (this is useful when users have personal websites in ~/public_html/).
*getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
*setsebool -P httpd_enable_homedirs on
*getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
Die Regeln anpassen
Da das SELinux-Regelwerk modular ist, könnte es interessant sein, neue Module für (möglicherweise maßgefertigte) Anwendungen zu entwickeln, für die es diese noch nicht gibt. Diese neuen Module würden dann die Referenzrichtlinien ergänzen.
Zur Erstellung neuer Module werden die Pakete selinux-policy-dev und selinux-policy-doc benötigt. Letzteres enthält die Dokumentation der Standardregeln (/usr/share/doc/selinux-policy-doc/html/) und Beispieldateien, die als Vorlagen für die Erstellung neuer Module verwendet werden können. Installieren Sie diese Dateien und untersuchen Sie sie genauer:
$ cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile
$ cp /usr/share/doc/selinux-policy-doc/example.fc ./
$ cp /usr/share/doc/selinux-policy-doc/example.if ./
$ cp /usr/share/doc/selinux-policy-doc/example.te ./
Die Datei .te ist die wichtigste. Sie legt die Regeln fest. Die Datei .fc bestimmt die „Dateikontexte“, das heißt, die Typen, die den auf diese Module bezogenen Dateien zugeordnet sind. Die in der Datei .fc befindlichen Daten werden während des Dateikennzeichnungsschrittes benutzt. Schließlich legt die Datei .if die Schnittstelle der Module fest: es ist ein Satz „öffentlicher Funktionen“, die andere Module verwenden können, um ordnungsgemäß mit dem Modul, das Sie erstellen, zu interagieren.
Eine .fc-Datei schreiben
Das Lesen des unten stehenden Beispiels sollte genügen, um die Struktur einer derartigen Datei zu verstehen. Sie können reguläre Ausdrücke verwenden, um denselben Sicherheitskontext mehreren Dateien zuzuordnen oder auch einem ganzen Verzeichnisbaum.
Beispiel 14.2. beispiel.fc-Datei
# myapp executable will have:
# label: system_u:object_r:myapp_exec_t
# MLS sensitivity: s0
# MCS categories: <none>
/usr/sbin/myapp -- gen_context(system_u:object_r:myapp_exec_t,s0)
Eine .if-Datei schreiben
In unten stehendem Beispiel kontrolliert die erste Schnittstelle („myapp_domtrans“), wer die Anwendung ausführen kann. Die zweite („myapp_read_log“) gewährt Schreibzugriff auf die Protokolldateien der Anwendung.
Jede Schnittstelle muss einen gültigen Regelsatz erzeugen, der in eine .te-Datei eingegliedert werden kann. Sie sollten daher alle Typen, die Sie verwenden, festlegen (mit dem Makro gen_require) und Standardanweisungen benutzen, um Berechtigungen zu vergeben. Beachten Sie jedoch, dass Sie auch Schnittstellen benutzen können, die von anderen Modulen bereitgestellt werden. Der nächste Abschnitt gibt weitere Erläuterungen darüber, wie diese Berechtigungen ausgedrückt werden können.
Beispiel 14.3. beispiel.if-Datei
## <summary>Myapp example policy</summary>
## <desc>
##
## More descriptive text about myapp. The desc
## tag can also use p, ul, and ol
## html tags for formatting.
##
##
## This policy supports the following myapp features:
##
-
##
- Feature A ##
- Feature B ##
- Feature C ##