Kategorien: | Debian HowTos |
---|---|
Tags: | AppArmor Debian Linux Open Source Sicherheit Ubuntu |
Wie im vorausgegangenen Beitrag beschrieben erfolgt unter unixoiden Systemen die Rechtekontrolle traditionell nach dem Prinzip der Discretionary Access Control (DAC). Anwendungen und Dienste laufen unter einer bestimmten User- und Group-ID und erhalten die entsprechenden Zugriffsrechte auf Dateien und Ordner.
AppArmor implementiert für Linux, aufbauend auf den Linux Security Modules, eine sogenannte Mandatory Access Control: eine Zugriffskontrollstrategie mit der einzelnen Programmen bestimmte Rechte gewährt oder verweigert werden können. Diese Sicherheitsschicht existiert zusätzlich zur traditionellen DAC.
Seit Debian 10 buster ist AppArmor standardmäßig im Kernel enthalten und aktiviert. Die Pakete apparmor und apparmor-utils bringen Tools zur Erstellung und Pflege von AppArmor-Profilen mit.
Die beiden erwähnten Pakete bringen keine fertigen Profile, sondern lediglich die im vorigen Artikel erwähnten Abstractions mit: Sammlungen von Regeln, die in mehreren Profilen eingebunden werden können.
Manche Programme bringen ihre Profile in ihren Paketen selbst mit, andere enthalten Profile, wenn entsprechende Module nachinstalliert werden – zum Beispiel mod_apparmor
beim Apache Webserver.
Die Pakete apparmor-profiles und apparmor-profiles-extra enthalten AppArmor-Profile, die nach der Installation in den Verzeichnissen /etc/apparmor.d
(für erprobte Profile) beziehungsweise /usr/share/apparmor/extra-profiles
(für experimentelle Profile) zu finden sind. Diese Profile können als Grundlage für eigene Profile herangezogen werden.
Während für die meisten gängigen Serverdienste wie beispielsweise den Apache Webserver zumindest experimentelle Profile zur Verfügung stehen, ist für den nginx Webserver nichts zu finden. Dies ist jedoch nicht weiter tragisch, denn ein neues AppArmor-Profil ist mit Hilfe der apparmor-utils schnell erstellt.
Im Folgenden wird eine einfache Basisinstallation des nginx, die lediglich HTML-Dateien unter /var/www/html
über HTTP ausliefert, angenommen. Dabei liegt der Fokus vor allem auf der allgemeinen Herangehensweise, sich wiederholende Schritte werden also übersprungen.
Die geschilderte Herangehensweise lässt sich auf beliebige andere Programme übertragen. Um sich über die verwendeten Pfade und Dateien eines Programms zu informieren, kann dpkg
mit der Option -L
herangezogen werden, welche alle Pfade eines Pakets auflistet. Dabei ist zu beachten, dass hierfür möglicherweise mehrere Pakete befragt werden müssen, für nginx liefert das gleichnamige Paket kaum brauchbare Informationen; diese erhält man erst mit dem Paket nginx-common:
# dpkg -L nginx-common
Für die folgenden Schritte empfiehlt es sich zwei Terminals mit root-Rechten geöffnet zu haben.
Bevor der Webserver-Prozess zur Erstellung eines Profils beobachtet werden kann, müssen all seine laufenden Prozesse beendet werden:
# systemctl stop nginx
Sind alle Prozesse gestoppt, wird im zweiten Terminal aa-genprof
mit dem Pfad der Programmdatei des Webservers aufgerufen:
# aa-genprof /usr/sbin/nginx
Es erscheinen einige Informationen zum aktuellen Aufruf von aa-genprof
, darunter der Hinweis Profiling: /usr/sbin/nginx
, gefolgt von Please start the application to be profiled in another window and exercise its functionality now.
Um dem Folge zu leisten wird im ersten Terminalfenster der Webserver-Prozess wieder gestartet:
# systemctl start nginx
Bevor im zweiten Fenster die Option S
zum durchsuchen der Logdateien nach AppArmor-Events aufgerufen wird, sollte der Webserver einige Momente laufen, auch sollte er von einem Browser aus aufgerufen werden, damit möglichst alle üblichen Aktivitäten des Prozesses aufgezeichnet werden.
Ist dies geschehen, können mit einem Druck auf die Taste S
die Logdateien nach Events durchsucht werden:
[(S)can system log for AppArmor events] / (F)inish Reading log entries from /var/log/syslog. Updating AppArmor profiles in /etc/apparmor.d. Complain-mode changes:
Wurde ein Event gefunden, wird das betroffene Profil sowie die Aktion angezeigt, die von AppArmor aufgezeichnet wurde:
Profile: /usr/sbin/nginx Capability: dac_override Severity: 9 [1 - capability dac_override,] (A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
Hier fordert das Programm /usr/sbin/nginx
die Capability dac_override
an, die bereits im letzten Artikel beschrieben wurde. Sie ist für den Betrieb des Webservers unabdingbar und wird mittels Druck auf A
erlaubt. Alternativ kann die Anforderung mit D
verweigert oder mit I
ignoriert werden. Mit der Option Audit würde diese Anforderung auch weiterhin im laufenden Betrieb in der Logdatei aufgezeichnet.
Profile: /usr/sbin/nginx Capability: net_bind_service Severity: 8 [1 - #include <abstractions/nis>] 2 - capability net_bind_service,
Das nächste Event zeigt, dass der Prozess die Capability net_bind_service
anfordert, der benötigt wird, um einen Port mit einer Portnummer kleiner als 1024 zu öffnen.
Anders als bei der ersten Nachfrage gibt es hier zwei Möglichkeiten den Zugriff zukünftig zu erlauben: in der ersten Option werden Abstractions für NIS, den Network Information Service eingebunden. In dieser Abstraction, welche unter /etc/apparmor.d/abstractions/nis
zu finden ist, ist neben einer Regel, die den Zugriff auf Regelwerke für NIS erlaubt auch die Capability net_bind_service
aufgeführt.
Da der HTTP-Server jedoch keine NIS-Funktionalität mitbringt, reicht es lediglich die Capability zu erlauben. Mit einem Druck auf 2
und A
wird diese in das Profil übernommen.
Gleiches gilt für die in den folgenden Schritten vorgeschlagenen Abstractions für dovecot
und postfix
: hier genügt es lediglich die Capabilities setgid
und setuid
zu erlauben.
Manchmal kann die Bezeichnung der Abstractions etwas irreführend sein: so enthält die Abstraction nameservice
neben Regeln, welche neben dem lesenden Zugriff auf die üblichen Nameservice-Dateien wie passwd
oder hosts
erlauben auch solche Regeln, die den Netzwerkzugriff gestatten. Es lohnt also immer ein Blick in die jeweilige Datei unter /etc/apparmor.d/abstractions/
, ob sich das Einbinden der Abstraction lohnt.
Nachdem der Webserver-Prozess alle nötigen Capabilities erhalten hat, versucht er offenbar seine Fehler-Logdatei /var/log/nginx/log
mit Schreibrechten zu öffnen. Hier fällt auf, dass neben dem üblichen Allow, Deny und Ignore noch die Optionen Glob und Glob with Extension hinzugekommen sind.
Profile: /usr/sbin/nginx Path: /var/log/nginx/error.log New Mode: w Severity: 8 [1 - /var/log/nginx/error.log w,] (A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish
Bei Eingabe von E
wird der Liste ein weiterer Vorschlag hinzugefügt:
1 - /var/log/nginx/error.log w, [2 - /var/log/nginx/*.log w,]
Der Dateiname error.log
wurde durch einen Wildcard und die Endung .log
ersetzt. Diese Regel würde neben den Schreibrechten auf die Datei /var/log/nginx/error.log
beispielsweise auch solche auf die Datei /var/log/nginx/access.log
gewähren – das sind (mindestens) zwei Regeln zusammengefasst zu einer einzigen.
Diese Regeln würde für dieses Beispiel bereits ausreichen, möglicherweise sollen aber auch Dateien, welche nicht die Dateiendung .log
besitzen, im Verzeichnis /var/log
geschrieben werden dürfen. Durch Eingabe von G
wird der Liste noch ein weiterer Vorschlag hinzugefügt:
1 - /var/log/nginx/error.log w, 2 - /var/log/nginx/*.log w, [3 - /var/log/nginx/* w,]
Der Dateiname wurde nun durch einen einzelnen Wildcard ersetzt, der Prozess dürfte also beliebige Dateien in /var/log/nginx
mit Schreibrechten öffnen.
Wie bereits erwähnt werden durch die vorgeschlagenen Regeln ausschließlich Schreib-, jedoch keine Leserechte eingeräumt, selbst wenn die Zugriffsrechte der Datei mehr erlauben würden. Für Logdatei eines Webservers reichen die Schreibrechte jedoch völlig aus.
Im Folgenden verlangt nginx lesenden Zugriff auf verschiedene Konfigurationsdateien, zum Beispiel /etc/nginx/nginx.conf
. Diese befindet sich im Konfigurationsverzeichnis des nginx Webservers, in dem noch weitere Dateien liegen, die ebenfalls gelesen werden können sollen.
Profile: /usr/sbin/nginx Path: /etc/nginx/nginx.conf New Mode: owner r Severity: unknown [1 - owner /etc/nginx/nginx.conf r,]
Auch hier kann mit G
die Regel auf alle Dateien des Verzeichnisses /etc/nginx
erweitert werden.
1 - owner /etc/nginx/nginx.conf r, [2 - owner /etc/nginx/* r,]
Gleiches gilt für die Unterverzeichnisse des Konfigurationsverzeichnisses, diese können durch Globbing als /etc/nginx/*/
abgedeckt werden.
Einen Spezialfall für das Globbing stellen die in jenen Unterverzeichnissen enthaltenen Dateien dar:
Profile: /usr/sbin/nginx Path: /etc/nginx/sites-available/default New Mode: owner r Severity: unknown [1 - owner /etc/nginx/sites-available/default r,]
Nach zweifacher Eingabe von G
wird nach dem von oben bekannten Wildcard *
das Wildcard **
vorgeschlagen, welches, wie im vorherigen Artikel beschrieben, alle in Unterverzeichnissen (und deren Unterverzeichnissen) befindlichen Dateien abdeckt.
1 - owner /etc/nginx/sites-available/default r, 2 - owner /etc/nginx/sites-available/* r, [3 - owner /etc/nginx/** r,]
Die letzten Schritte enthielten außerdem alle das Attribut owner
: dieses bewirkt, dass eine Regel ausschließlich dann Anwendung findet, wenn der zugreifende Prozess auch Besitzer der Datei ist. Ist die Datei vorhanden, gehört jedoch jemand anderem, wird der Zugriff verweigert.
Es folgen noch einige weitere Pfade und Dateien wie /usr/share/nginx/modules-available/
, /run/nginx.pid
und /proc/sys/kernel/random/boot_id
, welche der nginx ebenfalls zum ordnungsgemäßen Betrieb benötigt. Die Vorgehensweise bleibt jedoch unverändert.
Sind alle Events durchlaufen schließt das Programm mit der Meldung:
= Changed Local Profiles = The following local profiles were changed. Would you like to save them? [1 - /usr/sbin/nginx] (S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
Die Optionen sind klar: mit S
werden Änderungen gespeichert, mit V
können diese vorher als Diff angeschaut werden. Das folgende Listing zeigt das im obigen Durchlauf erzeugte Profil.
include <tunables/global> profile nginx /usr/sbin/nginx { include <abstractions/base> include <abstractions/nameservice> capability dac_override, capability dac_read_search, capability setgid, capability setuid, /usr/sbin/nginx mr, /var/log/nginx/*.log w, /var/www/html/** r, owner /etc/nginx/* r, owner /etc/nginx/** r, owner /run/nginx.pid rw, owner /usr/share/GeoIP/*.mmdb r, owner /usr/share/nginx/modules-available/*.conf r, owner /var/cache/nginx/** rw, owner /var/lib/nginx/** rw, }
Nach dem Speichern der Änderungen kehrt aa-genprof
zu seinem Startbildschirm zurück. Hier könnte nun erneut in Logdateien nach Events gesucht oder aber das Programm mit F
beendet werden.
Das Programm endet mit der Meldung:
Setting /usr/sbin/nginx to enforce mode. Reloaded AppArmor profiles in enforce mode.
Das soeben erstellte Profil wurde also geladen und in den enforce-Modus versetzt. Das bedeutet, dass dem Programm nur noch im Profil erlaubte Zugriffe möglich sind, alle anderen Zugriffsversuche werden von AppArmor blockiert und im Syslog festgehalten.
Für simple Programme ist die Erstellung eines Profils damit beendet und AppArmor kann seine Arbeit verrichten; komplexere Programme hingegen werden im weiteren Verlauf bislang unbekanntes Verhalten zeigen, das vom bislang erstellten Profil unterbunden würde. Hier hilft es, das Profil mittels aa-complain
in den sogenannten complain-Modus zu schalten.
# aa-complain nginx
Zugriffe, welche über das bekannte Profil hinausgehen werden im complain-Modus grundsätzlich erlaubt, aber im Syslog festgehalten.
Feb 18 15:25:50 web01 kernel: [ 9908.611408] audit: type=1400 audit(1645197950.338:100): apparmor="ALLOWED" operation="open" profile="nginx" name="/srv/www/index.html" pid=4490 comm="nginx" requested_mask="r" denied_mask="r" fsuid=33 ouid=0
Im obigen Auszug aus dem Syslog wurde das Webroot-Verzeichnis auf dem Host web01
zu /srv/www
geändert, das vormals erstellte AppArmor-Profil jedoch nicht angepasst. Da sich das Profil nun im complain-Modus befindet wurde der Zugriff dennoch erlaubt: apparmor="ALLOWED"
; im enforce-Mode stünde dort ein DENIED
und der Zugriff würde verweigert.
An den übrigen Informationen ist gut zu erkennen, was passiert ist: der Prozess mit der Prozess-ID (pid) 4190
hat versucht die Datei /srv/www/index.html
(name) lesend (requested_mask) zu öffnen, was aufgrund des Profils (profile) nginx
jedoch untersagt wäre (denied_mask).
Sollte eine mit AppArmor abgesicherte Software also einmal nicht so funktionieren wie erwartet, lohnt zu allererst ein Blick ins Syslog!
Nach einiger Zeit werden sich dort einige Einträge befinden, die dann in das AppArmor-Profil übernommen werden sollen. Dafür wird das Programm aa-logprof
verwendet: es durchsucht das Syslog nach Einträgen und fragt in der Manier von aa-genprof
nach, ob und wie darauf Einträge im Profil erstellt werden sollen. Dieser Vorgang kann beliebig oft wiederholt werden.
Finden sich im Syslog keine weiteren Einträge mehr, Wurde das Profil genügend angepasst und kann mit aa-enforce
wieder in den enforce-Modus versetzt werden:
# aa-enforce nginx
Damit ist die grundlegende Erstellung eines einfachen AppArmor-Profils abgeschlossen und die Prozesse des nginx werden entsprechend der darin definierten Regeln kontrolliert und überwacht.
Ob AppArmor, Debian oder PostgreSQL: mit über 22+ Jahren an Entwicklungs- und Dienstleistungserfahrung im Open Source Bereich, kann die credativ GmbH Sie mit einem beispiellosen und individuell konfigurierbaren Support professionell begleiten und Sie in allen Fragen bei Ihrer Open Source Infrastruktur voll und ganz unterstützen.
Sie haben Fragen zu unserem Artikel oder würden sich wünschen, dass die Spezialisten von credativ sich eine andere Software ihrer Wahl angucken?
Dann schauen Sie doch vorbei und melden sich über unser Kontaktformular oder schreiben uns eine E-mail an info@credativ.de.
Die credativ GmbH ist ein herstellerunabhängiges Beratungs- und Dienstleistungsunternehmen mit Standort in Mönchengladbach. Seit dem erfolgreichen Merger mit Instaclustr 2021 ist die credativ GmbH das europäische Hauptquartier der Instaclustr Gruppe.
Die Instaclustr Gruppe hilft Unternehmen bei der Realisierung eigener Applikationen im großen Umfang dank Managed-Plattform-Solutions für Open Source Technologien wie zum Beispiel Apache Cassandra®, Apache Kafka®, Apache Spark™, Redis™, OpenSearch™, Apache ZooKeeper™, PostgreSQL® und Cadence.
Instaclustr kombiniert eine komplette Dateninfrastruktur-Umgebung mit praktischer Expertise, Support und Consulting um eine kontinuierliche Leistung und Optimierung zu gewährleisten. Durch Beseitigung der Komplexität der Infrastruktur, wird es Unternehmen ermöglicht, ihre internen Entwicklungs- und Betriebsressourcen auf die Entwicklung innovativer kundenorientierter Anwendungen zu geringeren Kosten zu konzentrieren. Zu den Kunden von Instaclustr gehören einige der größten und innovativsten Fortune-500-Unternehmen.
Kategorien: | Debian HowTos |
---|---|
Tags: | AppArmor Debian Linux Open Source Sicherheit Ubuntu |
über den Autor
zur Person
Jan arbeitet seit 2020 an Projekten des Support–Teams und der Internen IT, nachdem er bereits sein Praktikum im Rahmen seines Informatikstudiums bei credativ absolvierte und auch seine Bachelorarbeit zum Thema Einmalpasswörter, Zwei–Faktor–Authentisierung und OpenVPN bei credativ schrieb. Bereits zu Schulzeiten interessierte er sich für Freie Software, Netzwerke und Telekommunikation und richtete zusammen mit Mitschülern ein Internetcafé ein, auf dessen Server und Clients Debian GNU/Linux seinen Dienst verrichtete.