Firejail - Ein menschliches Tool zur Kontrolle von Software

Firejail

Ein menschliches Tool zur Kontrolle von Software

Rocco Gagliardi
von Rocco Gagliardi
Lesezeit: 16 Minuten

Wenn wir ein Stück Software einsetzen, dann sind wir alle plötzlich streng gläubig: Wir glauben dann nicht nur an die Entwickler der Software, sondern auch an alle anderen Entwickler, die Einfluss auf das komplexe System gehabt haben. Wenn wir ein Stück Software einsetzen, dann sind wir vielleicht vorsichtig, wenn es um den Netzwerkanschluss geht, wir installieren Firewalls und andere Abwehrmechanismen. Einmal im Netz, befindet sich die Software aber im Kern – Wir tendieren dazu, der Software bedingungslos zu glauben.

Es gibt verschiedene Möglichkeiten, wie praktisch sämtliche Eigenschaften einer Software im Betrieb kontrolliert werden kann. Betrachtet man die verschiedenen Sicherheitsmodelle im IT-Bereich, dann findet man Klassiker wie DAC, MAC, RBAC – und daneben auch einige exotische Varianten. Unter Linux wurde Discretionary Access Control (DAC) durch die Kernel-Extensions von SELinux/AppArmor abgelöst, die Mandatory Access Control (MAC) unterstützen. In den letzten Jahren wurden sie zu einem festen Bestandteil moderner Distributionen.

Um Zugriffe einschränken zu können, wurden Sandboxen entwickelt. Eine Sandbox ist grundsätzlich für die Entkoppelung von Programmen zuständig: Es kann das Dateisystem, Netzwerk, Ressourcen voneinander trennen.

Capabilities und seccomp Security Models

Das Capabilities Security Model fokussiert sich auf privilegierte Benutzer. Die Vielzahl der Rechte eines Superusers werden geteilt und mit Labels versehen. Diese Labels werden dann Prozessen zugewiesen, die die entsprechenden Möglichkeiten innerhalb des Betriebssystems zulassen. Capabilities dürfen nicht als Syscalls, sondern als Sammlung von Ressourcen verstanden werden. Als Beispiel ziehen wir CAP_SYS_RAWIO heran (benutzen Sie man 7 capabilities):

CAP_SYS_RAWIO
   * Perform I/O port operations (iopl(2) and ioperm(2));
   * access /proc/kcore;
   * employ the FIBMAP ioctl(2) operation;
   * open devices for accessing x86 model-specific registers (MSRs, see msr(4));
   * update /proc/sys/vm/mmap_min_addr;
   * create memory mappings at addresses below the value specified by /proc/sys/vm/mmap_min_addr;
   * map files in /proc/bus/pci;
   * open /dev/mem and /dev/kmem;
   * perform various SCSI device commands;
   * perform certain operations on hpsa(4) and cciss(4) devices;
   * perform a range of device-specific operations on other devices.

seccomp-bpf ist eine Extension von seccomp, das das Filtern von Syscalls mittels einer frei konfigurierbaren Policy auf der Basis von Berkeley Packet Filter Rules zulässt. Es wird von OpenSSH und vsftpd sowie Google Chrome und Chromium verwendet. Es fungiert dabei quasi als Firewall, die bestimmt, welche Funktionalität durch den Kernel (System-Calls) für einen Prozess zur Verfügung gestellt wird. Dadurch wird die Exponiertheit des Kernels gegenüber einem Prozess eingeschränkt.

Die Anzahl der Syscalls kann variieren; auf meinem System werden 380/332[32/64] Syscalls unterstützt (benutzen Sie man 2 syscalls and take a look into /usr/src/linux-headers-<ver>/include/uapi/asm-generic/unistd.h zur Anzeige einer kompletten Liste).

Exponiertheit reduzieren

Firejail greift auf die Funktionalität von Capabilities und Seccomp-bpf zurück, um Anwendungen in eine Sandbox zu setzen.

Nehmen wir folgendes Beispiel des Executables ping, dessen Exponiertheit mittels der Firejail Sandbox eingeschränkt werden soll. Wir werden:

  1. Die von ping genutzten Syscalls identifizieren
  2. Alle nicht benötigten Capabilities einschränken
  3. Firejail von einem Blacklist- in einen Whitelist-Modus schalten

