Firejail Usage

 

Contents:
     Running Programs
     Running Mozilla Firefox
     Running a chroot Sandbox
     Networked Sandboxes
     Servers
     Process Monitoring
     Joining an Existing Sandbox
     Sandboxing Users at Login Time

 

Running Programs

$ firejail [options] program_and_arguments

Example:

$ firejail netstat -rn
Parent pid 7961, child pid 7962
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                192.168.1.50        255.255.255.0       UP                  

Child process initialized
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0

parent is shutting down, bye...
$

Fierjail configures a basic sandbox, runs the program and exits. The sandbox consists of a mount namespace and a new process namespace. In the mount namespace, the main system directories are mounted read-only.

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

$ firejail
Parent pid 8037, child pid 8038
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                192.168.1.50        255.255.255.0       UP                  

Child process initialized
[netblue@debian ~]$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
netblue      1  8.0  0.4  21004  3724 pts/0    S    09:56   0:00 /bin/bash
netblue     44  0.0  0.1  16836  1196 pts/0    R+   09:56   0:00 ps aux
[netblue@debian ~]$ 

 

Running Mozilla Firefox

The command to start Mozilla Firefox is firejail firefox. You can use –debug flag to get status messages as the sandbox is created:

$ firejail --debug firefox
Creating /tmp/firejail-8092-b85p9S directory
Parent pid 8092, child pid 8093
Initializing child process
PID namespace installed
Mounting read-only /bin, /sbin, /lib, /lib64, /usr, /boot, /etc, /var
/var/run is a symbolic link to /run
/dev/shm is a symbolic link to /run/shm
Mounting tmpfs on /run directory
Mounting tmpfs on /run/shm
Found firefox profile in /etc/firejail directory
Disabling /sbin
Disabling /usr/sbin
Disabling /boot
Disabling /bin/umount
Disabling /bin/mount
Disabling /bin/fusermount
Disabling /bin/su
Disabling /usr/bin/sudo
Disabling /usr/bin/xinput
Disabling /usr/bin/strace
Disabling /home/netblue/.ssh
Disabling /home/netblue/.gnome2/keyrings
Disabling /home/netblue/.adobe
Disabling /home/netblue/.macromedia
Disabling /home/netblue/.local/share/recently-used.xbel
Remounting /proc and /proc/sys filesystems
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                192.168.1.50        255.255.255.0       UP                  

Starting firefox 
Child process initialized
Background starting...

The sandbox above mounts read-only the main filesystem directories, and disables /sbin, /usr/sbin and /boot. It also disables some SUID executables such as mount and su. Several user files and directories storing encryption keys and certificates are also blocked. An attacker gaining control of the browser will have no access to these files. Firejail also restricts the processes visible in the sandbox, making Firefox PID 1.

 

Running a chroot Sandbox

Firejail allows you to mount a previously build root filesystem using –chroot option. The filesystem can be a full Linux distribution installed on a different disk partition, a filesystem build using regular distro tools such as debootstrap, or even a filesystem extracted from an OpenVZ template.

This is how you create a sandbox for a Debian filesystem. As root, start by running debootstrap in a new directory:

# mkdir /imgs && cd /imgs
# debootstrap --arch=amd64 jessie jessie

Start the sandbox:

# firejail --chroot=/imgs/jessie --name=jessie
Parent pid 21466, child pid 21467
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                192.168.1.50        255.255.255.0       UP                  

Child process initialized
[root@jessie ~]$  
 

Networked Sandboxes

A network namespace is basically a new TCP/IP stack attached to the sandbox. The sandbox connects to the host stack on a regular kernel bridge device.

Network setup

Network setup

In this example vm1 sandbox connects to the host br0 bridge. br0 needs to be created and configured before vm1 sandbox is started using –net=br0:

(as root)
# brctl addbr br0
# ifconfig br0 10.10.20.1

(as regular user)
$ firejail --net=br0 --ip=10.10.20.10
Parent pid 14749, child pid 14750
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                10.10.20.10         255.255.255.0       DOWN                

Child process initialized
[netblue@debian ~]$ 

If no IP address is specified, Firejail will find one not in use on bridge br0 and assign it to the sandbox:

$ firejail --net=br0
Parent pid 14817, child pid 14818
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                10.10.20.69         255.255.255.0       UP                  

Child process initialized
[netblue@debian ~]$ 

Specific IP addresses are set using –ip option.

$ firejail --net=br0 --ip=10.10.20.10
Parent pid 5347, child pid 5348
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                10.10.20.10         255.255.255.0       UP                

Child process initialized
[netblue@debian ~]$ 

Up to four networks can be specified using –net option. Other networking options are –noip used mainly for DHCP setups, and –defaultgw to specify a default gateway.

 

Servers

Use sleep inf to keep Firejail sessions alive while running daemons:

# firejail "/etc/init.d/lighttpd start && sleep inf"
# firejail --net=br0 "/etc/init.d/ssh start && sleep inf"
 

Process Monitoring

Called with –list option, Firejail will print a list of all processes running in sandboxes:

$ firejail --list
2767:root:firejail firefox 
  2768:netblue:iceweasel 
    14401:netblue:/usr/lib/iceweasel/xulrunner/plugin-container /usr/lib/...
