Programme absichern mit Firejail

Aus LinuxUser 04/2015

Programme absichern mit Firejail

© SergeyMironov, 123RF

Heiße Zelle

Firejail erhöht die Sicherheit, indem es beliebige Programme und Prozesse in voneinander abgeschottete Gefängnisse sperrt und den Zugriff auf das Dateisystem strikt reglementiert.

Schadprogramme gelangen häufig über Sicherheitslücken im Browser oder in Hintergrunddiensten auf das eigene System. Dort manipulieren sie dann Konfigurationsdateien, installieren Rootkits oder missbrauchen andere Programme.

Firejail verhindert derartige Attacken, indem es Firefox, Apache oder ein beliebiges anderes gefährdetes Programm in ein Gefängnis sperrt. In dieser sogenannten Sandbox können die solcherart arretierten Anwendungen dann keine wichtigen Dateien mehr manipulieren und höchstens noch innerhalb ihrer engen Mauern Amok laufen. Auf Wunsch reglementiert und verändert Firejail sogar die Sicht der entsprechenden Prozesse auf das Dateisystem und verwirft alle von den Programmen erstellen Dateien.

Im Gegensatz zum Einsatz in einer virtuellen Maschine, die gleich einen kompletten PC nachbildet, laufen in der Sandbox von Firejail neben beliebigen GUI- und Server-Anwendungen auch anspruchsvolle Spiele mit 3D-Beschleunigung mit voller Leistung.

Gefängnisbau

Auf der Firejail-Homepage [1] warten bereits je ein DEB- (Debian, Ubuntu, Linux Mint) und RPM-Paket (Fedora, OpenSuse, CentOS 7 und RHEL 7) auf den Download. Beide setzen zwingend ein 64-Bit-System voraus. Arch-Linux-Nutzer finden Firejail im AUR, für Slackware stehen Pakete im SlackBuilds-Repository bereit [2]. Firejail arbeitet mit allen Kerneln der 3er-Reihe zusammen. Einige wenige Funktionen können Sie allerdings erst unter neueren Kernel-Versionen nutzen (dazu später noch mehr).

Finden Sie kein für die von Ihnen verwendete Distribution passendes Paket, greifen Sie zum Quellcode-Archiv. Nachdem Sie es entpackt haben, wechseln Sie ins dabei neu entstandene Verzeichnis und übersetzen Firejail mit dem klassischen Dreisatz (Listing 1). Die daraufhin startende Übersetzung und Installation setzt Make, einen C-Compiler und die Kernel-Header voraus.

Listing 1

$ ./configure && make && sudo make install

Um eine Anwendung in ein Gefängnis zu sperren, rufen Sie Firejail mit dem Namen des zu startenden Programms auf. Ein Beispiel für Firefox zeigt die erste Zeile von Listing 1. Sofern die einzusperrende Anwendung noch Parameter benötigt, hängen Sie diese einfach hinten an den Befehl an.

Listing 2

$ firejail firefox
$ firejail "/etc/init.d/sshd start && sleep inf"

Rufen Sie Firejail ohne jeden Parameter auf, so startet wie in Abbildung 1 eine Sandbox mit einer Bash-Shell. Entgegen der offiziellen Dokumentation [3] läuft Firejail so lange immer im Hintergrund weiter, bis sich das Programm in der Sandbox beendet.

Abbildung 1: Beim Start gibt Firejail noch eine Übersicht über die in der Sandbox gültigen IP-Adressen. In der von Firejail gestarteten Sandbox besitzt das eingesperrte Programm immer die Prozess-ID 1.

Abbildung 1: Beim Start gibt Firejail noch eine Übersicht über die in der Sandbox gültigen IP-Adressen. In der von Firejail gestarteten Sandbox besitzt das eingesperrte Programm immer die Prozess-ID 1.

Eine kleine Stolperfalle lauert bei Webservern, Datenbanken und anderen Diensten: Deren Daemons verkrümeln sich nach dem Start umgehend in den Hintergrund. Firejail glaubt dann, das Programm habe sich beendet, und reißt die Sandbox samt Dienst umgehend wieder ein. Um das zu verhindern, müssen Sie zu einem Trick greifen und Firejail nach dem Start des Daemons unendlich lange warten beziehungsweise mitlaufen lassen. Ein entsprechendes Beispiel für SSH sehen Sie in der zweiten Zeile von Listing 2.

Äußerst vergesslich