Als ersten Schritt werden wir versuchen herauszufinden, welche Ressourcen durch ping genutzt werden. Die grundlegenden Syscalls können wie folgt herausgefunden werden:

root@ubunthin:~# strace -qcf ping -c1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=24.1 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 24.110/24.110/24.110/0.000 ms
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         8           read
  0.00    0.000000           0         6           write
  0.00    0.000000           0        35        13 open
  0.00    0.000000           0        23           close
  0.00    0.000000           0        23           fstat
  0.00    0.000000           0        31           mmap
  0.00    0.000000           0        14           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           setitimer
  0.00    0.000000           0         1           getpid
  0.00    0.000000           0         5         2 socket
  0.00    0.000000           0         1           connect
  0.00    0.000000           0         1           sendto
  0.00    0.000000           0         1           recvmsg
  0.00    0.000000           0         1           getsockname
  0.00    0.000000           0         7           setsockopt
  0.00    0.000000           0         1           getsockopt
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getuid
  0.00    0.000000           0         1           setuid
  0.00    0.000000           0         1           geteuid
  0.00    0.000000           0         7           capget
  0.00    0.000000           0         3           capset
  0.00    0.000000           0         2           prctl
  0.00    0.000000           0         1           arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                   195        23 total

Wir können ping innerhalb von Firejail ohne ein spezifisches Profil oder eine Konfiguration aufrufen, um minimale Sicherheit zu erreichen. Firejail lässt alle Capabilities zu, führt aber ein Blacklisting für bestimmte Syscalls durch:

root@ubunthin:/home/rcc# firejail --name=ping ping 8.8.8.8

root@ubunthin:/home/rcc# firejail --list
11971:rcc:firejail --name=ping ping 8.8.8.8

root@ubunthin:/home/rcc# firejail --seccomp.print=ping
SECCOMP Filter:
  VALIDATE_ARCHITECTURE
  EXAMINE_SYSCAL
  UNKNOWN ENTRY!!!
  UNKNOWN ENTRY!!!
  UNKNOWN ENTRY!!!
  BLACKLIST 165 mount
  BLACKLIST 166 umount2
  BLACKLIST 101 ptrace
  BLACKLIST 246 kexec_load
  BLACKLIST 320 kexec_file_load
  BLACKLIST 304 open_by_handle_at
  BLACKLIST 303 name_to_handle_at
  BLACKLIST 175 init_module
  BLACKLIST 313 finit_module
  BLACKLIST 174 create_module
  BLACKLIST 176 delete_module
  BLACKLIST 172 iopl
  BLACKLIST 173 ioperm
  BLACKLIST 251 ioprio_set
  BLACKLIST 167 swapon
  BLACKLIST 168 swapoff
  BLACKLIST 103 syslog
  BLACKLIST 310 process_vm_readv
  BLACKLIST 311 process_vm_writev
  BLACKLIST 139 sysfs
  BLACKLIST 156 _sysctl
  BLACKLIST 159 adjtimex
  BLACKLIST 305 clock_adjtime
  BLACKLIST 212 lookup_dcookie
  BLACKLIST 298 perf_event_open
  BLACKLIST 300 fanotify_init
  BLACKLIST 312 kcmp
  BLACKLIST 248 add_key
  BLACKLIST 249 request_key
  BLACKLIST 250 keyctl
  BLACKLIST 134 uselib
  BLACKLIST 163 acct
  BLACKLIST 154 modify_ldt
  BLACKLIST 155 pivot_root
  BLACKLIST 206 io_setup
  BLACKLIST 207 io_destroy
  BLACKLIST 208 io_getevents
  BLACKLIST 209 io_submit
  BLACKLIST 210 io_cancel
  BLACKLIST 216 remap_file_pages
  BLACKLIST 237 mbind
  BLACKLIST 239 get_mempolicy
  BLACKLIST 238 set_mempolicy
  BLACKLIST 256 migrate_pages
  BLACKLIST 279 move_pages
  BLACKLIST 278 vmsplice
  BLACKLIST 161 chroot
  BLACKLIST 184 tuxcall
  BLACKLIST 169 reboot
  BLACKLIST 180 nfsservctl
  BLACKLIST 177 get_kernel_syms
  RETURN_ALLOW

  root@ubunthin:/home/rcc# firejail --caps.print=ping
  chown               - enabled
  dac_override        - enabled
  dac_read_search     - enabled
  fowner              - enabled
  fsetid              - enabled
  kill                - enabled
  setgid              - enabled
  setuid              - enabled
  setpcap             - enabled
  linux_immutable     - enabled
  net_bind_service    - enabled
  net_broadcast       - enabled
  net_admin           - enabled
  net_raw             - enabled
  ipc_lock            - enabled
  ipc_owner           - enabled
  sys_module          - enabled
  sys_rawio           - enabled
  sys_chroot          - enabled
  sys_ptrace          - enabled
  sys_pacct           - enabled
  sys_admin           - enabled
  sys_boot            - enabled
  sys_nice            - enabled
  sys_resource        - enabled
  sys_time            - enabled
  sys_tty_config      - enabled
  mknod               - enabled
  lease               - enabled
  audit_write         - enabled
  audit_control       - enabled
  setfcap             - enabled
  mac_override        - enabled
  mac_admin           - enabled
  syslog              - enabled
  wake_alarm          - enabled
  block_suspend       - enabled
  audit_read          - enabled

