Mit einer vernünftigen Backup-Strategie wappnen sich Administratoren erfolgreich gegen Datenverluste und längere Systemausfälle. So zeigen wir Ihnen ... (mehr)

Capabilities zuteilen

Ganz ähnlich verhält es sich mit den sogenannten Capabilities, die ein Container zugewiesen bekommt. Üblicherweise unterscheidet Linux lediglich zwischen privilegierten (euid = 0) und nicht privilegierten (euid != 0) Prozessen. Im Falle von Docker ist es aber nicht wünschenswert, dass Container immer als privilegierte Prozesse ablaufen. Glücklicherweise lässt sich die Anforderung durch den Einsatz von Capabilities recht leicht umsetzen. Sie unterteilen die Privilegien in kleine Happen, die sich dann einem Prozess mit der effektiven User-ID 0 zuweisen lassen.

Somit hat der Prozess immer noch die Möglichkeit, diverse privilegierte Aktionen durchzuführen, aber eben nur noch die, die dem Prozess explizit erlaubt wurden. Für Docker-Container sind dies aktuell die folgenden Privilegien: chown, dac_override, fowner, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, setfcap, audit_write und fsetid. Eine vollständige Liste sämtlicher Privilegien und deren Bedeutung finden Sie in der Manpage "capabilities".

 Das folgende Beispiel zeigt, wie sich das fehlende Privileg net_admin für einen Container auswirkt:

# ip address add 192.168.0.11 dev eth0
RTNETLINK answers: Operation not permitted

Wollen Sie also eine IP-Adresse innerhalb des Containers definieren, schlägt dies fehl, da die notwendige Berechtigung "cap_net_admin" dem Container nicht zur Verfügung steht. Das Netzwerk muss in diesem Fall also "von außen" mittels des Docker-Services definiert werden. Es gibt Fälle, in denen ein Container mehr Rechte benötigt als die zuvor definierten. In einem solchen Fall können Sie sie einfach dem docker-Tool als Kommandozeilenoptionen "--cap-add" übergeben:

# docker run --name mycontainer --rm -it --cap-add net_admin fedora: latest /bin/bash

Versuchen Sie nun, die IP-Adresse innerhalb des Container zu ändern, werden Sie erfolgreich sein. Um vordefinierte Rechte zu entfernen, können Sie auf die Option "--cap-drop" zurückgreifen.

Wer sich an dieser Stelle fragt, wo alle diese Default-Konfigurationen hinterlegt sind, sollte einen Blick auf die Konfiguration von libcontainer [1] werfen. Die in Go geschriebene API greift auf die Container-Funktionen des Kernels zurück und ersetzt in Docker die zuvor verwendete LXC-basierte Implementation.

Mit SELinux Container schützen

Neben Namespaces, Cgroups und Capabilities stellt SELinux eine weitere grundlegende Schutzsäule für Docker-Container dar. Sämtliche Container-Prozesse laufen dabei innerhalb der SELinux-Domäne svirt_lxc_net_t. Dateien innerhalb eines Containers sind mit dem SELinux-Label svirt_sandbox_file_t versehen. Das SELinux-Regelwerk erlaubt allen Container-Prozessen den Zugriff auf Objekte mit diesem Label:

# sesearch --allow -s svirt_lxc_net_t -t svirt_sandbox_file_t -c file
[...]
allow svirt_sandbox_domain svirt_sandbox_file_t : file { ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute execute_no_trans open } ;

Auf dem Host ist der Zugriff für Prozesse aus der svirt_lxc_net_t sehr eingeschränkt. Das folgende Beispiel verdeutlicht dies. Hier wird eine Shell in der SELinux-Domäne gestartet, in der die Prozesse eines Docker Containers laufen. Obwohl der folgende Zugriff auf die Datei »/etc/shadow« unter der Benutzer-ID 0 stattfindet, wird der Zugriff unterbunden:

# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# runcon system_u:system_r:svirt_lxc_net_t:s0 cat /etc/shadow
cat: /etc/shadow: Permission denied

Ein Blick in das Audit-Log bestätigt, dass das SELinux-Subsystem den Zugriff unterbunden hat, da das vorhandene Regelwerk über keine passende Regel verfügt, die ihn erlauben würde:

# ausearch -m avc -ts recent
----
time->Mon Mar 23 19:33:23 2015
type=AVC msg=audit(1427135603.651:6367): avc: denied { read } for pid=17293 comm="cat" name="shadow" dev="dm-2" ino=3032084
scontext=system_u:system_r:svirt_lxc_net_t:s0 tcontext=system_u:object_r:shadow_t:s0 tclass=file permissive=0

Ähnliche Artikel

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023