Eine andere Möglichkeit besteht darin, dass man eine Applikation in kleinere Prozesse zerlegt, die vom Hauptprozess gestartet werden, und diese mit besonderen Zugriffsrechten ausstattet.
Abbildung 1 zeigt am Beispiel des HTTP-Daemons Apache, wie man sich eine sichere Umgebung für einen Webserver vorzustellen hat. Wenn Apache gestartet wird, hat der Hauptprozess zunächst alle Rechte, um auf die Konfigurationsdateien und die komplette Verzeichnisstruktur zuzugreifen. Außerdem werden noch die Sockets erstellt, über die Webbrowser die Möglichkeit haben, die Webseiten abzurufen. Nachdem diese Grundkonfiguration abgeschlossen ist, werden Subprozesse gestartet, welche die eigentliche Aufgabe des HTTP-Daemons übernehmen. Jeder Subprozess erhält die Berechtigung, auf das ihm zugeordnete Verzeichnis und Ressourcen zuzugreifen. Das bedeutet, der Prozess läuft in einer Sandbox.
Um einen in dieser Art und Weise abgesicherten HTTP-Daemon zu programmieren, muss man einen erheblichen Aufwand betreiben. Der Grund liegt darin, dass für jedes UNIX-System oder BSD-Betriebssystem die Zugriffsmechanismen eigens implementiert werden müssen.
Unter FreeBSD gibt es mit Capsicum eine Lösung für das geschilderte Problem. FreeBSD dient hier als Referenzplattform nicht nur für die anderen BSD-Systeme, sondern auch für andere Unix-Plattformen. Im Rahmen des Google Summer of Code wurde Capsicum in FreeBSD implementiert. Ein besonderes Lob gilt hier Pawel Jakub Dawidek (pjd) und seinen Kollegen im FreeBSD-Entwicklerteam für die Betreuung und Durchführung des Projekts.
Bei der Entwicklung des Capsicum-Frameworks hat man sich der oben genannten Probleme angenommen und neue Sicherheitsmerkmale eingeführt, um die Abschottung von Anwendungen zu unterstützen. Um die Vorteile von Capsicum voll auszuschöpfen, müssen entweder – im schlechtesten Fall – Anwendungen neu entwickelt oder der Code neu strukturiert werden. Letzteres muss nicht von Nachteil sein.
Für die Entwicklung von Capsicum stand im Vordergrund, dass bestehende Mechanismen der Zugriffskontrolle unverändert funktionsfähig bleiben. Ebenso sollten die Programmierschnittstellen (APIs) nicht verändert werden, damit bestehende Software weiterhin ohne Einschränkungen funktioniert. Daher erweitert das Capsicum-System die Unix-Programmierschnittstellen, indem es innerhalb des Betriebssystemkerns eigene Funktionen implementiert. Um Capsicum in eigenen Anwendungen und Betriebssystemwerkzeugen zu nutzen, werden die C-Header-Files
»sys/capability.h
«
,
»libcapsicum.h
«
und die Bibliothek
»libcapsicum
«
bereitgestellt, die mit den Kernelerweiterungen kommuniziert.
Um Capsicum zu verstehen, sind einige nicht triviale Grundlagen zu erläutern. Capsicum kennt den sogenannten Capability-Mode. Dabei handelt es sich um ein Flag, das von der Funktion
»cap_enter()
«
gesetzt wird. Es zeigt an, dass alle Datei- und Speicheroperationen von jetzt an stark reglementiert sind. Dieses Flag wird an alle Kindprozesse vererbt und lässt sich nicht löschen. Prozesse, die sich im Capability-Mode befinden (Abbiuldung 2), haben nur extrem eingeschränkten Zugriff auf den Namespace des Kernels (siehe
Tabelle 1
). Zusätzlich werden einige Systemschnittstellen geschützt. Dazu gehören alle Gerätetreiber, die Zugriff auf den physischen Speicher oder PCI-Bus gestatten. Auch Kommandos wie
»reboot
«
oder
»kldload
«
werden geblockt.
Tabelle 1
Globaler Namespace des FreeBSD-Kernel
Namespace |
Erklärung |
---|---|
Prozesskennung (PID) |
Unix-Prozesse werden durch eine eindeutige Kennung repräsentiert. PIDs werden beim Starten eines Prozesses zurückgegeben und lassen sich zum Debugging, zum Senden von Signalen, Monitoring und zum Ermitteln des aktuellen Status heranziehen. |
Dateipfade |
Unix-Files liegen in einem globalen, hierarchisch aufgebauten Namespace, der durch DAC und MAC geschützt ist. |
NFS-File-Handles |
Sowohl NFS-Server als auch der NFS-Client benutzen File-Handles, um Dateien und Verzeichnisse zu identifizieren. Davon macht die NFS-Zugriffsverwaltung Gebrauch. |
Filessystem-Kennungen |
Damit wird die Zuordnung von Mountpoints zu Pfaden bestimmt. Sie werden benutzt, um einen Zwangs-Unmount vorzunehmen, wenn kein Pfad mehr existiert. |
Protokoll-Adressen |
Die Protokoll-Familien benutzen Socket-Adressen, um lokale beziehungsweise entfernte Netzwerkendpunkte zu bezeichnen. Sie existieren genauso wie IPv4-Adressen und Ports oder die Sockets im globalen Namensraum. |
Sysctl-MIBs |
Das Sysctl-Verwaltungssystem verwendet sowohl numerische als auch alphanumerische Einträge, um Systemparameter auszulesen und zu verändern. |
SystemV-IPC |
Message-Queues, Semaphoren und Shared Memory dienen der Kommunikation zwischen Prozessen und werden nach dem SystemV-Standard abgewickelt. |
Posix-IPC |
Message-Queues, Semaphoren und Shared Memory dienen der Kommunikation zwischen Prozessen und werden nach dem Posix-Standard abgewickelt. |
Systemuhren |
FreeBSD-Systeme stellen mehrere Schnittstellen zur Verwaltung der Systemuhr bereit. |
Jails |
Jails als auf FreeBSD basierende Virtualisierung nutzt einen eigenen Namespace als Untermenge des globalen Namespace. |
CPU-Sets |
Zuordnung von CPU-Ressourcen zu Prozessen und Threads. |