Linux System Administration

Security Hardening: Fläche, Policy-Schicht, Nachweis

Ein Dienst kann eine Datei nicht lesen — Eigentümer und Rechte stimmen nachweislich. Ein anderer lief monatelang und bricht nach einer Wiederherstellung aus der Sicherung, obwohl sich nichts geändert hat. Und beim nächsten Audit lässt sich nicht belegen, dass die beschlossene Härtung überhaupt aktiv ist. Alle drei Fälle haben mit derselben Sache zu tun: Auf einem gehärteten Linux-System entscheiden zwei unabhängige Schichten über jeden Zugriff. Dieses Modul zeigt dir, wie sie zusammenspielen, warum ein Etikett mit der Datei mitwandert — und wie man eine Verweigerung löst, ohne eine Schutzschicht abzuschalten.

Lehrtext · 12 Abschnitte · zuletzt geprüft: 2026-09-03

Härtung ist kein Zustand, sondern eine Kette von Entscheidungen

„Der Server ist gehärtet“ ist keine überprüfbare Aussage. Überprüfbar ist, welche Funktionen erreichbar sind, welche Schichten den Zugriff prüfen und was davon belegt werden kann. Vier Größen tragen dieses Modul:

Angriffsfläche
Was überhaupt erreichbar ist und läuft. Jede nicht benötigte Funktion ist vermeidbare Fläche.
Zugriffskontrolle
Zwei Schichten übereinander — die klassischen Rechte und darüber eine verbindliche Policy.
Härtung des Dienstes
Was ein Dienst noch anfassen kann, wenn er selbst kompromittiert wird.
Nachweis
Ob sich die Konfiguration und die tatsächlichen Zugriffe hinterher belegen lassen.

Die vierte wird am häufigsten vergessen und entscheidet im Ernstfall über alles: Eine Maßnahme, deren Wirkung niemand belegen kann, ist im Zweifel keine.

Angriffsfläche: was läuft, und warum

Der wirksamste Schritt ist auch der langweiligste: Dinge nicht laufen zu lassen. Ein Dienst, der nicht existiert, braucht keine Patches, keine Regeln und keine Überwachung.

Der Einstieg ist ss -tulpn: Es listet jeden Listener zusammen mit Adresse, Port, Prozess und Konto. Für jeden Eintrag gilt dieselbe Frage: gehört das zum Profil dieses Servers, und wer verantwortet es? Ein Listener ohne Antwort auf die zweite Hälfte ist kein Sicherheitsproblem, sondern erst einmal ein Inventarproblem — und das eine wird ohne das andere nicht lösbar.

Warum „intern erreichbar“ keine Grenze istEin häufiges Argument lautet, ein Dienst sei ja nur aus dem internen Netz erreichbar. Das setzt das interne Netz mit einer Vertrauensgrenze gleich — und genau diese Annahme trägt nicht mehr, sobald ein einziges Gerät darin kompromittiert ist. Erreichbare Funktion ist Angriffsfläche, unabhängig davon, wer heute in diesem Netz steht.

Der Preis dieser Disziplin ist ehrlich zu nennen: Vor jeder Abschaltung sind die Abhängigkeiten zu prüfen. Ein Dienst, den niemand kennt, wird gelegentlich doch gebraucht — und das merkt man dann im Wartungsfenster. Die Alternative, im Zweifel alles laufen zu lassen, kostet dafür dauerhaft.

Zwei Schichten Zugriffskontrolle

Auf einem gehärteten Linux-System entscheiden zwei Mechanismen über jeden Zugriff, und sie sind voneinander unabhängig. Beide müssen zustimmen.

Klassische Rechte (DAC)
Eigentümer, Gruppe, Modus. Wer eine Datei besitzt, kann ihre Rechte ändern — die Kontrolle liegt beim Benutzer.
Verbindliche Policy (MAC)
Eine systemweite Regel darüber, welcher Prozesstyp auf welchen Objekttyp zugreifen darf. Der Eigentümer kann sie nicht aufheben.

Mandatory Access ControlEine Zugriffskontrolle, deren Regeln zentral festgelegt sind und die ein Benutzer oder Dienst nicht für seine eigenen Dateien lockern kann. Auf Linux verbreitet als SELinux oder AppArmor.