Die Programme in der Sandbox können auf nahezu sämtliche Verzeichnisse nur lesend zugreifen und somit keine wichtigen Dateien manipulieren. Lediglich die Verzeichnisse /home, /tmp and /var dürfen die eingesperrten Anwendungen weiterhin beschreiben (Abbildung 2).

Abbildung 2: Rufen Sie Firejail mit dem zusätzlichen Parameter <code srcset=

–debug auf, dann zeigt das Werkzeug zahlreiche Informationen an, darunter auch die eingebundenen Verzeichnisse.” width=”300″ height=”265″ /> Abbildung 2: Rufen Sie Firejail mit dem zusätzlichen Parameter --debug auf, dann zeigt das Werkzeug zahlreiche Informationen an, darunter auch die eingebundenen Verzeichnisse.

Genügen diese Restriktionen nicht, dann aktivieren Sie zusätzlich ein sogenanntes Overlay-Dateisystem. Die dahinterstehende Technik kommt auch bei Live-Systemen zum Einsatz: Firejail gaukelt dem Programm in der Sandbox vor, es dürfte im Dateisystem schalten und walten. Stattdessen fängt es jedoch sämtliche Änderungen ab, die es zudem beim Beenden der Sandbox verwirft. Die Daten auf der Festplatte bleiben somit gänzlich unverändert.

Technisch gesehen legt Firejail dazu ein zusätzliches Dateisystem über das vorhandene (siehe Kasten “Interna”). Wenn Sie das Overlay-Dateisystem nutzen möchten, hängen Sie firejail den Parameter --overlay an:

$ firejail --overlay gedit

Mit dem so gestarteten Gnome-Editor können Sie Dateien erstellen und verändern. Nach dem Beenden von Gedit befinden sich jedoch alle neuen Daten im Nirwana, während die vermeintlich geänderten Dateien weiterhin in der ursprünglichen Fassung auf der Festplatte liegen.

Als besonders nützlich erweist sich das Overlay-Dateisystem bei Webbrowsern: Sämtliche gesammelten Cookies, die History und der Cache lösen sich nach dem Beenden in Wohlgefallen auf. Allerdings funktioniert --overlay erst mit einem Linux-Kernel ab Version 3.18. Einige Distributionen haben die zugrundeliegende Kernel-Funktion jedoch schon länger aktiviert, darunter Ubuntu und OpenSuse.

Interna

Firejail erstellt die Sandbox mithilfe der vom Linux-Kernel angebotenen Namespaces. Mit deren Hilfe gaukelt das Programm einem Prozess vor, er würde ganz alleine auf dem System laufen. Zudem nutzt Firejail die Namespaces, um den Zugriff auf das Netzwerk und das Dateisystem zu reglementieren. Zudem erstellt es in der Sandbox einen eigenen Netzwerk-Stack. Die Sandbox besitzt folglich ihre eigene Routing-Tabelle, eigene Netfilter- beziehungsweise Iptables-Firewalls und eigene Netzwerkschnittstellen.

Das Overlay-Dateisystem realisiert Firejail mittels OverlayFS [5]. Dabei landen neue und geänderte Dateien in einem eigenen Dateisystem, das das vorhandene überdeckt. Nach einem ähnlichen Prinzip funktioniert der Private Mode: In ihm mountet Firejail ein Tmpfs-Dateisystem über das Heimatverzeichnis.

Wie die Parameter --seccomp und --caps andeuten, nutzt Firejail dabei die Seccomp-Unterstützung des Kernels beziehungsweise greift auf die sogenannten Linux Capabilities [6] zurück. Experten dürfen hinter --seccomp weitere Syscalls auflisten, die Firejail in der Sandbox blocken soll, wie etwa:

$ firejail --seccomp=chmod,fchmod,fchmodat

Einen tieferen Einblick in den Ablauf der eingesperrten Prozesse gibt das Werkzeug firemon. Mit ihm können Sie alle Fork-, Exec-, ID-Change- und Exit-Ereignisse in der Sandbox verfolgen und bei Bedarf in ein Log schreiben lassen. Firemon benötigt dazu Root-Rechte. Welche Prozesse die Funktionen open, unlink, mkdir, rmdir, stat, access, socket, connect und bind in der Glibc aufrufen, erfahren Sie, wenn Sie Firejail mit dem Parameter --trace starten.

Privatvergnügen

