Podman: Linux-Container einfach gemacht, Teil 2

Seite 5: Podman und Linux Audit

Inhaltsverzeichnis

Linux hat ein weiteres Sicherheitskonzept, das das Herz eines jeden Administrators höher schlagen lässt: das Audit-Subsystem. Audit erlaubt es, über bestimmte Ereignisse auf dem System genau Buch zu führen, um nachzuvollziehen, welche sicherheitsrelevanten Aktivitäten von welchem Benutzer zu einem bestimmten Zeitpunkt ausgeführt wurden. Audit ist hinreichend umfangreich und komplex, um eine Artikelserie nur diesem Thema zu widmen. Für die Zwecke des Artikels genügt es zu wissen, dass Audit ein zentraler Bestandteil vieler Linux-Systeme und beliebtes Mittel von Administratoren ist. Darüber hinaus setzen viele Sicherheitszertifizierungen Audit voraus. Es ist aus dem Alltag nicht mehr wegzudenken.

Bei jedem Login eines Benutzers weist Audit dem Prozess eine eindeutige ID zu, die man über das /proc-Dateisystem einsehen kann.

$ cat /proc/self/loginuid
1000

Eine wichtige Eigenschaft der LoginUID ist, dass sie auch allen Kindprozessen zugewiesen wird, selbst wenn sie als Root laufen.

$ sudo cat /proc/self/loginuid
1000

Die Eindeutigkeit der LoginUID und deren Unveränderbarkeit nach dem Login ist die Kerneigenschaft von Audit, denn damit können Anwender genau nachvollziehen, welche Aktivität von welchem Benutzer ausging.

Genau hier spielt die Architektur von Podman eine große Rolle. Wie im Teil 1 der Artikelserie beschrieben, setzt Podman auf eine klassische Fork-Exec-Architektur, wodurch jeder Container ein Kind-Prozess von Podman ist.

$ sudo podman run alpine cat /proc/self/loginuid
1000
$ sudo docker run alpine cat /proc/self/loginuid
4294967295

Im Beispiel hat der Docker-Container eine LoginUID von 4294967295, obwohl der ausführende Benutzer eine ID von 1000 hat. Grund dafür ist die Client-Server-Architektur von Docker. Der Docker-Client selbst wird mit der ID von 1000 ausgeführt, jedoch kommuniziert er über einen Unix-Socket mit dem Docker-Daemon, den wiederum Systemd gestartet hat.

$ sudo cat /proc/1/loginuid
4294967295

Damit erbt der Docker-Container die LoginUID von Systemd und kann sich somit dem Audit-System teilweise entziehen. Über Aktivitäten wird zwar nach wie vor Buch geführt, jedoch wissen Entwickler nicht, von welchem Benutzer sie ausgingen. Es folgt ein praktisches Beispiel.

Zunächst befiehlt man Audit, die /etc/shadow-Datei zu überwachen und führt einen Docker-Container aus, der die Datei mountet und den Zeitstempel verändert.

$ sudo auditctl -w /etc/shadow
$ sudo docker run -v /etc:/etc alpine touch /etc/shadow
$ sudo ausearch -f /etc/shadow -i
type=SYSCALL msg=audit(05/01/2019 14:23:14.322:1819) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7ffd81a2bf55 a2=O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK a3=0x1b6 items=2 ppid=19876 pid=19895 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=touch exe=/usr/bin/touch subj=system_u:system_r:spc_t:s0 key=(null)

Die Ausgabe listet viele Details, wobei auid=unset die relevante Information ist. Audit ist nicht in der Lage, die Aktivität einer LoginUID zu bestimmen, da Systemd zum Systemstart als Prozess 1 ausgeführt wird und damit keine LoginUID zugewiesen bekommt.

$ sudo podman run -v /etc:/etc alpine touch /etc/shadow
$ sudo ausearch -f /etc/shadow -i
type=SYSCALL msg=audit(05/01/2019 14:23:17.353:1823) : arch=x86_64 syscall=openat success=yes exit=4 a0=0xffffff9c a1=0x7fec7a334181 a2=O_RDONLY|O_CLOEXEC a3=0x0 items=1 ppid=19984 pid=19986 auid=valentin uid=root gid=valentin euid=root suid=root fsuid=root egid=valentin sgid=valentin fsgid=valentin tty=pts19 ses=3 comm=unix_chkpwd
exe=/usr/sbin/unix_chkpwd subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)

Das Ausführen mit Podman liefert das gewünschte Ergebnis und zeigt eindeutig, von welchem Benutzer die Aktivität ausging (siehe auid=valentin): eines von vielen Beispielen der Vorteile von Podmans Fork-Exec-Architektur.