Die praktische Folge: Ein Zugriff kann scheitern, obwohl Eigentümer und Modus nachweislich stimmen. Das ist kein Widerspruch und kein Fehler — es ist die zweite Schicht, die verweigert. Und sie hinterlässt dabei einen eigenen Eintrag im Auditlog, der genau das sagt.

Kurzcheck

Ein Dienst kann eine Datei nicht lesen. Eigentümer und Modus sind nachweislich korrekt, und im Auditlog steht eine Verweigerungsmeldung der Policy-Schicht. Was ist die richtige Reaktion?

  • Den Kontext der Datei prüfen und ihn auf den vorgesehenen Wert bringen.
  • Die Rechte erweitern, damit der Zugriff auf klassischer Ebene sicher erlaubt ist.
  • Die Policy-Schicht in den permissiven Modus versetzen, damit der Dienst wieder arbeiten kann.

Treffer. Genau. Die Meldung lokalisiert die verweigernde Schicht bereits — die Frage ist, ob die Datei den Kontext trägt, den die Policy für diesen Ort vorsieht. Nach einem Verschieben oder Wiederherstellen ist das oft nicht der Fall.

Die drei Modi — und warum der mittlere so nützlich ist

enforcing
Die Policy wird durchgesetzt: Verstöße werden verweigert und protokolliert. Der Zielzustand.
permissive
Die Policy ist geladen, Verstöße werden erlaubt, aber protokolliert. Man sieht genau, was blockiert würde.
disabled
Der größte Teil der Funktion ist abgeschaltet, die Policy wird nicht geladen. Kein Schutz und keine Information.

Der mittlere Modus ist das eigentlich wertvolle Werkzeug und wird am seltensten genutzt. Er beantwortet vor einer Umstellung die Frage, die sonst niemand beantworten kann: Was genau würde brechen? Man lässt eine Anwendung darin einen typischen Betriebstag laufen, sammelt die Verweigerungen und modelliert daraus die nötigen Ausnahmen — bevor sie im Betrieb stören.

Der Unterschied, der im Incident zähltPermissiv und abgeschaltet werden im Alltag oft gleichgesetzt. Sie sind es nicht: Im permissiven Modus hast du weiterhin die Meldungen. Wer im Störungsfall auf permissiv wechselt, kann danach nachlesen, was die Policy verweigert hätte, und die Ausnahme gezielt bauen. Wer abschaltet, hat den Dienst wieder — und keine einzige Information darüber, warum er stand.

Der Modus steht in /etc/selinux/config und gilt ab dem nächsten Start; getenforce zeigt den aktuellen, setenforce wechselt zur Laufzeit zwischen enforcing und permissive. Ein Wechsel von abgeschaltet zurück auf aktiv ist dabei kein reiner Schalter: Dateien, die in der Zwischenzeit entstanden sind, tragen möglicherweise keinen oder einen falschen Kontext und müssen neu ausgezeichnet werden.

Kontexte: was auf der Datei steht und was dort stehen soll

Bei SELinux trägt jede Datei ein Etikett — den Kontext — als erweitertes Dateiattribut. Die Policy entscheidet anhand dieses Etiketts, nicht anhand des Pfades. Und damit gibt es zwei Angaben, die auseinanderlaufen können.

Das tatsächliche Etikett
Was gerade an der Datei hängt. Es wandert mit ihr mit, wenn sie verschoben wird.
Die Regel in der Policy
Welches Etikett für diesen Ort vorgesehen ist. Sie beschreibt den Sollzustand.

restorecon gleicht die beiden ab: Es liest den vorgesehenen Kontext aus der Policy und schreibt ihn als erweitertes Dateiattribut an die Datei. ls -Z zeigt, was aktuell dransteht. Das ist der Standardgriff nach allem, was Dateien an einen neuen Ort bringt — Verschieben, Entpacken, Wiederherstellen aus einer Sicherung.

Das klassische FehlerbildEine Datei wird an ihren Zielort verschoben statt dort neu angelegt und behält dabei das Etikett ihres Ursprungsorts. Alles sieht richtig aus, die Rechte stimmen — und der Dienst kommt nicht heran. Wer stattdessen kopiert, bekommt in der Regel das für den Zielort vorgesehene Etikett. Derselbe Unterschied erklärt, warum eine wiederhergestellte Sicherung Zugriffsprobleme erzeugen kann, die vorher nicht existierten.

