Product SiteDocumentation Site

14.4. Einführung in AppArmor

14.4.1. Prinzipien

AppArmor ist ein Mandatory Access Control System (MAC), das auf der LSM-Schnittstelle (Linux Security Modules) von Linux aufbaut. In der Praxis befragt der Kernel AppAmor vor jedem Systemaufruf, um herauszufinden, ob der Prozess autorisiert ist, den jeweiligen Vorgang auszuführen.
AppArmor wendet eine Reihe von Regeln (bekannt als "Profil") auf jedes Programm an. Das vom Kernel verwendete Profil hängt vom Installationspfad des ausgeführten Programms ab. Im Gegensatz zu SELinux (beschrieben in Abschnitt 14.5, „Einführung in SELinux“) sind die angewandten Regeln nicht vom Benutzer abhängig. Alle Benutzer haben die gleichen Regeln, wenn sie das gleiche Programm ausführen (aber die traditionellen Benutzerberechtigungen gelten weiterhin und können zu unterschiedlichem Verhalten führen!).
AppArmor-Profile werden in /etc/apparmor.d/ gespeichert und enthalten eine Liste von Zugriffskontrollregeln für Ressourcen, die jedes Programm verwenden kann. Die Profile werden mit dem Befehl apparmor_parser in den Kernel geladen. Jedes Profil kann entweder im Erzwingungs- oder im Beschwerdemodus geladen werden. Ersterer setzt die Richtlinie durch und meldet Verstöße, während Letzterer die Richtlinie nicht durchsetzt, aber dennoch die Systemaufrufe protokolliert, die abgelehnt worden wären.

14.4.2. AppArmor Profile einschalten und verwalten

AppArmor-Unterstützung ist in die von Debian bereitgestellten Standardkernel integriert. Das Aktivieren von AppArmor ist also nur eine Frage der Installation einiger Pakete und des Hinzufügens einiger Parameter zur Kernel-Befehlszeile:
# apt install apparmor apparmor-profiles apparmor-utils
[...]
# perl -pi -e 's,GRUB_CMDLINE_LINUX="(.*)"$,GRUB_CMDLINE_LINUX="$1 apparmor=1 security=apparmor",' /etc/default/grub
# update-grub
Nach einem Neustart ist AppArmor nun funktionsfähig und aa-status bestätigt das schnell:
# aa-status
apparmor module is loaded.
44 profiles are loaded.
9 profiles are in enforce mode.
   /usr/bin/lxc-start
   /usr/lib/chromium-browser/chromium-browser//browser_java
[...]
35 profiles are in complain mode.
   /sbin/klogd
[...]
3 processes have profiles defined.
1 processes are in enforce mode.
   /usr/sbin/libvirtd (1295) 
2 processes are in complain mode.
   /usr/sbin/avahi-daemon (941) 
   /usr/sbin/avahi-daemon (1000) 
0 processes are unconfined but have a profile defined.
Der Zustand jedes Profils kann zwischen Erzwingen und Beschweren mit Aufrufen von aa-enforce und aa-complain umgeschaltet werden, wobei als Parameter entweder der Pfad der ausführbaren Datei oder der Pfad zur Policy-Datei angegeben wird. Zusätzlich kann ein Profil mit aa-disable vollständig deaktiviert werden oder mit aa-audit in den Audit-Modus versetzt werden (um auch akzeptierte Systemaufrufe zu protokollieren).
# aa-enforce /usr/sbin/avahi-daemon
Setting /usr/sbin/avahi-daemon to enforce mode.
# aa-complain /etc/apparmor.d/usr.bin.lxc-start
Setting /etc/apparmor.d/usr.bin.lxc-start to complain mode.

14.4.3. Ein neues Profil erstellen

Obwohl die Erstellung eines AppArmor-Profils recht einfach ist, haben die meisten Programme keins. Dieser Abschnitt zeigt Ihnen, wie Sie ein neues Profil von Grund auf neu erstellen, indem Sie das Zielprogramm verwenden und AppArmor den Systemaufruf und die Ressourcen, auf die es zugreift, überwachen lassen.
Die wichtigsten Programme, die eingeschränkt werden sollen, sind die Programme, die mit dem Netzwerk verbunden sind, da diese die wahrscheinlichsten Ziele von entfernten Angreifern sind. Das ist der Grund, warum AppArmor bequem einen Befehl aa-unconfined zur Verfügung stellt, um die Programme aufzulisten, die kein zugehöriges Profil haben und einen offenen Netzwerk-Socket anbieten. Mit der Option --paranoid erhalten Sie alle unbeschränkten Prozesse, die mindestens eine aktive Netzwerkverbindung haben.
# aa-unconfined
801 /sbin/dhclient not confined
890 /sbin/rpcbind not confined
899 /sbin/rpc.statd not confined
929 /usr/sbin/sshd not confined
941 /usr/sbin/avahi-daemon confined by '/usr/sbin/avahi-daemon (complain)'
988 /usr/sbin/minissdpd not confined
1276 /usr/sbin/exim4 not confined
1485 /usr/lib/erlang/erts-6.2/bin/epmd not confined
1751 /usr/lib/erlang/erts-6.2/bin/beam.smp not confined
19592 /usr/lib/dleyna-renderer/dleyna-renderer-service not confined
Im folgenden Beispiel wird also versucht, ein Profil für /sbin/dhclient zu erstellen. Dazu verwenden wir aa-genprof dhclient. Es wird Sie einladen, die Anwendung in einem anderen Fenster zu benutzen, und wenn es fertig ist, zu aa-genprof zurückzukehren, um nach AppArmor-Ereignissen in den Systemprotokollen zu suchen und diese Protokolle in Zugriffsregeln umzuwandeln. Für jedes protokollierte Ereignis macht es einen oder mehrere Regelvorschläge, die Sie entweder genehmigen oder auf mehrere Arten weiter bearbeiten können:
# aa-genprof dhclient
Writing updated profile for /sbin/dhclient.
Setting /sbin/dhclient to complain mode.

