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änktSELinux-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 ignoriertModi 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: 33Modus ä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
rebootContexts 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 httpdBenutzer-Contexts
# Aktueller Benutzer
id -Z
# unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023Type 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-DateienContext ä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/webBooleans
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 httpdBooleans ä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=1Wichtige 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ührenPorts 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, 9000Port 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 8080Häufige Port-Typen
http_port_t # Webserver
ssh_port_t # SSH
smtp_port_t # Mail
mysql_port_t # MySQL
postgresql_port_t # PostgreSQLTroubleshooting
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 setroubleshootDenial 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) verweigertLö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 mypolModule 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 meineappManuelles 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.ppModul entfernen
semodule -r meineappPraktische 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/webWebserver 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 onNicht-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 8443Samba 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 /sharesTools
setroubleshoot
# Installation
dnf install setroubleshoot setroubleshoot-server
# Service
systemctl enable --now setroubleshootd
# GUI
sealert -b # Browser-InterfaceSELinux-Management-Tools
# 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 durchsuchenBest Practices
Nicht deaktivieren
# Schlecht: SELinux deaktivieren
# SELINUX=disabled
# Besser: Permissive für Debugging
setenforce 0
# Problem lösen
setenforce 1Contexts 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/customDokumentieren
# Änderungen dokumentieren
semanage fcontext -l -C # Custom file contexts
semanage port -l -C # Custom ports
semanage boolean -l -C # Custom booleansZusammenfassung
| 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.