Basic Usage


     Running Programs
     Private Mode
     Listing Sandboxes and Processes
     Joining an Existing Sandbox
     Direct Network Setup
     Routed Network Setup
     Traffic shaping


Running Programs

We try to make security simple. Forget about steep learning curves and enterprise-level skills, just prefix your application with “firejail” and run it:

$ firejail firefox
Reading profile /etc/firejail/firefox.profile
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Blacklist violations are logged to syslog
Child process initialized

The sandbox consists of a filesystem container built “on the fly” and four security filters: seccomp, network protocol, noroot user namespace, and a Linux capability filter.

In a more general way, the command format is as follows:

$ firejail [options] program_and_arguments

Without any arguments, Firejail starts a regular /bin/bash shell. Only the bash session and its descendants are visible inside the sandbox:

$ firejail 
Reading profile /etc/firejail/default.profile
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Reading profile /etc/firejail/

** Note: you can use --noprofile to disable generic.profile **

Parent pid 3908, child pid 3909
Child process initialized
[netblue@debian ~]$ ps aux
65534        1  0.0  0.0  15916  1616 pts/1    S    08:54   0:00 firejail
netblue      2  1.2  0.0  21052  5188 pts/1    S    08:54   0:00 /bin/bash
netblue     45  0.0  0.0  16848  2344 pts/1    R+   08:54   0:00 ps aux
[netblue@debian ~]$ 

Any type of GUI programs should work. Sound, video and hardware acceleration available on the host platform, should also be available in the sandbox. This makes Firejail ideal for running untrusted programs such as Google Chrome, Dropbox, Skype, Adobe Reader, games.


Private Mode

Private mode is a quick way of hiding all the files in your home directory from sandboxed programs. It is enabled using –private command line option:

$ firejail --private program_and_arguments

Firejail mounts a temporary tmpfs filesystem on top of /home/user directory. Any files created in this directory will be deleted once the sandbox exits. You can also use an existing directory as home directory for your sandbox, allowing you to have a persistent sandbox home:

$ firejail --private=~/my_private_dir program_and_arguments


Start your servers the same way you would start your desktop applications. Most servers are running as root, so you’ll need to be root when you start them:

# firejail /etc/init.d/apache2 start
# firejail --net=eth0 --ip= /etc/init.d/nginx start

This document describes a full WordPress setup in a jailed environment.


Listing Sandboxes and Processes

Called with –list option, Firejail lists all running sandboxes:

$ firejail --list
3787:netblue:firejail --private 
3860:netblue:firejail iceweasel 
3963:root:firejail /etc/init.d/nginx start

Each line represents a sandbox. The format for the information is PID:user name:command.

Called with –tree option, Firejail prints the process tree for each sandbox:

$ firejail --tree
3787:netblue:firejail --private 
3860:netblue:firejail iceweasel 
3963:root:firejail /etc/init.d/nginx start 
  3964:root:/bin/bash -c /etc/init.d/nginx start
    3969:root:nginx: master process /usr/sbin/nginx
      3970:www-data:nginx: worker process
      3971:www-data:nginx: worker process
      3973:www-data:nginx: worker process
      3974:www-data:nginx: worker process

–top option is like the regular process top command in Linux:

$ firejail --top
PID   User      RES(KiB) SHR(KiB) CPU%  Prcs Uptime    Command
3860  netblue   333388   36212    1.2   2    00:12:49  firejail iceweasel 
3787  netblue   5404     3116     0.0   3    00:14:18  firejail --private 
3963  root      11532    4860     0.0   8    00:11:40  firejail /etc/init.d/nginx start

Joining an existing sandbox

Sometimes we need to join an already running sandbox and modify the filesystem, the network parameters, or do some other admin work. We start by finding the PID of the sandbox (–list option), and pass this PID to Firejail (–join option):

$ firejail --list
3787:netblue:firejail --private 
3860:netblue:firejail iceweasel 
3963:root:firejail /etc/init.d/nginx start