Beim Durchgehen der Capabilities fragt sich, warum ping das Recht haben soll, einen Node auf dem Dateisystem zu erstellen. Grundsätzlich können wir sämtliche Capabilities bis auf CAP_NET_RAW entfernen, um alle unnötigen Zugriffe einzuschränken:

CAP_NET_RAW
  * use RAW and PACKET sockets;
  * bind to any address for transparent proxying.

Nun wieder Firejail starten:

root@ubunthin:/home/rcc# firejail --name=ping --caps.keep=net_raw ping 8.8.8.8

root@ubunthin:/home/rcc# firejail --list
12121:rcc:firejail --name=ping --caps.keep=net_raw ping 8.8.8.8

root@ubunthin:/home/rcc# firejail --caps.print=ping
...
net_admin           - disabled
net_raw             - enabled
ipc_lock            - disabled
...

Wir haben alle Capabilities bis auf CAP_NET_RAW entfernen lassen, wodurch der Aufruf der entsprechenden Syscalls verboten wird. Dennoch pflegt ping nach wie vor 23 Syscalls einzusetzen. Mittels seccomp-bpf ist es nun möglich, granulare Filter durchzusetzen und so eine Minimierung der Syscalls zu etablieren. Hierbei wird von einer Blacklist auf eine Whitelist gewechselt.

Um die Syscalls in die Whitelist zu übertragen, die von ping genutzt können werden sollen, wird ein strace auf die erforderlichen Syscalls angesetzt. Ein Blick in Syslog zeigt dann die Resultate:

root@ubunthin:/home/rcc# firejail --caps.keep=net_raw --shell=none --noprofile --debug --seccomp.keep=read,write,open,close,fstat,mmap,mprotect,munmap,brk,rt_sigaction,rt_sigprocmask,ioctl,access,setitimer,getpid,socket,connect,sendto,recvmsg,getsockname,setsockopt,getsockopt,execve,getuid,setuid,geteuid,capget,capset,prctl,arch_prctl,setresuid,setresgid,getgid,fcntl,clone,set_robust_list,stat,nanosleep,wait4,getdents,exit_group ping -c1 8.8.8.8

Syslog reklamiert den letzten Syscall als Problem (blocked by Firejail):

Aug  7 21:09:57 ubunthin firejail[28419]: firejail --shell=none --noprofile --seccomp.keep=read,write,open,close,fstat,mmap,mprotect,munmap,brk,rt_sigaction,rt_sigprocmask,ioctl,access,setitimer,getpid,socket,connect,sendto,recvmsg,getsockname,setsockopt,getsockopt,execve,getuid,setuid,geteuid,capget,capset,prctl,arch_prctl,setresuid,setresgid,getgid,fcntl --debug ping -c1 8.8.8.8
Aug  7 21:09:58 ubunthin kernel: [98202.176765] audit: type=1326 audit(1502132998.041:55): auid=1000 uid=0 gid=0 ses=2 pid=28420 comm="firejail" exe="/usr/bin/firejail" sig=31 arch=c000003e syscall=56 compat=0 ip=0x7ff72e5ca40a code=0x0
Aug  7 21:09:58 ubunthin firejail[28419]: exiting...