Des Weiteren kann Firejail die Sandbox in einen sogenannten Private Mode schalten. Dabei versteckt die Sandbox das komplette Heimatverzeichnis vor allen in ihren laufenden Programmen. Diese sehen dann nur leere /root– und /home-Verzeichnisse. Alle in diese Ordner geschriebenen Dateien verwirft Firejail nach dem Beenden der Sandbox. Den Private Mode aktivieren Sie über den Parameter --private (Listing 3, erste Zeile).

Anstelle von /root und /home können Sie auch ein beliebiges anderes Verzeichnis in die Sandbox reichen. Dann bleiben die vom Programm erstellten Dateien erhalten, landen aber nicht in den echten /root– und /home-Verzeichnissen, sondern im von Ihnen angegebenen Ersatzverzeichnis. Im Beispiel aus der zweiten Zeile von Listing 3 würde Firefox in der Sandbox den Inhalt des Unterverzeichnisses ~/muell als Heimatverzeichnis sehen (Abbildung 3).

Listing 3

$ firejail --private firefox
$ firejail --private=~/muell firefox

Abbildung 3: Firejail hängt das Unterverzeichnis <code srcset=

~/muell mit einer Datei in die Sandbox. Die darin laufende Shell sieht als Heimatverzeichnis nur noch den Inhalt von ~/muell.” width=”300″ height=”120″ /> Abbildung 3: Firejail hängt das Unterverzeichnis ~/muell mit einer Datei in die Sandbox. Die darin laufende Shell sieht als Heimatverzeichnis nur noch den Inhalt von ~/muell.

Rumhängen

In allen bisher vorgestellten Konfigurationen sehen die Programme in der Sandbox Dateien aus dem lokalen Dateisystem – mal mehr davon, mal weniger. Auch das lässt sich verhindern, indem Sie das Dateisystem einer komplett anderen Linux-Installation in die Sandbox einhängen.

Das entsprechende Dateisystem darf auf einer anderen Partition liegen, oder aber Sie installieren in ein separates Verzeichnis ein komplett neues Linux-System. Letzteres erledigen verschiedene Werkzeuge; unter Debian hilft etwa Debootstrap (Abbildung 4). Anschließend müssen Sie Firejail nur noch den Namen des Unterverzeichnisses mitteilen (Abbildung 5). Der folgende Befehl etwa hängt das Verzeichnis /debian als Root-Dateisystem in die Sandbox ein und startet darin dann Iceweasel:

$ sudo firejail --chroot=/debian iceweasel --name=debian

Abbildung 4: Diese beiden Befehle erstellen schnell eine neue Debian-Installation im Unterverzeichnis <code srcset=

/debian, die sich dann …” width=”300″ height=”182″ /> Abbildung 4: Diese beiden Befehle erstellen schnell eine neue Debian-Installation im Unterverzeichnis /debian, die sich dann …

Abbildung 5: … einer Sandbox unterschieben lässt.

Abbildung 5: … einer Sandbox unterschieben lässt.

Der Webbrowser sieht jetzt nur noch die Dateien und Verzeichnisse unterhalb von /debian.

Starten Sie die Sandbox anders als in Abbildung 5 als normaler Nutzer, dann läuft das Programm in der Sandbox unter deren zugehörigen Benutzer-ID (UID). Die UIDs auf Ihrem und dem in der Sandbox genutzten System müssen dann übereinstimmen.

Der Parameter --name= schließlich ändert den Hostnamen. Im Beispiel würde folglich Iceweasel glauben, es liefe auf einem Rechner namens debian.

Ziemlich beschränkt

Mit dem zusätzlichen Parameter --seccomp verbietet Firejail den Programmen in der Sandbox einige sicherheitskritische Aktionen. Unter anderem dürfen sie weder Kernel-Module laden noch den Swap-Speicher kontrollieren, Programme mit Root-Rechten (SUID) ausführen oder das System neu starten. Versucht eine Anwendung eine dieser Systemfunktionen aufzurufen, beendet sie der Kernel umgehend. Dieses äußerst nützliche Sicherheitsnetz steht allerdings erst ab einem Linux-Kernel in Version 3.5 zur Verfügung.

Ergänzend kennt Firejail den Parameter --caps. Mit ihm aktiviert Firejail einen Sicherheitsfilter im Kernel. Er blockiert unter anderem jeden Versuch, das System neu zu starten, den Kernel zu ersetzen, Kernel-Module zu laden, den Prozessen in der Sandbox mehr Rechenzeit (über den sogenannten Nice-Wert) und ihnen Systemadmin-Privilegien zu geben.