Soll ein Dienst dauerhaft an einem anderen als dem üblichen Ort arbeiten, reicht das Neuauszeichnen nicht: Dann muss die Regel selbst um diesen Ort ergänzt werden — mit semanage fcontext —, damit die Auszeichnung auch nach dem nächsten restorecon hält. Das ist der Unterschied zwischen einer Reparatur und einer Konfiguration.

Schalter statt eigener Policy

Eine eigene Policy zu schreiben klingt nach der sauberen Lösung und ist selten die erste. Für die häufigsten Fälle gibt es vorbereitete Schalter: getsebool -a listet sie, setsebool -P setzt einen dauerhaft. Sie weichen die Policy an einer definierten Stelle auf — etwa: darf dieser Diensttyp Netzverbindungen aufbauen, darf er auf Benutzerverzeichnisse zugreifen.

Der Vorteil ist erheblich: Ein Schalter ist von der Distribution vorgesehen, dokumentiert, überlebt Policy-Updates und lässt sich in einem Satz begründen. Eine selbst gebaute Regel muss gepflegt, bei jedem Update geprüft und von jemandem verstanden werden, der sie nicht geschrieben hat.

Die Reihenfolge bei einer VerweigerungErst prüfen, ob das Etikett stimmt — das ist der häufigste Fall. Dann, ob ein vorgesehener Schalter den Fall abdeckt. Erst danach über eine eigene Regel nachdenken. Und ganz am Ende, weit nach allem anderen, über das Abschalten der Schicht — als dokumentierte Ausnahme mit Ablaufdatum, nicht als Feierabendlösung.

Den Dienst selbst einsperren

Die verbindliche Policy schützt das System vor einem Dienst. Die zweite Hälfte derselben Idee kommt von der Dienstverwaltung selbst: Ein Dienst bekommt nur die Sicht auf das System, die er braucht — ProtectSystem=strict für schreibgeschützte Systembereiche, PrivateTmp=yes für ein eigenes /tmp, ProtectHome=yes gegen Benutzerverzeichnisse, NoNewPrivileges=yes gegen das Erlangen zusätzlicher Rechte.

Das ist unabhängig von SELinux oder AppArmor, wirkt sofort und kostet nichts außer Sorgfalt. Für einen Dienst, der aus dem Internet erreichbar ist, ist es der Unterschied zwischen einer Lücke im Dienst und einer Lücke im System.

Einen erreichbaren Dienst schrittweise einsperren

Szenario

Ein Webdienst nimmt Anfragen aus dem Internet entgegen. Er soll nur noch das anfassen können, was er tatsächlich braucht — ohne dass die Umstellung ihn im Betrieb bricht.

Anforderungen

  • Jede Einschränkung einzeln nachvollziehbar
  • Kein Ausfall durch eine zu weit gehende Einstellung
  • Der erreichte Zustand ist hinterher belegbar

Schritte

  1. Feststellen, welche Pfade der Dienst tatsächlich beschreibt — nicht raten, sondern im Betrieb beobachten und gegen systemd-analyze security <unit> halten, das die vorhandenen Einschränkungen bewertet.
  2. Die Einschränkungen einzeln über systemctl edit als Ergänzung setzen, nicht als Block aus einer Vorlage kopieren.
  3. Nach jeder einzelnen neu starten und die Dienstfunktion prüfen. Bricht etwas, ist die Ursache eindeutig.
  4. Benötigte Schreibpfade ausdrücklich wieder freigeben, statt die Einschränkung zurückzunehmen.
  5. Den erreichten Zustand mit systemctl cat aus der zusammengeführten Sicht dokumentieren — die Einzeldateien zeigen ihn nicht.

Merksatz: Einzeln gesetzt ist jede Einschränkung in Sekunden zuzuordnen. Als Block gesetzt kostet derselbe Fehler eine Stunde Ausschlussverfahren.

Der Nachweis: Konfiguration und Ereignisse