Before you begin, you may wish to check if a
profile already exists for the application you
wish to confine. See the following wiki page for
more information:
http://wiki.apparmor.net/index.php/Profiles

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below in 
order to scan the system logs for AppArmor events. 

For each AppArmor event, you will be given the 
opportunity to choose whether the access should be 
allowed or denied.

Profiling: /sbin/dhclient

[(S)can system log for AppArmor events] / (F)inish
Reading log entries from /var/log/audit/audit.log.

Profile:  /sbin/dhclient 1
Execute:  /usr/lib/NetworkManager/nm-dhcp-helper
Severity: unknown

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
P
Should AppArmor sanitise the environment when
switching profiles?

Sanitising environment is more secure,
but some applications depend on the presence
of LD_PRELOAD or LD_LIBRARY_PATH.

(Y)es / [(N)o]
Y
Writing updated profile for /usr/lib/NetworkManager/nm-dhcp-helper.
Complain-mode changes:
WARN: unknown capability: CAP_net_raw

Profile:    /sbin/dhclient 2
Capability: net_raw
Severity:   unknown

[(A)llow] / (D)eny / (I)gnore / Audi(t) / Abo(r)t / (F)inish
A
Adding capability net_raw to profile.

Profile:  /sbin/dhclient 3
Path:     /etc/nsswitch.conf
Mode:     r
Severity: unknown

  1 - #include <abstractions/apache2-common> 
  2 - #include <abstractions/libvirt-qemu> 
  3 - #include <abstractions/nameservice> 
  4 - #include <abstractions/totem> 
 [5 - /etc/nsswitch.conf]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
3

