FOSS, linux, security

Sandbox your applications with Firejail

One thing I that like about the Android App security model is that for a given app, it presents the permissions to the user and the user has to accept them. This is good because the user has control over the software it runs, and is an invaluable tool to be able to use an App without granting it too much access without having to renounce to use it altogether.

Fortunately, the Linux world is a much more friendly environment in terms of malicious software. A big reason for this, is the fact that software is audited and curated by distro package maintainers. I recommend this interesting post on the subject.

Even the best written software can contain vulnerabilities that can be exploited. With the advent of container technologies, such as docker, flatpak or LXC, many have suggested to use them to isolate software from the rest of the system and in doing so mitigate the harm of possible breaches.

By sandboxing software this way, you get some more control over what it is capable of doing, effectively getting closer to the Android security model.

Some alternatives

Well, containers are just a buzzword, in the sense that they are really no first class citizens in Linux. There is no concept of container in the Linux kernel. Rather, containers are a smart combination of existing kernel techniques that help isolate parts of the system. The big contribution of container technologies is to make it easier to use this Linux features. There are others I have not tested, such as and runC.


Docker is the most prominent actor in this scenario. While docker security has improved greately the past few years, and you can use it to run contained graphical applications by mounting the X server socket, it seems an overkill to require a docker daemon to run firefox more securely.

Among other recent security improvements, docker now supports user namespaces, allowing to map the root user so that a priviledged process inside the containers runs as a normal user outside of it.

Also, as the docker daemon runs with root privileges, and it is a pretty big featureful piece of software, it expands the attack surface unnecessarily just to provide sandboxing. There has to be a better way.


We also can have look at bubblewrap from ProjectAtomic. It is derived from the Flatpak project, and compared to Docker it is designed to be run by user processes with no privileges, like desktop applications.

This kind of software is the focus of the Flatpak project, whereas Docker is designed towards servers, daemons, cloud and the whole IaaS thing.

For a regular, security conscious user it seems a bit too hard to manage and setup. Just have a look at the (always awesome) Arch Wiki page and see for yourself.

It is the smallest of the three and that is a benefit in terms of attack surface. The downside is that it does not cover and does not try to cover all scenarios, so it does not play well with pulseaudio, X11 or DBus. Bubblewrap designers argue that this is more secure, so Flatpak tries to make software such as Wayland aware of the sandbox.

In short, it does not play well with all software.


Finally, I would like to recommend Firejail, which is the one I use personally. It is easy to use, easy to install and configure, and it comes with a very nice set of configuration files for common software. If you want to get advanced, it has that too.

It tries to cover all software, so it is far more complex. This is seen by many as a bad thing because it is really hard to secure a complex SUID program. The benefit is that it will work easily with all your current software.

But before we learn how to use it, let’s see how these “sandboxes” work.

How do sandboxes work

As we mentioned before, the so called containers merely use some existing Linux features. All container technologies that I know build on top of these.

Linux namespaces

The Linux kernel has the concept of namespaces. These namespaces represent different views of different parts of the system.

For example, only if two processes run in the same file namespace they will be able to see the same file and directory tree and access to the same files. Files in other namespaces will be invisible and inaccesible to them.

There are 7 namespaces in Linux, such as the file namespace, the network namespace, the cgroup namespace, the user namespace, the pid namespace and so on. For instance, we can have two processes use the same network interface without being able to see each other (net namespace), or have different views of the pid tree or user ids (pid and uid namespaces).

We can see what namespaces are available in our system with

$ ls /proc/self/ns
cgroup  ipc  mnt  net  pid  pid_for_children  uts
Linux capabilities

Traditionally, Linux has had the concept of an all powerful root priveleged user. That user has unlimited powers and access to all parts of the system. SUID programs are allowed all these privileges even if run by an unprivileged user.

While there is a legitimate need for this in some situations, it is also dangerous and unnecessary. For instance, many will be surprised to know that the simple ping command requires access to raw sockets in order to send the ICMP packages.

Linux capabilities allows us to improve this black and white situation. We can limit what the root user is able to perform by indivilually setting its capabilities. Things such as chowning files, ignoring DAC permissions, changing the network configuration or killing processes can be determined individually for a given process.