Die Optionen --seccomp und --caps unterbinden also teilweise dieselben Aktionen. Im Fall von --caps beendet der Kernel jedoch nicht den Prozess, sondern lässt ihn weiterlaufen. Zudem unterstützen auch ältere Linux-Kernel diesen Sicherheitsfilter.

Ins Netz gegangen

Auf Wunsch kann Firejail in die Sandbox eine eigene TCP/IP-Netzwerkschnittstelle einbauen. Diese lässt sich dann mit einer existierenden Netzwerk-Bridge verbinden. Das ist für Testzwecke nützlich oder aber, um eine demilitarisierte Zone (DMZ) aufzubauen.

Listing 4

$ firejail --net=br0 --ip=10.10.20.10 firefox

Mit dem Befehl aus Listing 4 würde Firejail die auf dem PC bereits existierende Netzwerk-Bridge br0 mit der Sandbox verbinden, in der wiederum Firefox läuft. Lassen Sie den Parameter --ip weg, dann versucht Firejail selbst eine passende freie IP-Adresse zu finden (Abbildung 6). Mit dem Parameter --net=none trennen Sie die Sandbox komplett vom Netzwerk.

Abbildung 6: In diesem Beispiel wurde zunächst eine Netzwerk-Bridge <code srcset=

br0 eingerichtet und dann die Sandbox daran angeschlossen. Letztgenannte hat sich selbst eine noch nicht vergebene IP-Adresse verpasst.” width=”300″ height=”112″ /> Abbildung 6: In diesem Beispiel wurde zunächst eine Netzwerk-Bridge br0 eingerichtet und dann die Sandbox daran angeschlossen. Letztgenannte hat sich selbst eine noch nicht vergebene IP-Adresse verpasst.

Im Profil

Statt Kommandozeilenparameter zu verwenden, können Sie für jedes Programm eine eigene Konfigurationsdatei erstellen. In diesen sogenannten Security Profiles aktivieren Sie bei Bedarf explizit die Funktionen --seccomp– und --caps. Darüber hinaus legen Sie detailliert fest, welche Verzeichnisse Firejail nicht oder nur schreibgeschützt in die Sandbox durchreichen soll, und geben die entsprechenden Einhängepunkte vor. Abschließend dürfen Sie auch noch der Sandbox ein paar Grenzen setzen und etwa die in ihr laufende Anzahl von Prozessen limitieren.

Sämtliche Security Profiles lagern im Verzeichnis /etc/firejail. Firejail 0.9.18 bringt Profile für Chromium, Dropbox, Evince, Firefox, Iceweasel und Midori mit. Der Dateiname des Profils beginnt dabei mit dem Namen des Programms und endet auf .profile. Das Profil für firefox steckt folglich in der Datei firefox.profile.

Sobald Sie firejail firefox aufrufen, wendet Firejail automatisch alle Einstellungen aus dem zugehörigen Security Profile an. Die Security Profiles selbst sind recht simpel aufgebaut, in jeder Zeile steht eine Einstellung. Die Tabelle “Security Profiles” zeigt die wichtigsten Einstellungen auf einen Blick. Weitere Informationen zum Aufbau eines Security Profiles liefert die Manpage man firejail-profile.

Security Profiles

Angabe Bedeutung
blacklist /usr/bin Firejail versteckt das Verzeichnis /usr/bin.
read-only /usr/bin Firejail bindet das Verzeichnis /usr/bin nur lesend ein.
tmpfs /etc Mountet ein Tmpfs-Dateisystem über das Verzeichnis /etc. Dort abgelegte Dateien werden nach dem Beenden der Sandbox verworfen.
bind /root/config/ssh,/etc/ssh Hängt das Verzeichnis /root/config/ssh als /etc/ssh in die Sandbox ein.
private /tmp/muell Hängt das Verzeichnis /tmp/muell als Heimatverzeichnis in die Sandbox ein.
caps Gleichbedeutend mit --caps.
seccomp Gleichbedeutend mit --seccomp.
rlimit-fsize 1024 Ein Programm in der Sandbox darf höchstens 1024 Byte große Dateien anlegen.
rlimit-nofile 500 Ein Programm in der Sandbox darf höchstens 500 Dateien gleichzeitig öffnen.
rlimit-nproc 1000 In der Sandbox lassen sich höchstens 1000 Prozesse erstellen.