14167:root:firejail 
  14168:netblue:/bin/bash 
$

Each line represents a process. The format for the information is PID:user name:command. All the process creation, exit, forks and uid/guid changes can be monitored using firemon utility. root privileges are required to run firemon. The next example shows Mozilla Firefox starting Adobe Flash Player plugin as captured by firemon:

# firemon
2767:root:firejail firefox 
  2768:netblue:iceweasel 
    14401:netblue:/usr/lib/iceweasel/xulrunner/plugin-container /usr/lib/...
14167:root:firejail 
  14168:netblue:/bin/bash 

17:53:20 fork 2768 (netblue) iceweasel 
	child 14401 iceweasel 
17:53:20 exec 14401 (netblue) /usr/lib/iceweasel/xulrunner/plugin-container /usr/lib/flashplugin-nonfree/libflashplayer.so -greomni /usr/lib/iceweasel/xulrunner/omni.ja -appdir /usr/lib/iceweasel/browser 1 plugin 
17:53:20 fork 14401 (netblue) /usr/lib/iceweasel/xulrunner/plugin-container /usr/lib/flashplugin-nonfree/libflashplayer.so -greomni /usr/lib/iceweasel/xulrunner/omni.ja -appdir /usr/lib/iceweasel/browser 1 plugin 
	child 14403 /usr/lib/iceweasel/xulrunner/plugin-container /usr/lib/flashplugin-nonfree/libflashplayer.so -greomni /usr/lib/iceweasel/xulrunner/omni.ja -appdir /usr/lib/iceweasel/browser 1 plugin 
17:53:20 exec 14403 (netblue) sh -c ps x | grep netscape 
17:53:20 fork 14403 (netblue) sh -c ps x | grep netscape 
	child 14404 sh -c ps x | grep netscape 
17:53:20 fork 14403 (netblue) sh -c ps x | grep netscape 
	child 14405 sh -c ps x | grep netscape 
17:53:20 exec 14405 (netblue) grep netscape 
17:53:20 exec 14404 (netblue) ps x 
17:53:20 exit 14404 (netblue)
17:53:20 exit 14405 (netblue)
17:53:20 exit 14403 (netblue)
17:53:23 fork 14303 (netblue) /bin/bash 
	child 14409 /bin/bash 
17:53:24 exec 14409 (netblue) ps aux 
17:53:24 exit 14409 (netblue)

 

Joining an existing sandbox

To join an existing sandbox, you need to find the PID for the process running in the sandbox, and pass this PID to firejail using –join option:

$ firejail --list
2767:root:firejail firefox 
  2768:netblue:iceweasel 
    14401:netblue:/usr/lib/iceweasel/xulrunner/plugin-container /usr/lib/...
14167:root:firejail 
  14168:netblue:/bin/bash 
$ firejail --join=2768
netblue@debian:/$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
netblue      1  1.0 12.7 1266872 511256 ?      Rl   Apr09  58:37 iceweasel
netblue   1358  3.2  0.6 358460 28016 ?        Sl   17:53   0:00 /usr/lib/icewea
netblue   1366  0.0  0.0  16840  1240 pts/0    R+   17:53   0:00 ps aux
netblue@debian:/$

This feature is supported on Linux Kernel 3.8 or newer.

 

Sandboxing Users at Login Time

Firejail can also work as a user login shell in /etc/passwd. Started by telnet or SSH server, firejail interprets it as a login request. Firejail grabs extra arguments for the specific user from /etc/firejail/login.users file. It configures the sandbox and passes the control to /bin/bash.

The steps to configure a jailed user account are as follows:

  • Set firejail as a shell in /etc/password (adduser –shell /usr/bin/firejail username, or chsh /usr/bin/firejail username).
  • Add extra arguments in /etc/firejail/login.users file.

For example, a sandbox set as firejail –debug –net=br0 requires the following line in /etc/firejail/login.users (I have bingo as username):

bingo:--debug --net=br0

This is how an ssh login session looks like:

$ ssh bingo@192.168.1.50
bingo@192.168.1.50's password: 
Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64
You have mail.
Last login: Sat Apr 12 12:15:47 2014 from localhost
Bridge device br0 at 10.10.20.1/24
Parent pid 11056, child pid 11057
Initializing child process
PID namespace installed
Mounting read-only /bin, /sbin, /lib, /lib64, /usr, /boot, /etc, /var
/var/run is a symbolic link to /run
/dev/shm is a symbolic link to /run/shm
Mounting tmpfs on /run directory
Mounting tmpfs on /run/shm
Remounting /proc and /proc/sys filesystems
Looking for an unused IP address
Trying 10.10.20.155, using 10.10.20.254 as source address ...
Configuring 10.10.20.155 address on interface eth0
Network namespace enabled
Interface           IP                  Mask                Status              
lo                  127.0.0.1           255.0.0.0           UP                  
eth0                10.10.20.155        255.255.255.0       UP                  

Starting /bin/bash
Child process initialized
[bingo@debian ~]$ 

Notice the IP address in the sandbox can be totally different than the IP address the user connected using ssh.

Back to Firejail project page

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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