Here is the complete list of capabilities. For instance, we can check the default capabilities of the ping executable with getcap.

$ getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep

Sandboxes often allow us to decide what capabilities we grant to a  privileged process, providing an extra level of control.

Seccomp filters

Most userspace processes need to interact with the kernel, even if we don’t realize it. There’s very few interesting things a program can do without access to files, network or standard output.

Userspace programs use kernel facilities through system calls. There are over 300 system calls in Linux. These are often used to try to exploit kernel bugs and escalate privileges, and needless to say, that most often userland software doesn’t need all of them.

seccomp-bpf is a feature of the kernel that allows us to use BPF filters, to specify what syscalls are we allowing for our processes.

If a program is a text processor, why would it need access to the network? we can control that.

Firejail basic usage

Now that we understand the basics, let’s see how to use Firejail.

Install the package from your distro repository and you are ready to go.

If you want to run a sandboxed program, just run the command after firejail

$ firejail program_name

It supports one time flags, such as —seccomp to filter system calls, or –private in order to hide even the home folder from the process.

Do you want some private square browsing?

$ firejail --private firefox --private window
The contents of my home folder are invisible to Firefox

For more granular control, a profile configuration file can be used, but creating one is rarely needed. Firejail comes with a nice set of preconfigured profiles that you can find in /etc/firejail