$ firejail --join=3860
Switching to pid 3861, the first child process inside the sandbox

[netblue@debian ~]$ ps aux
netblue      1 12.1  4.5 996168 320576 ?       Sl   07:33   1:59 iceweasel
netblue     77  2.5  0.0  20916  3716 pts/2    S    07:49   0:00 /bin/bash
netblue    120  0.0  0.0  16840  1256 pts/2    R+   07:49   0:00 ps aux

[netblue@debian ~]$ 

It works like a regular terminal login in the sandbox. The new shell session inserted in the sandbox has all the restrictions the processes running in the sandbox have, including seccomp and Linux capabilities.


Direct Network Setup

A network namespace is a separate TCP/IP stack attached to the sandbox. The new stack has its own socket space, ARP and route tables, a separate netfilter/iptables firewall, and its own set of interfaces created using –net command line option. The sandbox is connected to the network using a kernel macvlan device (direct setup) or using a bridge device (bridged or routed setups).

Direct setup:

Direct network

Direct network

$ firejail --net=eth0 firefox
Reading profile /etc/firejail/firefox.profile
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Reading profile /etc/firejail/
Parent pid 4042, child pid 4043
Blacklist violations are logged to syslog

Interface        MAC                IP               Mask             Status
lo                                UP    
eth0-4042        f2:c8:11:f4:bb:0f    UP    
Default gateway

Child process initialized

In this example, the sandbox creates a new TCP/IP stack for our Mozilla Firefox session, assigns an IP address, and installs a browser-specific iptable filter.

Another interesting networking option is –net=none. This attaches the sandbox to a new, unconnected network stack, preventing any network access. Example:

$ firejail --net=none vlc

Routed Network Setup

In a routed setup sandboxes are connected to a Linux bridge, and the bridge traffic is routed by the host. Address translation needs to be enabled in host netfilter module in order for the sandbox traffic to go out on Internet:


Script for setting this up:

# Routed network configuration script
# bridge setup
brctl addbr br0
ifconfig br0 up
# enable ipv4 forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
# netfilter cleanup
iptables --flush
iptables -t nat -F
iptables -X
iptables -Z
iptables -P INPUT ACCEPT
# netfilter NAT
iptables -t nat -A POSTROUTING -o eth0 -s  -j MASQUERADE

Starting the sandbox:

$ firejail --net=br0 firefox

For running servers, network address translation is replaced by port forwarding:

# host port 80 forwarded to sandbox port 80
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to

Starting Apache server:

# firejail --net=br0 --ip= /etc/init.d/apache2 start

Traffic shaping

Network bandwidth is an expensive resource shared among all sandboxes running on a system. Traffic shaping allows the user to increase network performance by controlling the amount of data that flows into and out of sandboxes. Firejail implements a simple rate-limiting shaper based on Linux tc command. The shaper works at sandbox level:

$ firejail --name=browser --net=eth0 firefox &
$ firejail --bandwidth=browser set eth0 80 20

In this example we set a bandwidth of 80 kilobytes per second on receive side and a bandwidth of 20 kilobytes per second on transmit side. As the sandbox is running, we can change the values or even reset them:

$ firejail --bandwidth=browser set eth0 40 10
$ firejail --bandwidth=browser clear eth0