Einblicke

Sämtliche laufenden Gefängnisse und die jeweils darin werkelnden Prozesse listet das Kommando firejail --list auf. Mit firejail --tree finden Sie schnell heraus, welches Programm welche anderen Prozesse gestartet hat und unter welchen Benutzerkennungen diese laufen (Abbildung 7). Der Parameter --top liefert eine ähnliche Ansicht wie das allseits bekannte top-Kommando.

Abbildung 7: Mit <code srcset=

firejail –tree zeigt das Werkzeug die Prozesse aus den Sandboxen in einer Hierarchie an. Hier wurde in der unteren Sandbox eine Shell gestartet, die wiederum Firefox aufgerufen hat.” width=”300″ height=”140″ /> Abbildung 7: Mit firejail --tree zeigt das Werkzeug die Prozesse aus den Sandboxen in einer Hierarchie an. Hier wurde in der unteren Sandbox eine Shell gestartet, die wiederum Firefox aufgerufen hat.

Sie können nachträglich in eine Sandbox wechseln. Dazu ermitteln Sie zunächst via firejail --list die Prozess-ID (PID) der Sandbox. In der angezeigten Liste mit allen Sandboxen erkennen Sie die gesuchte am Programmnamen. Ganz vorne in der entsprechenden Zeile steht die PID, wie etwa 2652 (Abbildung 8). Genau die hängen Sie jetzt einfach an den Parameter --join=:

$ firejail --join=2652

Firejail öffnet nun eine Shell, die in eben jener Sandbox läuft und den dort geltenden Restriktionen unterliegt. Um die Join-Funktion nutzen zu können, benötigen Sie einen Linux-Kernel ab der Version 3.8.

Abbildung 8: Hier läuft Firefox in einer Sandbox, in der <code srcset=

firejail –join=2652 eine Shell öffnet.” width=”300″ height=”96″ /> Abbildung 8: Hier läuft Firefox in einer Sandbox, in der firejail --join=2652 eine Shell öffnet.

Fazit

Das unter der GPLv2 stehende Firejail lässt sich einfach bedienen und erhöht die Sicherheit. Sie müssen Anwendungen zudem nicht extra auf die Sandbox vorbereiten und können sogar Dropbox flugs in ein Gefängnis stecken [4].

Nichtsdestotrotz stellt die Sandbox kein Allheilmittel dar. Ein von Angreifern ferngesteuerter Webserver könnte zwar nicht mehr das System zerstören, auf dem er läuft, sich aber immer noch an einem Angriff auf andere Internetseiten beteiligen. Firejail bildet somit nur einen Baustein für das Absichern eines Linux-Systems – allerdings lässt es sich schnell und effektiv anwenden.

Weitere Informationen rund um Firejail bietet die Homepage des Tools [1]. Neben einer kleinen Link-Sammlung mit verschiedenen Tutorials finden Sie dort auch eine Anleitung, wie sich Firejail als Login-Shell einsetzen lässt. 

Infos

[1] Firejail: https://l3net.wordpress.com/projects/firejail/

[2] Firejail im SlackBuilds-Directory: http://slackbuilds.org/repository/14.1/system/firejail/?search=firejail

[3] Firejail_Dokumentation: https://l3net.wordpress.com/projects/firejail/firejail-usage/

[4] Dropbox in einer Sandbox: https://l3net.wordpress.com/2014/11/18/running-dropbox-in-firejail-sandbox/

[5] Wikipedia-Eintrag zu OverlayFS: http://en.wikipedia.org/wiki/OverlayFS

[6] Rechte über Capabilities einschränken: Marcel Hilzinger, “Grenzen setzen”, LU 06/2009, S. 36, https://www.linux-community.de/18253

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 04/2015 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

1 Kommentar
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Fred
8 Jahre her

Nun, ehe ich mit “meckern” anfange, muss ich erst mal ein dickes Lob los werden: der Artikel ist absolute Sahne.
Dass es bei mir mit Debian nicht geklappt hat, kann ich da nicht nachvollziehen. Alles lief perfekt, aber als ich debian mit firejail aufgerufen habe, wurde mir gesagt, dass /dev nicht vorhanden sei. Was natürlich auch gestimmt hat – nix da in /debian. Die Installation war also nicht korrekt und das lag dann an Debian selbst.
Ich werde es mal mit einem anderen System (außer Windows) probieren.

Nach oben