ls /etc/firejail/                                                                                                                                                                                                   2.12 L  ✓ 
0ad.profile               clementine.profile      feh.profile                   google-chrome-unstable.profile            konversation.profile       neverball.profile           seamonkey-bin.profile        viewnior.profile
2048-qt.profile           clipit.profile          file-roller.profile           google-chrome.profile                     ktorrent.profile                  seamonkey.profile            viking.profile
7z.profile                cmus.profile            file.profile                  google-play-music-desktop-player.profile  kwrite.profile             nylas.profile               server.profile               vim.profile
Cryptocat.profile         conkeror.profile        filezilla.profile             gpa.profile                               leafpad.profile            obs.profile                 silentarmy.profile           virtualbox.profile
Cyberfox.profile          corebird.profile        firefox-esr.profile           gpg-agent.profile                         less.profile               odt2txt.profile             simple-scan.profile          vivaldi-beta.profile
FossaMail.profile         cpio.profile            firefox-nightly.profile       gpg.profile                               libreoffice.profile        okular.profile              simutrans.profile            vivaldi-stable.profile
Gitter.profile            cryptocat.profile       firefox.profile               gpicview.profile                          liferea.profile            open-invaders.profile       skanlite.profile             vivaldi.profile
Mathematica.profile       curl.profile            firejail.config               gpredict.profile                          localc.profile             openbox.profile             skype.profile                vlc.profile
Telegram.profile          cvlc.profile            flashpeak-slimjet.profile     gtar.profile                              lodraw.profile             openshot.profile            skypeforlinux.profile        vym.profile
Thunar.profile            cyberfox.profile        flowblade.profile             gthumb.profile                            loffice.profile            opera-beta.profile          slack.profile                w3m.profile
VirtualBox.profile        darktable.profile       fontforge.profile             guayadeque.profile                        lofromtemplate.profile     opera.profile               smplayer.profile             warzone2100.profile
Wire.profile              deadbeef.profile        fossamail.profile             gucharmap.profile                         login.users                orage.profile               snap.profile                 waterfox.profile
Xephyr.profile            default.profile         franz.profile                 gwenview.profile                          loimpress.profile          palemoon.profile            soffice.profile    
Xvfb.profile              deluge.profile          frozen-bubble.profile         gzip.profile                              lollypop.profile           parole.profile              soundconverter.profile       weechat-curses.profile
abrowser.profile          dex2jar.profile         gajim.profile                 handbrake-gtk.profile                     lomath.profile             pcmanfm.profile             spotify.profile              weechat.profile
akregator.profile         dia.profile             galculator.profile            handbrake.profile                         loweb.profile              pdfsam.profile              sqlitebrowser.profile        wesnoth.profile
amarok.profile            digikam.profile         geany.profile                 hashcat.profile                           lowriter.profile           pdftotext.profile           ssh-agent.profile            wget.profile
android-studio.profile    dillo.profile           geary.profile                 hedgewars.profile                         luminance-hdr.profile      peek.profile                ssh.profile        
apktool.profile           dino.profile            gedit.profile                 hexchat.profile                           lximage-qt.profile         picard.profile              start-tor-browser.profile    wine.profile
arduino.profile       geeqie.profile                highlight.profile                         lxmusic.profile            pidgin.profile              steam.profile                wire.profile
ark.profile            ghb.profile                   hugin.profile                             lxterminal.profile         pingus.profile              stellarium.profile           wireshark-gtk.profile
arm.profile        gimp-2.8.profile              icecat.profile                            lynx.profile               pithos.profile              strings.profile              wireshark-qt.profile
atom-beta.profile    gimp.profile                  icedove.profile                           mate-calc.profile          pix.profile                 supertux2.profile            wireshark.profile
atom.profile              display.profile         git.profile                   iceweasel.profile                         mate-calculator.profile    pluma.profile               synfigstudio.profile         xchat.profile
atool.profile             dnscrypt-proxy.profile  gitg.profile                                   mate-color-select.profile  polari.profile              tar.profile                  xed.profile
atril.profile             dnsmasq.profile         gitter.profile                img2txt.profile                           mate-dictionary.profile    psi-plus.profile            telegram-desktop.profile     xfburn.profile
audacious.profile         dolphin.profile         gjs.profile                   inkscape.profile                          mathematica.profile        qbittorrent.profile         telegram.profile             xfce4-dict.profile
audacity.profile          dosbox.profile          globaltime.profile            inox.profile                              mcabber.profile            qemu-launcher.profile       thunar.profile               xfce4-notes.profile
aweather.profile          dragon.profile          gnome-2048.profile            iridium-browser.profile                   mediainfo.profile          qemu-system-x86_64.profile  thunderbird.profile          xiphos.profile
baloo_file.profile         dropbox.profile         gnome-books.profile           iridium.profile                           mediathekview.profile      qlipper.profile             torbrowser-launcher.profile  xmms.profile
baobab.profile            ebook-viewer.profile    gnome-calculator.profile      itch.profile                              meld.profile               qpdfview.profile            totem.profile                xonotic-glx.profile
bibletime.profile         electron.profile        gnome-chess.profile           jd-gui.profile                            midori.profile             qtox.profile                tracker.profile              xonotic-sdl.profile
bitlbee.profile           elinks.profile          gnome-clocks.profile          jitsi.profile                             minetest.profile           quassel.profile             transmission-cli.profile     xonotic.profile
bleachbit.profile         emacs.profile           gnome-contacts.profile        k3b.profile                               mousepad.profile           quiterss.profile            transmission-gtk.profile     xpdf.profile
blender.profile           empathy.profile         gnome-documents.profile       kate.profile                              mplayer.profile            qupzilla.profile            transmission-qt.profile      xplayer.profile
bless.profile             enchant.profile         gnome-font-viewer.profile     kcalc.profile                             mpv.profile                qutebrowser.profile         transmission-show.profile    xpra.profile
brasero.profile           engrampa.profile        gnome-maps.profile            keepass.profile                           multimc5.profile           rambox.profile              truecraft.profile            xreader.profile
brave.profile             eog.profile             gnome-mplayer.profile         keepass2.profile                          mumble.profile             ranger.profile              tuxguitar.profile            xviewer.profile
caja.profile              eom.profile             gnome-music.profile           keepassx.profile                          mupdf.profile              remmina.profile             uget-gtk.profile             xz.profile
calibre.profile           epiphany.profile        gnome-photos.profile          keepassx2.profile                         mupen64plus.profile        rhythmbox.profile           unbound.profile              xzdec.profile
catfish.profile            etr.profile             gnome-twitch.profile          keepassxc.profile                         musescore.profile          riot-web.profile            unknown-horizons.profile     yandex-browser.profile
cherrytree.profile        evince.profile          gnome-weather.profile         kino.profile                              mutt.profile               ristretto.profile           unrar.profile                youtube-dl.profile
chromium-browser.profile  evolution.profile       goobox.profile                kmail.profile                             nautilus.profile           rtorrent.profile            unzip.profile                zathura.profile
chromium.profile          exiftool.profile        google-chrome-beta.profile    knotes.profile                            nemo.profile               scribus.profile             uudeview.profile             zoom.profile
claws-mail.profile        fbreader.profile        google-chrome-stable.profile  kodi.profile                              netsurf.profile            sdat2img.profile            uzbl-browser.profile