4 thoughts on “Basic Usage

  1. Robert

    Hi netblue30

    Do you have any pointers to getting firejail runing under (Debian 8) systemd?

    I currently have transmission-daemon running fine under systemd at system startup and I can successfully run firejail + transmission-daemon as a background task from the command line (subject to a few tweaks regarding location of config files) but I simply cannot get firejail + transmission-daemon to work together under systemd. If there is any documentation on the subject of firejail and systemd, please let me know.


    1. netblue30 Post author

      Start by locating the service file. I just installed transmission-daemon on a Debian 8 computer, the file seems to be /etc/systemd/system/

      Open the file and on “ExecStart” line add firejail. You will also need to add a profile file, I think /etc/firejail/transmission-gtk.profile will work. So, your ExecStart line would look like this:

      ExecStart=firejail –profile=/etc/firejail/transmission-gtk.profile /usr/bin/transmission-daemon -f –log-error


  2. Robert

    Hi netblue31,

    It’s always difficult to know where to pitch a first post where things could become quite involved, so my default is always to ask for direction to the relevant documentation, if available. That way, the workload is on me, rather than you, and I can read it and try things out without resorting to a to-and-fro session of questions and answers.

    While I’ll freely admit that I’m still learning about systemd, I’ve already tried the (logical) option of prefixing the ExecStart line with /usr/bin/firejail. I even created a transmission-daemon.profile and tweaked the location of the config files, but transmission-daemon still fails without a clear reason as to why.

    Feb 19 11:13:57 megat firejail[18624]: #033]0;firejail /usr/bin/transmission-daemon -f #007Child process initialized
    Feb 19 11:13:57 megat firejail[18624]: Parent pid 18624, child pid 18625
    Feb 19 11:13:57 megat firejail[18624]: Parent is shutting down, bye…
    Feb 19 11:13:57 megat systemd[1]: transmission-daemon.service: Main process exited, code=exited, status=1/FAILURE

    Part of the problem is likely to be down to my transmission-daemon.profile needing some tweaking but I’m hitting a fundamental issue that seems to be systemd-related and is blocking my attempts at debugging.

    So, instead of running with a modified copy of the transmission-gtk.profile, I tried running with the –noprofile option, to keep things as simple as possible. The system log file then get spammed wuth this message:

    Feb 19 11:28:39 megat systemd[1]: transmission-daemon.service: Got notification message from PID 18737, but reception only permitted for main PID 18734

    that gets repeated every second until some timeout mechanism intervenes.

    Those process ids are as follows:

    user@megat:~$ ps -ef|grep [t]ransmission
    root 18731 18547 0 11:27 pts/0 00:00:00 sudo systemctl start transmission-daemon
    root 18732 18731 0 11:27 pts/0 00:00:00 systemctl start transmission-daemon
    debian-+ 18734 1 0 11:27 ? 00:00:00 /usr/bin/firejail –noprofile /usr/bin/transmission-daemon -f
    debian-+ 18735 18734 0 11:27 ? 00:00:00 /usr/bin/firejail –noprofile /usr/bin/transmission-daemon -f
    debian-+ 18737 18735 0 11:27 ? 00:00:00 /usr/bin/transmission-daemon -f

    So the transmission-daemon [PID 18737] is trying to send some notification but systemd only permits notification from PID 18734. Thus the information never makes it to the system log. Unfortunately, adding the transmission options -e /tmp/translog -log-debug to the command line doesn’t write anything (or even create the file).

    Systemd seems to be a very different beast from the traditional init. As I said in my initial post, systemd + transmission-daemon works fine, as does firejail + transmission-daemon. Systemd + firejail + transmission-daemon is the problem combination. I have tried many different combinations but so far to no avail.It might simply be my lack of systemd knowledge but I’ve hit the stops for now.


  3. songo

    Thanks for this program, I like it
    one thing, when i use with firefox ( firejail firefox -no-remote) sometimes I see this

    1487853543335 addons.update-checker WARN Update manifest for did not contain an updates property
    1487853543350 addons.update-checker WARN Update manifest for did not contain an updates property
    1487853543366 addons.update-checker WARN Update manifest for did not contain an updates property
    1487853543417 addons.update-checker WARN Update manifest for did not contain an updates property
    1487853543596 addons.update-checker WARN Update manifest for {972ce4c6-7e08-4474-a285-3208198ce6fd} did not contain an updates property
    1487853543642 addons.update-checker WARN Update manifest for did not contain an updates property
    1487853543769 addons.update-checker WARN Update manifest for did not contain an updates property
    1487853543803 addons.update-checker WARN Update manifest for did not contain an updates property

    What is this?
    Many Thanks



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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s