Firewall & SELinux Integration (Artikel 095)
Das Zusammenspiel der Sicherheitsmechanismen unter RHEL. Erfahren Sie, wie Firewalld und SELinux gemeinsam den Netzwerkzugriff kontrollieren und wie Sie Port-Labeling verwalten.
# Defense in Depth: Das Duo Firewalld und SELinux
TL;DR / Management Summary In der RHEL-Welt ist ein offener Port in der Firewall nur die halbe Miete. Damit ein Dienst wirklich erreichbar ist, muss auch SELinux erlauben, dass der Prozess an diesen Port binden darf. Diese “Defense in Depth” Strategie sorgt dafür, dass ein kompromittierter Prozess nicht einfach willkürliche Ports öffnen kann, selbst wenn die Firewall offen wäre. In diesem Modul lernen wir, wie wir beide Systeme synchron halten.
# 1. Einführung & Architektur
Zwei Wächter, ein Ziel.
- Firewalld: Kontrolliert, welche Pakete vom Netzwerk zum Kernel durchgelassen werden (Externer Schutz).
- SELinux: Kontrolliert, welcher Prozess welche Ports öffnen (bind) darf (Interner Schutz).
# Der Zugriffs-Check (Mermaid)
graph TD
A[Incoming Packet: Port 8080] --> B{Firewalld Check}
B -->|Blocked| C[Drop Packet]
B -->|Allowed| D{Kernel: Process Bind Check}
D --> E{SELinux: Is port 8080 allowed for this type?}
E -->|No| F[Deny Bind - Service fails to start]
E -->|Yes| G[Success: Application receives Data]
# 2. SELinux Port-Labeling
Dem Kernel sagen, was erlaubt ist.
SELinux nutzt Typen für Ports (z.B. http_port_t). Ein Webserver darf nur an Ports binden, die dieses Label tragen.
# Liste der erlaubten Ports anzeigen
sudo semanage port -l | grep http_port_t
# Output: http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
# Einen neuen Port hinzufügen
Wenn Ihr Webserver auf Port 8080 lauschen soll, dieser aber nicht in der Liste steht:
sudo semanage port -a -t http_port_t -p tcp 8080
# 3. Synchronisation: Ein Praxis-Beispiel
Den Dienst freischalten.
Szenario: Ein SSH-Dämon soll auf Port 2222 laufen.
# Schritt 1: Firewall öffnen
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
# Schritt 2: SELinux Port labeln
sudo semanage port -a -t ssh_port_t -p tcp 2222
# Schritt 3: Dienst konfigurieren & starten
Erst jetzt wird sshd erfolgreich auf Port 2222 starten.
# 4. Day-2 Operations: Troubleshooting
Wer blockiert gerade?
# Der klassische Fehler
Symptom: systemctl start nginx schlägt fehl. In den Nginx-Logs steht bind() to 0.0.0.0:8888 failed (13: Permission denied). Die Firewall ist offen.
Ursache: SELinux kennt Port 8888 nicht als Web-Port.
Lösung: sudo semanage port -a -t http_port_t -p tcp 8888.
# 5. “War Stories” aus der Praxis
Fehlersuche auf Experten-Niveau.
# Story 1: “Der hängende Datenbank-Connect”
Symptom: Die Firewall erlaubt Zugriff von der App zur DB (Port 5432). Die DB lauscht. Trotzdem meldet die App “Connection Refused”.
Ursache: Der App-Server (Typ httpd_t) darf laut SELinux-Boolean httpd_can_network_connect_db keine Netzwerkverbindungen aufbauen.
Lösung: setsebool -P httpd_can_network_connect_db on. Hier greift nicht das Port-Labeling, sondern die Prozess-Berechtigung.
# Story 2: “Port-Konflikte bei SELinux”
Symptom: semanage port -a schlägt fehl mit “Port already defined”.
Ursache: Der Port ist bereits einem anderen Dienst zugeordnet (z.B. Port 8080 gehört oft zu http_cache_port_t).
Lösung: Nutzen Sie -m (modify) statt -a (add), um das Label zu ändern, oder nutzen Sie einen anderen Port.
# 6. Fazit & Empfehlung
- Reihenfolge: Öffnen Sie erst den Port in der Firewall, dann das Label in SELinux.
- Best Practice: Nutzen Sie immer
semanage port -l, bevor Sie einen Dienst auf einen Non-Standard-Port umstellen. - Logging: Bei Fehlern hilft
ausearch -m AVC -ts recent.
# Anhang: Cheatsheet
| Aufgabe | Befehl |
|---|---|
| Alle Port-Labels listen | semanage port -l |
| Port-Label hinzufügen | semanage port -a -t <typ> -p <proto> <port> |
| Port-Label ändern | semanage port -m -t <typ> -p <proto> <port> |
| Port-Label löschen | semanage port -d -p <proto> <port> |
| Firewall Port öffnen | firewall-cmd --add-port=<port>/<proto> |