Using Firejail to sandbox applications in Linux


This guide shall let the reader be informed about the usage of firejail. Additionally, the reader shall be informed about how to use firejail profiles efficiently. Video and audio support are present and are excellent. At the end of the guide, the reader shall have the ability to run X11 applications in an arbitrary home folder using a custom configuration I made.

What is firejail? Why firejail?

I cannot explain Linux namespaces in a very good way, so I shall let this blogpost explain the purpose of firejail.

I did a blogpost on a similar tool called bubblewrap a while ago; however, bubblewrap has many limitations such as inefficiency in running Xorg applications, and the lack of other application support, such as PulseAudio. Bubblewrap is limited to small applications in the console, so I won’t expect anything much from it anyway.


Installation varies per distribution, but for Arch users, it is as simple as sudo pacman -S firejail .

Note: For Arch users, user namespaces are disabled by default. However, firejail should not care. For those who want to use user namespaces (such as those using bubblewrap at the same time), you may compile your own kernel, or install linux-hardened.

Post-installation configuration

Upon installation, firejail should configure itself, adding symbolic links in /usr/local/bin to /usr/bin/firejail.  The implications of this means that, for example, running Firefox by default would run it in a firejail instance automatically.

Man pages

The man pages for firejail and firejail-profile prove to be a very useful resource. From them you may create your own profiles, even without reading the rest of this blogpost.

Built-in configuration

As aforementioned, many applications already have built-in profiles. All profiles are listed in the folder /etc/firejail.

I highly encourage the reader to read on the man page for firejail-profile as linked earlier, and read default.profile and other profiles, because the assumption is that the reader knows which flags mean which.


Default profiles

All built-in profiles are in the folder /etc/firejail. For example, my default.profile looks like the following:

# Persistent local customizations
include /etc/firejail/default.local
# Persistent global definitions
include /etc/firejail/globals.local

# generic gui profile
# depending on your usage, you can enable some of the commands below:

include /etc/firejail/
# include /etc/firejail/
include /etc/firejail/
include /etc/firejail/

caps.drop all
# ipc-namespace
# no3d
# nodvd
# nogroups
# nosound
# notv
# novideo
protocol unix,inet,inet6
# shell none

# disable-mnt
# private
# private-bin program
# private-dev
# private-etc none
# private-lib
# private-tmp

# memory-deny-write-execute
# noexec ${HOME}
# noexec /tmp

The default.profile is the profile automatically used by firejail if the program does not have a custom profile in /etc/firejail or ~/.config/firejail.

Note that the default.profile has some include commands, whose configurations disable some commands, blacklist certain folders, etc. The reader is encouraged to inspect these files.

Also note that ampersands # denote comments, similar to those in the bash shell.

Choosing a custom profile

One can choose which profile firejail shall read from using the --profile flag. For example,

firejail --profile=~/env1.profile zsh

This shall be useful for us later.

Creating a custom profile

In our home folder, let us create a new profile for our, say, “environment”. Let us copy the default.profile to some folder in our home folder ~/firejail.

Let us lay down our goal: we want to create an isolated “environment”, with a non-default persistent home folder, say, in ~/firejail/env1, so that the current home folder ~ shall not be affected. Additionally, we also aim to be able to run various applications, such as those requiring Xorg, in this environment.

Our custom environment

We shall base our configuration with the built-in profiles in /etc/firejail. That is, default.profile. Additionally, we should also take note of profiles for graphical applications such as okular.profile and firefox.profile.

As aforementioned, let us create a profile env1.profile inside ~/firejail. Let us simply copy the contents of default.profile and change some lines.

Changing the home folder

The first thing to do is to change the ${HOME} folder, since we want our configuration and files to be isolated, but, at the same time, persistent. Let us add private ${HOME}/firejail/env1 in the lines before include /etc/firejail/

Blacklisting and disable inc files