Härtung, die niemand belegen kann, ist im Zweifel nicht passiert. Der Nachweis hat zwei Seiten, und beide werden gebraucht.

Konfigurationsnachweis
Der Ist-Zustand gegen eine Vorgabe. Beantwortet: Ist das System so eingerichtet, wie beschlossen wurde?
Ereignisnachweis
Was tatsächlich passiert ist — auch das, was verweigert wurde. Beantwortet: Was hat jemand versucht?

Für die erste Seite gibt es veröffentlichte Vorgabenkataloge. Ihr Wert liegt weniger in der einzelnen Empfehlung als darin, dass jemand anders sie durchdacht und begründet hat — man muss nicht jede Einstellung selbst herleiten.

Ein Katalog ist kein ZielzustandEine Vorgabe blind anzuwenden bricht zuverlässig Anwendungen, und die Abweichung ist oft die richtige Entscheidung. Der Katalog liefert die Liste der Fragen; die Antworten hängen vom Serverprofil ab. Eine begründete und dokumentierte Abweichung ist besser als eine unbegründete Einhaltung — und vor allem prüfbar.

Die zweite Seite liefert die Auditinfrastruktur des Systems. Für Zugriffsverweigerungen der Policy-Schicht ist sie ohnehin die Quelle — ausearch -m AVC fördert genau diese Meldungen zutage; bei Vorfällen mit rechtlicher Relevanz ist sie oft der einzige Beleg, der später standhält. Ihre Aufbewahrung und ihr Ablageort gehören deshalb vor den Vorfall entschieden.

AppArmor: dasselbe Ziel, ein anderer Ansatz

Nicht jede Distribution setzt auf SELinux. Die verbreitete Alternative ist AppArmor, und der Unterschied ist für den Betrieb greifbar: Sie bindet ihre Regeln an Pfade statt an Etiketten.

SELinux
Regeln greifen am Etikett der Datei. Das Etikett wandert mit ihr — deshalb erzeugen Verschieben und Wiederherstellen Zugriffsprobleme, und deshalb gibt es restorecon.
AppArmor
Profile beziehen sich auf Pfade. Eine verschobene Datei fällt damit unter die Regel ihres neuen Orts — dafür ändert ein umbenannter Pfad die Bewertung.

Das Modell unterscheidet sich, die Betriebsregel nicht: Ein Profil kann ebenfalls beobachtend statt durchsetzend laufen, und auch hier ist der beobachtende Modus das Werkzeug zur Einführung. Wer beide Systeme kennt, erkennt dieselben drei Fragen — welche Schicht verweigert, wo ist die Regel definiert, gibt es einen vorgesehenen Anpassungspunkt.

Was du daraus mitnehmen kannstDie konkreten Befehle unterscheiden sich, die Denkweise nicht. Wer auf einem System die Frage „welche Schicht hat verweigert, und wo steht ihre Regel“ gelernt hat, ist auf dem anderen nach einer halben Stunde Dokumentation arbeitsfähig. Was nicht überträgt, sind die Befehle — und genau deshalb gehört vor jeder Änderung geklärt, welches der beiden Systeme auf diesem Host aktiv ist.

Der Zugang zum System als eigene Fläche

Ein Teil der Angriffsfläche ist kein Dienst, sondern der Verwaltungszugang selbst. Er verdient dieselbe Behandlung: so eng wie nötig, nachvollziehbar, und mit einem geprüften Ausnahmeweg.

Die Bausteine dafür stehen in anderen Modulen — individuelle Konten, eng geschnittene Privilegien, Schlüssel statt Passwörter, ein getesteter Notzugang. An dieser Stelle zählt vor allem, dass sie zusammen betrachtet werden: Eine harte Policy-Schicht auf einem Host, auf dem sich fünf Leute ein Administratorkennwort teilen, sichert das Falsche ab.

Die Reihenfolge, wenn die Zeit knapp istWer nur begrenzte Zeit für Härtung hat, bekommt in dieser Reihenfolge am meisten: erstens nicht benötigte Dienste abschalten, zweitens den Verwaltungszugang auf individuelle Konten mit Schlüsseln umstellen, drittens die erreichbaren Dienste einzeln einsperren. Die Policy-Schicht zu modellieren ist wertvoll und kommt danach — sie ist die tiefste Ebene und die aufwendigste.