In diesem Fall versucht ping auf Syscall 56 zuzugreifen, der nicht in der Whitelist ist, wodurch Firejail den Prozess killt. Den Namen eines Syscalls anhand dessen Nummer kann mit folgender Eingabe herausgefunden werden:

root@ubunthin:/home/rcc# firejail --debug-syscalls | grep 56
56	- clone

Die Whitelist der Syscalls muss um clone and retry erweitert werden. Somit wird setresuid,setresgid,getgid,fcntl,clone,set_robust_list,stat,nanosleep,wait4,getdents,exit_group hinzugefügt:

root@ubunthin:/home/rcc# firejail --caps.keep=net_raw --shell=none --noprofile --debug --seccomp.keep=read,write,open,close,fstat,mmap,mprotect,munmap,brk,rt_sigaction,rt_sigprocmask,ioctl,access,setitimer,getpid,socket,connect,sendto,recvmsg,getsockname,setsockopt,getsockopt,execve,getuid,setuid,geteuid,capget,capset,prctl,arch_prctl,setresuid,setresgid,getgid,fcntl,clone,set_robust_list,stat,nanosleep,wait4,getdents,exit_group ping -c1 8.8.8.8
Command name #ping#
DISPLAY :0, 0
Enabling IPC namespace
Using the local network stack
Parent pid 28503, child pid 28504
The new log directory is /proc/28504/root/var/log
Initializing child process
Host network configured
PID namespace installed
Mounting tmpfs on /run/firejail/mnt directory
Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr, /etc, /var
Mounting tmpfs on /dev/shm
Mounting tmpfs on /var/lock
Mounting tmpfs on /var/tmp
Mounting tmpfs on /var/log
Mounting tmpfs on /var/lib/dhcp
Mounting tmpfs on /var/lib/snmp
Mounting tmpfs on /var/lib/sudo
Create the new utmp file
Mount the new utmp file
Remounting /proc and /proc/sys filesystems
Remounting /sys directory
Disable /sys/firmware
Disable /sys/hypervisor
Disable /sys/module
Disable /sys/power
Disable /sys/kernel/debug
Disable /sys/kernel/vmcoreinfo
Disable /sys/kernel/uevent_helper
Disable /proc/sys/fs/binfmt_misc
Disable /proc/sys/kernel/core_pattern
Disable /proc/sys/kernel/modprobe
Disable /proc/sysrq-trigger
Disable /proc/sys/kernel/hotplug
Disable /proc/sys/vm/panic_on_oom
Disable /proc/irq
Disable /proc/bus
Disable /proc/sched_debug
Disable /proc/timer_list
Disable /proc/timer_stats
Disable /proc/kcore
Disable /proc/kallsyms
Disable /lib/modules
Disable /usr/lib/debug
Disable /boot
Disable /dev/port
Disable /sys/fs
DISPLAY :0, 0
Set caps filter 2000
Ending syscall filter
SECCOMP Filter:
  VALIDATE_ARCHITECTURE
  EXAMINE_SYSCAL
  UNKNOWN ENTRY!!!
  UNKNOWN ENTRY!!!
  UNKNOWN ENTRY!!!
  WHITELIST 105 setuid
  WHITELIST 106 setgid
  WHITELIST 116 setgroups
  WHITELIST 32 dup
  WHITELIST 0 read
  WHITELIST 1 write
  WHITELIST 2 open
  WHITELIST 3 close
  WHITELIST 5 fstat
  WHITELIST 9 mmap
  WHITELIST 10 mprotect
  WHITELIST 11 munmap
  WHITELIST 12 brk
  WHITELIST 13 rt_sigaction
  WHITELIST 14 rt_sigprocmask
  WHITELIST 16 ioctl
  WHITELIST 21 access
  WHITELIST 38 setitimer
  WHITELIST 39 getpid
  WHITELIST 41 socket
  WHITELIST 42 connect
  WHITELIST 44 sendto
  WHITELIST 47 recvmsg
  WHITELIST 51 getsockname
  WHITELIST 54 setsockopt
  WHITELIST 55 getsockopt
  WHITELIST 59 execve
  WHITELIST 102 getuid
  WHITELIST 105 setuid
  WHITELIST 107 geteuid
  WHITELIST 125 capget
  WHITELIST 126 capset
  WHITELIST 157 prctl
  WHITELIST 158 arch_prctl
  WHITELIST 117 setresuid
  WHITELIST 119 setresgid
  WHITELIST 104 getgid
  WHITELIST 72 fcntl
  WHITELIST 56 clone
  WHITELIST 273 set_robust_list
  WHITELIST 4 stat
  WHITELIST 35 nanosleep
  WHITELIST 61 wait4
  WHITELIST 78 getdents
  WHITELIST 231 exit_group
  KILL_PROCESS