We see in the first few lines some include commands. Similar to the #include preprocessor for those who know C-like languages, they signify that all lines in such .inc files should be run first.

  • contains commands related to blocking access in certain sensitive files in $HOME. It also blacklists many sensitive files in /var/ and /etc/. The downside of this is that we cannot run desktop environments in our environment.  However, since our $HOME is detached from the default home directory, we can just copy this up, remove all commands blacklisting files in $HOME, and carry on.
  • contains commands related to blocking access to development tools (such as g++ and gcc). Somehow, it also contains commands blocking access to python3 and python2, but fortunately these commands are commented out by default. Since it’s assumed that whatever programs we run would not compile arbitrary code, let us include this.
  • contains commands related to blocking access in files in $HOME related to password managers such as .config/keepass. Let us include this.
  • contains commands related to blacklisting most configuration files. However, since our $HOME is going to be separate, this is irrelevant. Let us comment this out.

Filesystem configuration

We have already configured isolating the $HOME directory, but what about other, sensitive files in our system? For example, the sandbox may have arbitrary access to /tmp, which is not the worst, but there are implications to a sandbox accessing the temporary files of my current instance of Firefox.

I added the flags private-tmp and private-dev to isolate both the /tmp and the /dev directories. Additionally, I also included disable-mnt to disable access to removable media and similar directories.

Other flags

I added the following flags in my profile.

  • caps.drop all is a very useful flag, and is a must for all applications which do not need root access (so, basically, everything that we’re going to run in our environment).
  • seccomp is another useful one, which is unquestionably a must.
  • noroot is useful, since we have no use for a root user.
  • x11 xpra is used to sandbox Xorg applications, and choosing the Xpra server (for seamless interaction with the entire computer). Note that you may use Xephyr by using x11 xephyr instead of x11 or x11 xpra. I shall choose not to.
  • I shall not use any flags for resource limitation. I can, but I shall choose not to for this environment.
  • nodvd is also useful for me, since I shall not use any external media for my environment.
  • notv is not required, but since I won’t use digital video broadcasting, might as well restrict the sandbox.
  • nogroups is also not required, but let’s add it so that the sandbox won’t know that we’re in group something.
  • nonewprivs is a must so that no pri
  • netfilter is a must for connecting to the Internet. For applications which should not be connected online, replace it with net none.

There are many more useful flags in the man pages (such as modifying the MAC address), but let’s stick with the above.

Our final configuration

The following is our final env1.profile. The custom is the same as the one available in /etc/firejail, but without the lines containing ${HOME}.

# Firejail profile for environment one: safe stuff with Internet

# Persistent local customizations
include /etc/firejail/default.local
# Persistent global definitions
include /etc/firejail/globals.local

# Change the home directory
private ${HOME}/firejail/env1

#include /etc/firejail/
include /etc/firejail/
include /etc/firejail/
#include /etc/firejail/

# Filesystem isolation

# Security stuff
caps.drop all
x11 xpra
protocol unix,inet,inet6

As aforementioned, X11 applications perform very terribly, but this is the effect of isolating the X11 server. Without isolation, X11 applications perform significantly  better. Of course, it is up to the user to either isolate the X11 server (by adding the x11 option), or not (by commenting it out). However, there are risks to doing so, such as malicious programs being able to track your keystrokes. The risk is present, but minimal in many cases.

Additionally, I forgot to mention that audio works in Firejail, so that’s a huge bonus.


There is nothing to conclude here, aside from the fact that Firejail is much easier, and much more of a breeze, to configure than other sandboxes such as bubblewrap.

Further reading

Firejail blog in WordPress

Man pages for firejail and firejail-profile

Firejail page in the ArchWiki

5 thoughts on “Using Firejail to sandbox applications in Linux

  1. How do I create a symbolic link manually to firejail? I have tried for example code: ln -s /usr/bin/program-name /usr/bin/firejail

    I receive a “file exists” error.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s