SELinux (Security-Enhanced Linux) ist ein Mandatory Access Control (MAC) System, das vom NSA entwickelt wurde. Es ist der Standard für RHEL, CentOS und Fedora und bietet granulare Zugriffskontrolle.
Grundkonzepte
DAC vs. MAC
DAC (Discretionary Access Control):
- Traditionelle Unix-Berechtigungen
- Benutzer kontrolliert eigene Dateien
- Root hat uneingeschränkten Zugriff
MAC (Mandatory Access Control):
- Systemweite Sicherheitsrichtlinien
- Unabhängig von Dateieigentümer
- Auch Root wird eingeschränkt
SELinux-Komponenten
| Komponente | Beschreibung |
|---|
| Subject | Prozess, der auf etwas zugreift |
| Object | Datei, Port, Gerät |
| Policy | Regeln für erlaubte Aktionen |
| Context | Sicherheitslabel |
Security Context
# Format: user:role:type:level
system_u:object_r:httpd_sys_content_t:s0
user: SELinux-Benutzer (system_u, unconfined_u)
role: SELinux-Rolle (object_r, system_r)
type: SELinux-Typ (httpd_sys_content_t) - wichtigster Teil
level: MLS-Level (s0) - meist ignoriert
Modi und Status
SELinux-Modi
| Modus | Beschreibung |
|---|
| Enforcing | Richtlinien werden durchgesetzt |
| Permissive | Nur Logging, keine Blockierung |
| Disabled | SELinux deaktiviert |
Status prüfen
# Aktuellen Modus anzeigen
getenforce
# Detaillierter Status
sestatus
# Ausgabe:
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 33
Modus ändern
# Temporär zu Permissive
setenforce 0
# Temporär zu Enforcing
setenforce 1
# Permanent in /etc/selinux/config
SELINUX=enforcing
# oder
SELINUX=permissive
# oder
SELINUX=disabled
# Neustart nach Änderung erforderlich
reboot
Contexts verstehen
Datei-Contexts anzeigen
# Mit ls -Z
ls -Z /var/www/html/
# -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
# Prozess-Contexts
ps auxZ | grep httpd
# system_u:system_r:httpd_t:s0 apache 1234 0.0 httpd
Benutzer-Contexts
# Aktueller Benutzer
id -Z
# unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Type Enforcement
Wichtige Typen
# Webserver
httpd_sys_content_t # Statischer Web-Content
httpd_sys_rw_content_t # Beschreibbarer Content
httpd_sys_script_exec_t # CGI-Skripte
# Datenbank
mysqld_db_t # MySQL-Datenbanken
postgresql_db_t # PostgreSQL-Datenbanken
# Benutzer
user_home_t # Home-Verzeichnisse
user_home_dir_t # Home-Verzeichnis selbst
# Temporär
tmp_t # /tmp Dateien
var_log_t # Log-Dateien
Context ändern
# Temporär (bis Relabeling)
chcon -t httpd_sys_content_t /var/www/html/datei.html
# Rekursiv
chcon -R -t httpd_sys_content_t /var/www/html/
# Original wiederherstellen
restorecon /var/www/html/datei.html
# Rekursiv wiederherstellen
restorecon -Rv /var/www/
Permanent ändern
# Regel hinzufügen
semanage fcontext -a -t httpd_sys_content_t "/srv/web(/.*)?"
# Regel anwenden
restorecon -Rv /srv/web/
# Regeln anzeigen
semanage fcontext -l | grep /srv/web
Booleans
Was sind Booleans?
Booleans sind Schalter zum Aktivieren/Deaktivieren
von SELinux-Funktionen ohne Policy-Änderung.
Booleans anzeigen
# Alle Booleans
getsebool -a
# Bestimmte Booleans
getsebool httpd_can_network_connect
# Mit Beschreibung
semanage boolean -l | grep httpd
Booleans ändern
# Temporär
setsebool httpd_can_network_connect on
# Permanent
setsebool -P httpd_can_network_connect on
# Mehrere gleichzeitig
setsebool -P httpd_can_network_connect=1 httpd_can_sendmail=1
Wichtige Booleans
# Webserver
httpd_can_network_connect # Apache kann Netzwerkverbindungen herstellen
httpd_can_network_connect_db # Apache kann zu DB verbinden
httpd_can_sendmail # Apache kann Mails senden
httpd_enable_homedirs # Apache kann Home-Dirs servieren
httpd_use_nfs # Apache kann NFS nutzen
# Samba
samba_enable_home_dirs # Samba kann Home-Dirs teilen
samba_export_all_ro # Samba kann alles lesen
samba_export_all_rw # Samba kann alles schreiben
# FTP
ftpd_anon_write # FTP anonymes Schreiben
ftpd_full_access # FTP voller Zugriff
# Allgemein
allow_user_exec_content # User können Content ausführen
Ports verwalten
Port-Contexts anzeigen
# Alle definierten Ports
semanage port -l
# HTTP-Ports
semanage port -l | grep http
# http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
Port hinzufügen
# Port 8080 für HTTP erlauben
semanage port -a -t http_port_t -p tcp 8080
# Port ändern
semanage port -m -t http_port_t -p tcp 8080
# Port entfernen
semanage port -d -t http_port_t -p tcp 8080
Häufige Port-Typen
http_port_t # Webserver
ssh_port_t # SSH
smtp_port_t # Mail
mysql_port_t # MySQL
postgresql_port_t # PostgreSQL
Troubleshooting
AVC Denials finden
# Audit-Log durchsuchen
ausearch -m avc -ts recent
# Mit sealert analysieren
sealert -a /var/log/audit/audit.log
# Journal durchsuchen
journalctl -t setroubleshoot
Denial verstehen
# Beispiel-Denial:
type=AVC msg=audit(1234567890.123:456): avc: denied { read }
for pid=1234 comm="httpd" name="index.html" dev="sda1" ino=123456
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:user_home_t:s0
tclass=file permissive=0
# Erklärung:
# httpd (httpd_t) wurde das Lesen (read)
# einer Datei (user_home_t) verweigert
Lösung finden
# setroubleshoot-Vorschläge
sealert -a /var/log/audit/audit.log
# audit2why für Erklärung
ausearch -m avc -ts recent | audit2why
# audit2allow für Lösungsvorschläge
ausearch -m avc -ts recent | audit2allow -M mypol
Module erstellen
Mit audit2allow
# Denials sammeln
ausearch -m avc -ts today | audit2allow -M meineapp
# Modul installieren
semodule -i meineapp.pp
# Modul prüfen
semodule -l | grep meineapp
Manuelles Modul
# meineapp.te erstellen
policy_module(meineapp, 1.0)
require {
type httpd_t;
type user_home_t;
class file { read open getattr };
}
allow httpd_t user_home_t:file { read open getattr };
# Kompilieren und installieren
checkmodule -M -m -o meineapp.mod meineapp.te
semodule_package -o meineapp.pp -m meineapp.mod
semodule -i meineapp.pp
Modul entfernen
semodule -r meineapp
Praktische Szenarien
Webserver mit Custom-Verzeichnis
# Problem: Apache kann /srv/web nicht lesen
# 1. Context prüfen
ls -Zd /srv/web
# drwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /srv/web
# 2. Richtigen Context setzen
semanage fcontext -a -t httpd_sys_content_t "/srv/web(/.*)?"
restorecon -Rv /srv/web
# 3. Prüfen
ls -Zd /srv/web
# drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /srv/web
Webserver mit Datenbankzugriff
# Problem: PHP-App kann nicht zu MySQL verbinden
# 1. Boolean prüfen
getsebool httpd_can_network_connect_db
# httpd_can_network_connect_db --> off
# 2. Boolean aktivieren
setsebool -P httpd_can_network_connect_db on
Nicht-Standard-Port
# Problem: Service läuft auf Port 8443
# 1. Port-Context prüfen
semanage port -l | grep 8443
# 2. Port hinzufügen
semanage port -a -t http_port_t -p tcp 8443
# Falls bereits belegt:
semanage port -m -t http_port_t -p tcp 8443
Samba Home-Verzeichnisse
# Problem: Samba kann Home-Dirs nicht teilen
# 1. Boolean aktivieren
setsebool -P samba_enable_home_dirs on
# 2. Falls eigenes Verzeichnis
semanage fcontext -a -t samba_share_t "/shares(/.*)?"
restorecon -Rv /shares
setroubleshoot
# Installation
dnf install setroubleshoot setroubleshoot-server
# Service
systemctl enable --now setroubleshootd
# GUI
sealert -b # Browser-Interface
# Wichtige Tools
semanage # Verwalten von Contexts, Ports, Booleans
restorecon # Contexts wiederherstellen
chcon # Contexts temporär ändern
getsebool # Booleans anzeigen
setsebool # Booleans setzen
semodule # Module verwalten
seinfo # Policy-Informationen
sesearch # Policy durchsuchen
Best Practices
Nicht deaktivieren
# Schlecht: SELinux deaktivieren
# SELINUX=disabled
# Besser: Permissive für Debugging
setenforce 0
# Problem lösen
setenforce 1
Contexts richtig setzen
# Schlecht: chcon verwenden
chcon -t httpd_sys_content_t /var/www/custom
# Besser: semanage + restorecon
semanage fcontext -a -t httpd_sys_content_t "/var/www/custom(/.*)?"
restorecon -Rv /var/www/custom
Dokumentieren
# Änderungen dokumentieren
semanage fcontext -l -C # Custom file contexts
semanage port -l -C # Custom ports
semanage boolean -l -C # Custom booleans
Zusammenfassung
| Befehl | Funktion |
|---|
getenforce | Modus anzeigen |
setenforce | Modus temporär ändern |
sestatus | Detaillierter Status |
ls -Z | Context anzeigen |
chcon | Context temporär ändern |
restorecon | Context wiederherstellen |
semanage fcontext | Context permanent ändern |
getsebool | Boolean anzeigen |
setsebool -P | Boolean permanent ändern |
semanage port | Ports verwalten |
audit2allow | Module aus Denials erstellen |
| Modus | Beschreibung |
|---|
| Enforcing | Regeln durchsetzen |
| Permissive | Nur loggen |
| Disabled | Deaktiviert |
| Typ | Verwendung |
|---|
| httpd_sys_content_t | Web-Content (nur lesen) |
| httpd_sys_rw_content_t | Web-Content (schreiben) |
| samba_share_t | Samba-Freigaben |
| var_log_t | Log-Dateien |
Fazit
SELinux bietet robusten Schutz durch Mandatory Access Control. Die initiale Lernkurve mag steil sein, aber das label-basierte System ist sehr mächtig. Für die meisten Probleme reichen Context-Anpassungen und Booleans. Die Troubleshooting-Tools (sealert, audit2allow) helfen bei der Diagnose. Statt SELinux zu deaktivieren, sollten Sie den Permissive-Modus zum Debugging nutzen und die Probleme gezielt lösen.