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 Sandstorm.io and runC.

Docker

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.

Bubblewrap

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.

Firejail

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

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.

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

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?

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

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

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

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

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

Firejail advanced usage

You can check what applications you have sandboxed with

Likewise, you can inspect processes inside a sandbox with

or monitor resources with –top or –netstats

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

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

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

, and elevated capabilities with

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

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

 

References

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

Arch wiki

Firejail home page

https://www.linux.com/news/understanding-and-securing-linux-namespaces

Author: nachoparker

Humbly sharing things that I find useful
[ github dockerhub ]

2 Comments on “Sandbox your applications with Firejail

Leave a Reply

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