It becomes a hassle to always prepend firejail to your commands, so you can easily configure your system to firejail everything you have a profile for. The command

$ sudo firecfg
Configuring symlinks in /usr/local/bin
   audacious created
   audacity created
   brasero created
   cvlc created
   display created
   dnsmasq created
   evince created
   feh created
   filezilla created
   firefox created
   ghb created
   gimp created
   gimp-2.8 created
   gitg created
   gthumb created
   img2txt created
   inkscape created
   k3b created
   keepassxc created
   less created
   libreoffice created
   localc created
   lodraw created
   loffice created
   lofromtemplate created
   loimpress created
   lomath created
   loweb created
   lowriter created
   meld created
   mplayer created
   pdftotext created
   pidgin created
   simple-scan created
   soffice created
   ssh created
   ssh-agent created
   strings created
   telegram-desktop created
   tracker created
   transmission-gtk created
   vlc created
   wget created
   wireshark-gtk created

will create symlinks in /usr/local/bin for programs that exist in the profile folder, so that they will be opened by firejail.

Also, it comes with desktop integration, and a widget called firetools

You can create your symlinks to use firejail with any other program

$ sudo ln -s /usr/bin/firejail /usr/local/bin/<program name>

Sometimes, you want to run the program without the sandbox only once. For instance, you might want to use meld in arbitrary paths. Instead of editing the profile, you can just find the binary

$ which -a meld

, and knowing that the one in /usr/local/bin is the symlink, we can just invoke it as

$ /usr/bin/meld

Firejail advanced usage

You can check what applications you have sandboxed with

$ firejail --list
738:nacho:firejail --list
26599:nacho:firejail /usr/bin/filezilla
30047:nacho:/usr/bin/firejail /usr/bin/keepassxc
31180:nacho:/usr/bin/firejail /usr/bin/firefox

Likewise, you can inspect processes inside a sandbox with

$ firejail --tree
2126:nacho:/usr/bin/firejail /usr/bin/firefox
  2140:nacho:/usr/bin/firejail /usr/bin/firefox
2129:nacho:/usr/bin/firejail /usr/bin/mumble
  2145:nacho:/usr/bin/firejail /usr/bin/mumble
2131:nacho:/usr/bin/firejail /usr/bin/thunderbird
  2152:nacho:/usr/bin/firejail /usr/bin/thunderbird
3286:nacho:gpg-agent --homedir /home/nacho/.gnupg --use-standard-socket --daemon
2738:nacho:/usr/bin/firejail /usr/bin/keepassxc
  2739:nacho:/usr/bin/firejail /usr/bin/keepassxc

or monitor resources with –top or –netstats

$firejail --top
PID   User      RES(KiB) SHR(KiB) CPU%  Prcs Uptime    Command
26599 nacho     59236    44404    13.0  3    00:07:33  firejail /usr/bin/filezilla 
31180 nacho     761036   132316   12.0  3    00:02:14  firejail /usr/bin/firefox 
369   nacho     2192     1940     0.0   1    00:00:09  firejail --top 
30047 nacho     76340    56716    0.0   3    00:03:10  firejail /usr/bin/keepassxc

You can copy files in and out of the sandbox with –ls, –put and –get

$ firejail --name=mybrowser --private firefox

$ firejail --ls=mybrowser ~/Downloads
drwxr-xr-x netblue  netblue         4096 .
drwxr-xr-x netblue  netblue         4096 ..
-rw-r--r-- netblue  netblue         7847 x11-x305.png
-rw-r--r-- netblue  netblue         6800 x11-x642.png
-rw-r--r-- netblue  netblue        34139 xpra-clipboard.png

$ firejail --get=mybrowser ~/Downloads/xpra-clipboard.png

$ firejail --put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png