Profile:  /sbin/dhclient
Path:     /etc/nsswitch.conf
Mode:     r
Severity: unknown

  1 - #include <abstractions/apache2-common> 
  2 - #include <abstractions/libvirt-qemu> 
 [3 - #include <abstractions/nameservice>]
  4 - #include <abstractions/totem> 
  5 - /etc/nsswitch.conf 
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding #include <abstractions/nameservice> to profile.

Profile:  /sbin/dhclient
Path:     /proc/7252/net/dev
Mode:     r
Severity: 6

  1 - /proc/7252/net/dev 
 [2 - /proc/*/net/dev]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /proc/*/net/dev r to profile

[...]
Profile:  /sbin/dhclient 4
Path:     /run/dhclient-eth0.pid
Mode:     w
Severity: unknown

 [1 - /run/dhclient-eth0.pid]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
N

Enter new path: /run/dhclient*.pid

Profile:  /sbin/dhclient
Path:     /run/dhclient-eth0.pid
Mode:     w
Severity: unknown

  1 - /run/dhclient-eth0.pid 
 [2 - /run/dhclient*.pid]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /run/dhclient*.pid w to profile

[...]
Profile:  /usr/lib/NetworkManager/nm-dhcp-helper 5
Path:     /proc/filesystems
Mode:     r
Severity: 6

 [1 - /proc/filesystems]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /proc/filesystems r to profile

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

 [1 - /sbin/dhclient]
  2 - /usr/lib/NetworkManager/nm-dhcp-helper 
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
S
Writing updated profile for /sbin/dhclient.
Writing updated profile for /usr/lib/NetworkManager/nm-dhcp-helper.

Profiling: /sbin/dhclient

[(S)can system log for AppArmor events] / (F)inish
F
Setting /sbin/dhclient to enforce mode.
Setting /usr/lib/NetworkManager/nm-dhcp-helper to enforce mode.

Reloaded AppArmor profiles in enforce mode.

Please consider contributing your new profile!
See the following wiki page for more information:
http://wiki.apparmor.net/index.php/Profiles

Finished generating profile for /sbin/dhclient.
Beachten Sie, dass das Programm die von Ihnen eingegebenen Steuerzeichen nicht wiedergibt, aber zur besseren Übersichtlichkeit der Erklärung habe ich sie in die Abschrift oben aufgenommen.

1

Das erste erkannte Ereignis ist die Ausführung eines anderen Programms. In diesem Fall haben Sie mehrere Möglichkeiten: Sie können das Programm mit dem Profil des übergeordneten Prozesses ausführen (Auswahl "Vererben"), Sie können es mit einem eigenen Profil ausführen (Auswahl "Profil" und "Benannt", die sich nur durch die Möglichkeit unterscheiden, einen beliebigen Profilnamen zu verwenden), Sie können es mit einem Unterprofil des übergeordneten Prozesses ausführen (Auswahl "Kind"), Sie können es ohne Profil ausführen (Auswahl "Unbegrenzt") oder Sie können entscheiden, es überhaupt nicht auszuführen (Auswahl "Verweigern").
Beachten Sie, dass das Tool, wenn Sie es unter einem speziellen, not nicht existierenden Profil ausführen, das fehlende Profil für Sie erstellt und Regelvorschläge für dieses Profil im selben Lauf macht.

2

Auf der Kernel-Ebene wurden die speziellen Befugnisse des root-Benutzers in "Fähigkeiten" aufgeteilt. Wenn ein Systemaufruf eine bestimmte Fähigkeit erfordert, prüft AppArmor, ob das Profil dem Programm erlaubt, diese Fähigkeit zu nutzen.

3

Hier sucht das Programm Leserechte für /etc/nsswitch.conf. aa-genprof hat festgestellt, dass diese Erlaubnis auch von mehreren "Abstraktionen" erteilt wurde und bietet sie als Alternative an. Eine Abstraktion bietet einen wiederverwendbaren Satz von Zugriffsregeln, die mehrere gemeinsam genutzte Ressourcen zusammenfassen. In diesem speziellen Fall wird die Datei im Allgemeinen über die Nameservice-bezogenen Funktionen der C-Bibliothek aufgerufen, und wir geben "3" ein, um zuerst die Option "#include <abstractions/nameservice>" und dann "A" auszuwählen, um sie zuzulassen.

4

Das Programm möchte die Datei /run/dhclient-eth0.pid erstellen. Wenn wir nur die Erstellung dieser speziellen Datei zulassen, wird das Programm nicht funktionieren, wenn der Benutzer sie auf einer anderen Netzwerkschnittstelle verwendet. Daher wählen wir "Neu", um den Dateinamen durch die allgemeinere "/run/dhclient*.pid" zu ersetzen, bevor wir die Regel mit "Zulassen" aufnehmen.

5

Beachten Sie, dass diese Zugriffsanforderung nicht Teil des dhclient-Profils ist, sondern des neuen Profils, das wir erstellt haben, als wir /usr/lib/NetworkManager/nm-dhcp-helper mit seinem eigenen Profil laufen ließen.
Nach Durchlaufen aller protokollierten Ereignisse bietet das Programm an, alle während des Laufs erstellten Profile zu speichern. In diesem Fall haben wir zwei Profile, die wir mit "Speichern" auf einmal speichern (Sie können sie aber auch einzeln speichern), bevor wir das Programm mit "Beenden" verlassen.
aa-genprof ist eigentlich nur ein intelligenter Wrapper um aa-logprof: er erstellt ein leeres Profil, lädt es im Beschwerdemodus und führt dann aa-logprof aus, das ein Werkzeug ist, um ein Profil basierend auf den protokollierten Profilverletzungen zu aktualisieren. So können Sie dieses Tool später erneut ausführen, um das gerade erstellte Profil zu verbessern.
Wenn Sie möchten, dass das generierte Profil vollständig ist, sollten Sie das Programm so verwenden, wie es berechtigterweise verwendet wird. Im Falle von dhclient bedeutet dies, dass es über den Netzwerk-Manager, über ifupdown, manuell usw. ausgeführt wird. Am Ende könnte /etc/apparmor.d/sbin.dhclient in der Nähe stehen von:
# Last Modified: Tue Sep  8 21:40:02 2015
#include <tunables/global>

/sbin/dhclient {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  capability net_bind_service,
  capability net_raw,

  /bin/dash r,
  /etc/dhcp/* r,
  /etc/dhcp/dhclient-enter-hooks.d/* r,
  /etc/dhcp/dhclient-exit-hooks.d/* r,
  /etc/resolv.conf.* w,
  /etc/samba/dhcp.conf.* w,
  /proc/*/net/dev r,
  /proc/filesystems r,
  /run/dhclient*.pid w,
  /sbin/dhclient mr,
  /sbin/dhclient-script rCx,
  /usr/lib/NetworkManager/nm-dhcp-helper Px,
  /var/lib/NetworkManager/* r,
  /var/lib/NetworkManager/*.lease rw,
  /var/lib/dhcp/*.leases rw,

  profile /sbin/dhclient-script flags=(complain) {
    #include <abstractions/base>
    #include <abstractions/bash>

    /bin/dash rix,
    /etc/dhcp/dhclient-enter-hooks.d/* r,
    /etc/dhcp/dhclient-exit-hooks.d/* r,
    /sbin/dhclient-script r,

  }
}