Und ein letzter Punkt, der oft untergeht: Jede dieser Maßnahmen verändert das Verhalten des Systems im Fehlerfall. Ein eingesperrter Dienst scheitert anders, eine Policy-Verweigerung sieht aus wie ein Rechteproblem, ein abgeschalteter Dienst fehlt irgendwo. Härtung, die niemand im Betriebsteam kennt, erzeugt genau die Störungen, die sie verhindern sollte — deshalb gehört sie dokumentiert und übergeben, nicht nur umgesetzt.

Wenn Härtung ein Problem verursacht statt eines zu verhindern

Jede der bisherigen Maßnahmen kann selbst zur Störungsursache werden — und dann sieht sie nie danach aus. Drei Muster kehren so regelmäßig wieder, dass es sich lohnt, sie zu kennen.

Der Rechtefehler, der keiner ist
Ein Zugriff scheitert, Eigentümer und Modus stimmen. Ursache ist die Policy-Schicht oder eine Sandbox-Direktive. Erkennbar an einer Meldung im Auditlog, die nichts mit Dateirechten zu tun hat.
Der Dienst, der nach Monaten bricht
Ein Update bringt eine neue Policy oder ein neues Profil mit. Der Dienst lief seit dem Aufsetzen — geändert hat sich die Regel, nicht die Anwendung.
Die Einschränkung, die niemand kennt
Jemand hat gehärtet und es nicht übergeben. Das Betriebsteam sucht in der Anwendung, weil ihm die zusätzliche Schicht nicht bekannt ist.
Der Test, der alle drei erkenntWenn ein Zugriff scheitert und die Dateirechte nachweislich stimmen, ist die nächste Frage nicht „welches Recht fehlt“, sondern „welche zusätzliche Schicht ist hier aktiv“. Zwei Blicke beantworten das: die Verweigerungsmeldungen im Auditlog und die zusammengeführte Unit-Sicht mit ihren Einschränkungen. Beides dauert zusammen keine Minute und erspart regelmäßig Stunden.

Daraus folgt die vielleicht wichtigste organisatorische Regel dieses Moduls: Härtung, die im Betriebshandbuch nicht auftaucht, kostet später mehr, als sie schützt. Nicht weil sie falsch wäre — sondern weil die Menschen, die das System um drei Uhr nachts wieder zum Laufen bringen sollen, ihre Existenz nicht kennen und deshalb an der falschen Stelle suchen.

Die Reihenfolge beim Härten

Inventar: was läuft, was hört, wer verantwortet esNicht Benötigtes abschalten — der wirksamste SchrittDie verbleibenden Dienste einzeln einsperren und einzeln prüfenPolicy-Verweigerungen über Etikett und Schalter lösen, nicht über AbschaltenKonfiguration und Ereignisse belegbar machen
Was du mitnehmen solltestVier Sätze tragen dieses Modul. Zwei Schichten entscheiden über jeden Zugriff — passende Rechte und trotzdem verweigert ist kein Widerspruch. Permissiv ist nicht abgeschaltet — der eine Modus liefert weiter Meldungen, der andere nicht. Das Etikett wandert mit der Datei — Verschieben und Wiederherstellen erzeugen Zugriffsprobleme, die vorher nicht existierten. Und eine Maßnahme ohne Nachweis ist im Zweifel keine.

Jetzt anwenden

Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.

Zum Modul →
Quellen & Aktualität10 Primärquellen · zuletzt geprüft:
  1. 01man7.org/linux/man-pages/man8/selinux.8.html
  2. 02man7.org/linux/man-pages/man8/restorecon.8.html
  3. 03man7.org/linux/man-pages/man8/setsebool.8.html
  4. 04man7.org/linux/man-pages/man8/auditd.8.html
  5. 05man7.org/linux/man-pages/man8/ss.8.html
  6. 06freedesktop.org/software/systemd/man/latest/systemd.exec.html
  7. 07cisecurity.org/cis-benchmarks
  8. 08ubuntu.com/server/docs/apparmor
  9. 09man.openbsd.org/sshd_config
  10. 10sudo.ws/docs/man/sudoers.man