You can traffic shape with –bandwidth ( download/upload 80KBps/20KBps )

firejail --bandwidth=mybrowser set eth0 80 20

You can even shell inside the sandbox with –join, in a similar way as doing docker exec -ti container bash

Other cool options are –disable-mnt which is self-explanatory and –chroot=dirname which will mount dirname read only.

The man pages contain excelent information.

Playing around

We can check our current namespaces with

$ lsns

4026531835 cgroup 75 592 nacho /usr/lib/systemd/systemd --user
4026531836 pid 74 592 nacho /usr/lib/systemd/systemd --user
4026531838 uts 70 592 nacho /usr/lib/systemd/systemd --user
4026531839 ipc 74 592 nacho /usr/lib/systemd/systemd --user
4026531840 mnt 70 592 nacho /usr/lib/systemd/systemd --user
4026531993 net 75 592 nacho /usr/lib/systemd/systemd --user
4026532421 mnt 1 2201 nacho /usr/lib/firefox/firefox
4026532422 uts 1 2201 nacho /usr/lib/firefox/firefox
4026532423 pid 1 2201 nacho /usr/lib/firefox/firefox
4026532424 mnt 1 2221 nacho /usr/bin/mumble
4026532425 uts 1 2221 nacho /usr/bin/mumble
4026532426 pid 2 2221 nacho /usr/bin/mumble
4026532487 mnt 2 2225 nacho /usr/lib/thunderbird/thunderbird
4026532488 uts 2 2225 nacho /usr/lib/thunderbird/thunderbird
4026532489 pid 2 2225 nacho /usr/lib/thunderbird/thunderbird
4026532633 mnt 1 2266 nacho /usr/bin/ssh -Y xxxx@xxxxx.xxxx

, and elevated capabilities with

$ pscap
ppid pid name command capabilities
1 266 root systemd-journal chown, dac_override, dac_read_search, fowner, setgid, setuid, sys_ptrace, sys_admin, audit_control, mac_override, syslog, audit_read
1 286 root systemd-udevd full
1 431 root systemd-logind chown, dac_override, dac_read_search, fowner, kill, sys_admin, sys_tty_config, audit_control, mac_admin
1 432 root dockerd full
1 441 root login full
432 450 root docker-containe full
1 732 rtkit rtkit-daemon dac_read_search, sys_ptrace, sys_nice
1 2984 root udisksd full
450 4405 root docker-containe full
4405 4423 root bash chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap
15942 8107 root sudo full
8107 8122 root wpa_supplicant full
1 10113 root upowerd full
450 10710 root docker-containe full
10710 10727 root full
10727 10814 root nginx full
10814 10815 root nginx full
10814 10816 root nginx full
10814 10817 root nginx full
10814 10819 root nginx full
10814 10820 root nginx full
10814 10821 root nginx full
10814 10822 root nginx full
10814 10823 root nginx full
10727 10830 root php5-fpm full
10727 10834 root nxlog full
10727 10835 root ntpd full
10727 10837 root mysqld full
10727 10842 root sshd full
10727 10847 root in.tftpd full
450 10925 root docker-containe full
10925 10946 root script full
10946 10953 root sh full
10953 10954 root bash full
1 17653 root systemd-hostnam sys_admin
10727 18157 root sleep full
450 21275 root docker-containe full
21275 21291 root bash chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap

Obviously, only priviledged processes are susceptible of having capabilities in the first place, so no user processes on that list.

We can run wireshark with sudo in order for it to have access to the network interfaces. This is a bad idea: permissions should be set properly to avoid this, but we will do it for the sake of the example

$ sudo /usr/bin/wireshark

$ pscap | grep wireshark

26219 26221 root wireshark-gtk full

We can compare that to running it in a sandbox, where it has dropped all capabilities that it doesn’t need

$ sudo firejail wireshark-gtk

$ pscap | grep wireshark

26803 26817 root wireshark-gtk dac_override, net_admin, net_raw



For more advanced configuration options, including writing and auditing profiles, I usually refer to the following sites.

Arch wiki

Firejail home page

Author: nachoparker

Humbly sharing things that I find useful [ github dockerhub ]


Leave a Reply

Your email address will not be published. Required fields are marked *