Save seccomp filter, size 784 bytes
seccomp enabled
Username root, no supplementary groups
starting application
LD_PRELOAD=(null)
execvp argument 0: ping
execvp argument 1: -c1
execvp argument 2: 8.8.8.8
Child process initialized
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
monitoring pid 2

64 bytes from 8.8.8.8: icmp_seq=1 ttl=45 time=28.6 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 28.614/28.614/28.614/0.000 ms
Sandbox monitor: waitpid 2 retval 2 status 0

Parent is shutting down, bye...

Jetzt können wir ein Profil für ping erstellen, wodurch die Exponiertheit im System gänzlich reduziert wird. Falls ping andere Zugriffe anstreben will, wird es unmittelbar gekillt.

Wo und wann Firejail einsetzen

Das Security In-Depth Paradigma erfordert verschiedene Schichten von Security-Controls. Falls eine versagt, kann die andere die Anforderungen durchsetzen.

Firejail kann als zusätzliche Line of Defense genutzt werden, vor allem im Zusammenhang mit Webbrowsern. Es kommt mit einigen vordefinierten Profilen daher und lässt sich so relativ einfach für zusätzliche Anwendungen einsetzen.

Ich benutze Firejail für Browsing, Software-Analyse und ausgewählte temporäre Einstellungen (z.B. DNS-spezifisch), um Installationen simulieren zu können.

Sandboxen vs. Container

Der Unterschied zwischen Sandboxen und Containern kann auf das Dateisystem reduziert werden:

Eine Sandbox funktioniert auf einem bestehenden Dateisystem, während ein Container ein eigenes Dateisystem hat.

Der Fokus auf Sicherheit der beiden Technologien unterscheidet sich:

Sandboxing fokussiert sich vollständig auf Sicherheit, während Container in erster Linie für Virtualisierung und Entwicklung eingesetzt wird.

In jedem Fall ist das eingesetzte Sicherheitsmodell das Gleiche. Das Verständnis für seccomp-bpf und Capabilities hilft dabei, ein Container-Environment (aka. Docker) absichern zu können.

Zusammenfassung

Das Absichern eines Computers endet nicht bei der Netzwerkschnittstelle. Einmal installierte und als vertrauenswürdig verstandene Software kann nach Belieben auf eine Vielzahl von Ressourcen zugreifen. Selbst dann, wenn es nicht erforderlich wäre (denken Sie dabei nur mal an X).

Diese Überexponiertheit muss vor allem bei Container-Technologien eine hohe Kritikalität beigemessen werden. Dort, wo Grenzen zwischen Ressourcen und Virtuellen Ressourcen verschwimmen.

Durch den Einsatz von Firejail kann ein Quickwin für sämtliche Applikationen, vor allem Browser ohne Sandboxing, erreicht werden. Es ist einfach zu nutzen und zu konfigurieren – Und der Impact auf das System ist sehr gering.

Tools

Andere empfohlene Tools:

Über den Autor

Rocco Gagliardi

Rocco Gagliardi ist seit den 1980er Jahren im Bereich der Informationstechnologie tätig. In den 1990er Jahren hat er sich ganz der Informationssicherheit verschrieben. Die Schwerpunkte seiner Arbeit liegen im Bereich Security Frameworks, Routing, Firewalling und Log Management.

Links

Sie wollen die Sicherheit Ihrer Firewall prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
Verbessern des Datenverständnisses

Verbessern des Datenverständnisses

Rocco Gagliardi

Übergang zu OpenSearch

Übergang zu OpenSearch

Rocco Gagliardi

Graylog v5

Graylog v5

Rocco Gagliardi

auditd

auditd

Rocco Gagliardi

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv