FIREJAIL(1)

๐Ÿ’– FIREJAIL(1) ๐Ÿ’–

okay bestie, welcome to the firejail man page โ€” the firejail manual, section 1, and honestly? it's a whole journey. grab a strawberry drink ๐Ÿ“ and let's go.


โœจ NAME โœจ

Firejail โ€” a Linux namespaces sandbox program. that's it, that's the name, no cap.


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

k so there's like five whole ways to summon this thing. here they all are, verbatim, don't @ me:

start a sandbox:

firejail [OPTIONS] [program and arguments]

start an AppImage program:

firejail [OPTIONS] --appimage [OPTIONS] [appimage-file and
arguments]

file transfer from an existing sandbox:

firejail {--ls | --get | --put | --cat} dir_or_filename

monitoring:

firejail {--list | --netstats | --top | --tree}

miscellaneous:

firejail {-? | --debug-caps | --debug-errnos | --debug-syscalls |
--debug-syscalls32 | --debug-protocols | --help | --version}

๐Ÿ‘‘ DESCRIPTION ๐Ÿ‘‘

so. Firejail is a SUID sandbox program whose whole entire job is reducing the risk of security breaches by restricting the running environment of untrusted applications โ€” using Linux namespaces, seccomp-bpf, and Linux capabilities. it literally lets a process and all its descendants have their own private view of the globally shared kernel resources. like the network stack, the process table, the mount table. main character energy for your process tree, fr fr. ๐Ÿ’…

it can also work inside a SELinux or AppArmor environment, and it's integrated with Linux Control Groups. versatile icon.

written in C with virtually no dependencies, the software runs on any Linux computer with a 3.x kernel version or newer. and it can sandbox any type of process: servers, graphical applications, even user login sessions. everything. all of it. ๐Ÿ˜ญ

Firejail lets you manage application security using security profiles. each profile defines a set of permissions for a specific application or group of applications. the software ships with security profiles for a bunch of more common Linux programs, like Mozilla Firefox, Chromium, VLC, Transmission, etc. iconic behavior honestly.

๐Ÿšจ okay this part is important so pay attention bestie: Firejail is currently implemented as an SUID binary, which means that if a malicious or compromised user account manages to exploit a bug in Firejail, that could ultimately lead to a privilege escalation to root. to mitigate this, it is recommended to only allow trusted users to run firejail (see firejail-users(5) for details on how to achieve that). for more details on the security/usability tradeoffs of Firejail, see: #4601.

alternative sandbox technologies like Snap (see https://snapcraft.io) and Flatpak (see https://flatpak.org) are not supported. like, at all. Snap and Flatpak packages have their own native management tools and will not work when sandboxed with Firejail. they said "we have our own thing going on" and honestly? respect.


๐ŸŒธ USAGE ๐ŸŒธ

without any options, the sandbox consists of a filesystem built in a new mount namespace, plus new PID and UTS namespaces. IPC, network and user namespaces can be added using the command line options โ€” you just gotta ask. โœจ

the default Firejail filesystem is based on the host filesystem with the main system directories mounted read-only. those directories are /etc, /var, /usr, /bin, /sbin, /lib, /lib32, /libx32 and /lib64. only /home and /tmp are writable. so all the fun stuff is locked in glass, cute but untouchable. ๐ŸŽ€

upon execution Firejail first looks in ~/.config/firejail/ for a profile, and if it doesn't find one, it looks in /etc/firejail/. if an appropriate profile is not found, Firejail will use a default profile. and the default profile is quite restrictive. so in case the application doesn't work, use --noprofile option to disable it. no shame in it, we've all been there.

if a program argument is not specified, Firejail starts the user's preferred shell. examples, bestie, look:

$ firejail [OPTIONS]                         # starting the program
specified in $SHELL, usually /bin/bash

$ firejail [OPTIONS] /usr/bin/firefox        # starting Mozilla Firefox

# sudo firejail [OPTIONS] /etc/init.d/nginx start

when an option is specified multiple times (whether in a profile, on the command line, or both) or conflicts with a related option, the precedence/behavior is option-specific and usually documented in the OPTIONS section below. note that an option specified in a profile can generally be disabled on the command line using --ignore. iykyk.


๐Ÿ’œ OPTIONS ๐Ÿ’œ

okay this is the long part. buckle up. every single flag, zero skips, let's go. ๐Ÿงš
  • -- โ€” signals the end of options and disables further option processing. like a little "ok we're done with flags now" curtain drop. ๐ŸŽญ
  • --allow-bwrap โ€” by default firejail replaces the /usr/bin/bwrap executable with a do-nothing program. our replacement just runs the bubblewrap target, and is visible only inside the firejail sandbox. use this option to disable this default functionality. slay, but like, don't.

Example:

$ firejail --noprofile --allow-bwrap bwrap --help
firejail version 0.9.77

Parent pid 44129, child pid 44130
Base filesystem installed in 0.04 ms
Child process initialized in 5.02 ms
usage: bwrap [OPTIONS...] [--] COMMAND [ARGS...]

    --help                       Print this help
    --version                    Print version
    --args FD                    Parse NUL-separated args from FD
  • --allow-debuggers โ€” allows tools such as strace and gdb inside the sandbox by whitelisting system calls ptrace and process_vm_readv. ๐Ÿ•ต๏ธ this option is only available when running on Linux kernels 4.8 or newer โ€” a kernel bug in ptrace system call allows a full bypass of the seccomp filter. so like, older kernels said no.

Example:

$ firejail --allow-debuggers
--profile=/etc/firejail/firefox.profile strace -f
/usr/bin/firefox

see also --private-etc and --trace.

  • --allusers โ€” all directories under /home are visible inside the sandbox. by default, only the current user home directory is visible. so this is the "let them see everyone" button. ๐Ÿ‘€

Example:

$ firejail --allusers
  • --apparmor โ€” enables AppArmor confinement with the "firejail-default" AppArmor profile. for more information, please see the APPARMOR section below. ๐Ÿ›ก๏ธ
  • --apparmor=profile_name โ€” enables AppArmor confinement with a custom AppArmor profile. note that the profile in question must already be loaded into the kernel. for more information, please see the APPARMOR section below. no auto-magic loading, sorry bestie.
  • --apparmor.print=name|pid โ€” prints the AppArmor confinement status for the sandbox identified by name or by PID. very "who are you and what are you wearing" of it.

Example:

$ firejail --apparmor.print=browser
5074:netblue:/usr/bin/firejail /usr/bin/firefox-esr
  AppArmor: firejail-default enforce
  • --appimage โ€” sandboxes an AppImage (see https://appimage.org) application. if the sandbox is started as a regular user, nonewprivs and a default capabilities filter are enabled. private-bin is disabled by default when running appimages.

Example:

$ firejail --appimage --profile=krita krita-3.0-x86_64.appimage
$ firejail --quiet --appimage --private --profile=krita
krita-3.0-x86_64.appimage
$ firejail --appimage --net=none --x11 --profile=krita
krita-3.0-x86_64.appimage

Note 1: when using both --appimage and --profile, it is recommended to always specify the former before the latter, so that any ?HAS_APPIMAGE conditionals inside of the profile evaluate to true (see ?CONDITIONAL in firejail-profile(5)). order matters, periodt. ๐Ÿ’…

Note 2: if you want to disable networking by default every time you sandbox an appimage, add a conditional in /etc/firejail/globals.local as follows:

$ cat /etc/firejail/globals.local
?HAS_APPIMAGE: net none
  • --bind=filename1,filename2 โ€” mount-binds filename1 on top of filename2. this option is only available when running as root. ๐Ÿ”’

Example:

# firejail --bind=/config/etc/passwd,/etc/passwd
  • --blacklist=dirname_or_filename โ€” blacklists a directory or file. this makes a file or directory completely inaccessible. all other files and directories are unaffected. the blacklisted file or directory is still visible on the filesystem, even if it's inaccessible. like it's at the party but you can't talk to it. ๐Ÿ’€

Symbolic link handling: blacklisting a path that is a symbolic link will also blacklist the path that it points to. for example, if ~/foo is blacklisted and it points to /bar, then /bar will also be blacklisted. symlinks to /dev/null are not followed (only the symlink itself will be affected), as replacing certain paths with symlinks to /dev/null is not uncommon and restricting access to /dev/null can lead to unexpected issues (see #5803). using /dev/null directly (instead of through a symlink) should work normally.

file globbing is supported, see the FILE GLOBBING section for more details. โœจ

Example:

$ firejail --blacklist=/sbin --blacklist=/usr/sbin
$ firejail --blacklist=~/.mozilla
$ firejail --blacklist="/home/username/My Virtual Machines"
  • --build โ€” the command builds a whitelisted profile. the profile is printed on the screen. the program is run in a very relaxed sandbox, with only --caps.drop=all and --seccomp=!chroot. programs that raise user privileges are not supported. ๐Ÿ—๏ธ

Note: this option is intended for profile debugging and development. the profile that is generated may be incomplete, non-functional and lacking in security. if you want to try to create a new profile, see CONTRIBUTING.md. it's giving "rough draft, don't ship it".

Example:

$ firejail --build /usr/bin/vlc ~/Videos/test.mp4
$ firejail --build --appimage ~/Downloads/Subsurface.AppImage
  • --build=profile-file โ€” the command builds a whitelisted profile, and saves it in profile-file. the program is run in a very relaxed sandbox, with only --caps.drop=all and --seccomp=!chroot. programs that raise user privileges are not supported.

Note: this option is intended for profile debugging and development. the profile that is generated may be incomplete, non-functional and lacking in security. if you want to try to create a new profile, see CONTRIBUTING.md.

Example:

$ firejail --build=vlc.profile /usr/bin/vlc ~/Videos/test.mp4
$ firejail --build=Subsurface.profile --appimage
~/Downloads/Subsurface.AppImage
  • -c โ€” login shell compatibility option. this option is used by some login programs when executing the login shell, such as when firejail is used as a restricted login shell. it currently does not change the execution of firejail. it's literally just there vibing. ๐Ÿซถ
  • --caps โ€” Linux capabilities is a kernel feature designed to split up the root privilege into a set of distinct privileges. these privileges can be enabled or disabled independently, thus restricting what a process running as root can do in the system. see capabilities(7) for details. ๐Ÿ”ฅ
  • --caps โ€” so this one's the default vibe for root programs: they run with every capability enabled ๐Ÿ˜ฌ but --caps shuts off this whole lil' roster: CAP_SYS_MODULE, CAP_SYS_RAWIO, CAP_SYS_BOOT, CAP_SYS_NICE, CAP_SYS_TTY_CONFIG, CAP_SYSLOG, CAP_MKNOD, CAP_SYS_ADMIN. And like, the filter hits every process started inside the sandbox, no exceptions bestie ๐Ÿ’…

Example:

$ sudo firejail --caps /etc/init.d/nginx start
  • --caps.drop=all โ€” drops all the capabilities for processes running in the sandbox. Lowkey this is the recommended one for GUI programs or literally anything that doesn't need root privileges. And honestly? It's a must-have for sandboxing untrusted stuff from unofficial sources โ€” games, Java programs, that whole sketchy category ๐ŸŽฎโ˜•

Example:

$ firejail --caps.drop=all /usr/bin/warzone2100
  • --caps.drop=capability,capability,capability โ€” build your own custom blacklist Linux capabilities filter ๐Ÿ–ค

Example:

$ firejail --caps.drop=net_broadcast,net_admin,net_raw
  • --caps.keep=capability,capability,capability โ€” and this one's the opposite energy: a custom whitelist Linux capabilities filter ๐Ÿค

Example:

$ sudo firejail --caps.keep=chown,net_bind_service,setgid,\
setuid /etc/init.d/nginx start
  • --caps.print=name|pid โ€” prints the caps filter for the sandbox, identified by name or by PID. Peek at the receipts ๐Ÿ‘€

Example:

$ firejail --name=mygame --caps.drop=all /usr/bin/warzone2100 &
$ firejail --caps.print=mygame

Example:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --caps.print=3272
  • --cat=name|pid filename โ€” prints the content of a file from the sandbox container ๐Ÿฑ (see the FILE TRANSFER section for the full tea, bestie).
  • --cpu=cpu-number,cpu-number,cpu-number โ€” sets CPU affinity, aka tells your program exactly which cores it's allowed to touch โœจ

Example:

$ firejail --cpu=0,1 /usr/bin/handbrake
  • --cpu.print=name|pid โ€” prints the CPU cores in use by the sandbox, matched by name or by PID ๐Ÿ”

Example:

$ firejail --name=mygame --caps.drop=all /usr/bin/warzone2100 &
$ firejail --cpu.print=mygame

Example:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --cpu.print=3272
  • --dbus-log=file โ€” tells it where to put the DBus log file ๐Ÿ“

The log file collects events for both the system and session buses if you've specified both --dbus-system.log and --dbus-user.log. And if you don't give a log file path at all? Logs go to standard output instead. Easy.

Example:

$ firejail --dbus-system=filter --dbus-system.log \
--dbus-log=dbus.txt
  • --dbus-system=filter|none โ€” sets the system DBus sandboxing policy.

The filter policy enables the system DBus filter. Heads up: this option requires installing the xdg-dbus-proxy utility ๐Ÿ› ๏ธ Permissions for well-known names can be specified with the --dbus-system.talk and --dbus-system.own options.

The none policy disables access to the system DBus. Like, fully.

Real talk: only the regular system DBus UNIX socket is handled by this option. To disable the abstract sockets (and force applications to use the filtered UNIX socket) you'd need to request a new network namespace using the --net command. Another option is to remove unix from the --protocol set. Iykyk ๐Ÿซถ

Example:

$ firejail --dbus-system=none
  • --dbus-system.broadcast=name=[member][@path] โ€” lets the app receive broadcast signals from the indicated interface member at the indicated object path exposed by the indicated bus name on the system DBus ๐Ÿ“ก The name may have a .* suffix to match all names underneath it, including itself. The interface member may have a .* to match all members of an interface, or be * to match all interfaces. The path may have a /* suffix to indicate all objects underneath it, including itself. Omitting the interface member or the object path will match all members and object paths, respectively.

Example:

$ firejail --dbus-system=filter --dbus-system.broadcast=\
org.freedesktop.Notifications=\
org.freedesktop.Notifications.*@/org/freedesktop/Notifications
  • --dbus-system.call=name=[member][@path] โ€” lets the app call the indicated interface member at the indicated object path exposed by the indicated bus name on the system DBus ๐Ÿ“ž Same matching rules, fr: the name may have a .* suffix to match all names underneath it, including itself. The interface member may have a .* to match all members of an interface, or be * to match all interfaces. The path may have a /* suffix to indicate all objects underneath it, including itself. Omitting the interface member or the object path will match all members and object paths, respectively.

Example:

$ firejail --dbus-system=filter --dbus-system.call=\
org.freedesktop.Notifications=\
org.freedesktop.Notifications.*@/org/freedesktop/Notifications
  • --dbus-system.log โ€” turns on DBus logging for the system DBus ๐Ÿชต This one requires --dbus-system=filter.

Example:

$ firejail --dbus-system=filter --dbus-system.log
  • --dbus-system.own=name โ€” lets the app own the specified well-known name on the system DBus ๐Ÿ‘‘ The name may have a .* suffix to match all names underneath it, including itself (e.g. "foo.bar.*" matches "foo.bar", "foo.bar.baz" and "foo.bar.baz.quux", but not "foobar").

Example:

$ firejail --dbus-system=filter --dbus-system.own=\
org.gnome.ghex.*
  • --dbus-system.see=name โ€” lets the app see the specified well-known name on the system DBus, but not talk to it ๐Ÿ‘€ Same suffix rules: the name may have a .* suffix to match all names underneath it, including itself (e.g. "foo.bar.*" matches "foo.bar", "foo.bar.baz" and "foo.bar.baz.quux", but not "foobar").

Example:

$ firejail --dbus-system=filter --dbus-system.see=\
org.freedesktop.Notifications
  • --dbus-system.talk=name โ€” lets the app talk to the specified well-known name on the system DBus ๐Ÿ’ฌ And again: the name may have a .* suffix to match all names underneath it, including itself (e.g. "foo.bar.*" matches "foo.bar", "foo.bar.baz" and "foo.bar.baz.quux", but not "foobar").

Example:

$ firejail --dbus-system=filter --dbus-system.talk=\
org.freedesktop.Notifications
  • --dbus-user=filter|none โ€” sets the session DBus sandboxing policy (yes, the session one this time, keep up bestie ๐Ÿ’–).

The filter policy enables the session DBus filter. This option requires installing the xdg-dbus-proxy utility. Permissions for well-known names can be added with the --dbus-user.talk and --dbus-user.own options.

The none policy disables access to the session DBus.

Same caveat as the system one: only the regular session DBus UNIX socket is handled by this option. To disable the abstract sockets (and force applications to use the filtered UNIX socket) you'd need to request a new network namespace using the --net command. Another option is to remove unix from the --protocol set.

Example:

$ firejail --dbus-user=none
  • --dbus-user.broadcast=name=[member][@path] โ€” lets the app receive broadcast signals from the indicated interface member at the indicated object path exposed by the indicated bus name on the session DBus ๐Ÿ“ก The name may have a .* suffix to match all names underneath it, including itself. The interface member may have a .* to match all members of an interface, or be * to match all interfaces. The path may have a /* suffix to indicate all objects underneath it, including itself. Omitting the interface member or the object path will match all members and object paths, respectively.

Example:

$ firejail --dbus-user=filter --dbus-user.broadcast=\
org.freedesktop.Notifications=\
org.freedesktop.Notifications.*@/org/freedesktop/Notifications
  • --dbus-user.call=name=[member][@path] โ€” lets the app call the indicated interface member at the indicated object path exposed by the indicated bus name on the session DBus ๐Ÿ“ž The name may have a .* suffix to match all names underneath it, including itself. The interface member may have a .* to match all members of an interface, or be * to match all interfaces. The path may have a /* suffix to indicate all objects underneath it, including itself. Omitting the interface member or the object path will match all members and object paths, respectively.

Example:

$ firejail --dbus-user=filter --dbus-user.call=\
org.freedesktop.Notifications=\
org.freedesktop.Notifications.*@/org/freedesktop/Notifications
  • --dbus-user.log โ€” turns on DBus logging for the session DBus ๐Ÿชต Requires --dbus-user=filter.

Example:

$ firejail --dbus-user=filter --dbus-user.log
  • --dbus-user.own=name โ€” lets the app own the specified well-known name on the session DBus ๐Ÿ‘‘ The name may have a .* suffix to match all names underneath it, including itself (e.g. "foo.bar.*" matches "foo.bar", "foo.bar.baz" and "foo.bar.baz.quux", but not "foobar").

Example:

$ firejail --dbus-user=filter --dbus-user.own=org.gnome.ghex.*
  • --dbus-user.see=name โ€” lets the app see, but not talk to, the specified well-known name on the session DBus ๐Ÿ‘€ The name may have a .* suffix to match all names underneath it, including itself (e.g. "foo.bar.*" matches "foo.bar", "foo.bar.baz" and "foo.bar.baz.quux", but not "foobar").

Example:

$ firejail --dbus-user=filter --dbus-user.see=\
org.freedesktop.Notifications
  • --dbus-user.talk=name โ€” lets the app talk to the specified well-known name on the session DBus ๐Ÿ’ฌ The name may have a .* suffix to match all names underneath it, including itself (e.g. "foo.bar.*" matches "foo.bar", "foo.bar.baz" and "foo.bar.baz.quux", but not "foobar").

Example:

$ firejail --dbus-user=filter --dbus-user.talk=\
org.freedesktop.Notifications
  • --debug โ€” prints debug messages ๐Ÿ› the classic "what is actually happening in there" button.

Example:

$ firejail --debug /usr/bin/firefox
  • --debug-blacklists โ€” bestie this one debugs blacklisting, that's it, that's the vibe โœจ

Example:

$ firejail --debug-blacklists /usr/bin/firefox
  • --debug-caps โ€” prints, like, all the recognized capabilities in the current Firejail software build and then dips ๐Ÿ‘‹

Example:

$ firejail --debug-caps
  • --debug-errnos โ€” prints all recognized error numbers in the current Firejail software build and exits. slay ๐Ÿ’…

Example:

$ firejail --debug-errnos
  • --debug-protocols โ€” prints all recognized protocols in the current Firejail software build and exits, iconic behavior ๐ŸŽ€

Example:

$ firejail --debug-protocols
  • --debug-syscall-groups[=@group1,@group2,@all,...] โ€” prints all system call groups and descriptions, then exits. ngl this one's kind of the main character of debug flags ๐Ÿ‘‘

Pass seccomp groups comma-separated and it'll print their system calls in the current Firejail software build and exit. Also the special group @all exists for printing every seccomp group plus its related syscalls, iykyk.

Example:

$ firejail --debug-syscall-groups
$ firejail --debug-syscall-groups=@chown,@mount,@swap
$ firejail --debug-syscall-groups=@all
  • --debug-syscalls โ€” prints all recognized system calls in the current Firejail software build and exits ๐Ÿ’–

Example:

$ firejail --debug-syscalls
Note: the syscall mapping comes directly from the architecture-specific .tbl files in the Linux kernel sources, which get transformed into header files in src/include and built into firejail. Only syscalls for the build target architecture and 32-bit variants (if applicable) are included in the build โ€” like for x86_64 and x86 respectively ๐Ÿ™ˆ. If a syscall number or name is not listed, it is not recognized by firejail. This may be because the syscall isn't present in the .tbl file (obsolete syscalls, we see you), because it hasn't been added to firejail yet, or because your current build of firejail is just too old. not me calling out stale builds ๐Ÿ˜ญ

Example .tbl files for x86_64 and x86 on Linux v6.19:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/entry/syscalls/syscall_64.tbl?h=v6.19
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/entry/syscalls/syscall_32.tbl?h=v6.19
  • --debug-syscalls32 โ€” prints all recognized 32 bit system calls in the current Firejail software build and exits. literally the same as --debug-syscalls but for the 32-bit syscalls ๐Ÿฆ‹
  • --debug-whitelists โ€” debug whitelisting, that's the whole gig โœจ

Example:

$ firejail --debug-whitelists /usr/bin/firefox
  • --defaultgw=address โ€” use this address as the default gateway in the new network namespace ๐Ÿ•ธ๏ธ

Example:

$ firejail --net=eth0 --defaultgw=10.10.20.1 /usr/bin/firefox
  • --deterministic-exit-code โ€” always exit firejail with the first child's exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. so if you like your outcomes predictable, this is your girl ๐ŸŽ€
  • --deterministic-shutdown โ€” always shut down the sandbox after the first child has terminated. The default behavior is to keep the sandbox alive as long as it contains running processes. choose your fighter ๐Ÿ’…
  • --disable-mnt โ€” blacklists /mnt, /media, /run/mount and /run/media access. no peeking ๐Ÿ”’

Example:

$ firejail --disable-mnt /usr/bin/firefox
  • --dns=address โ€” set a DNS server for the sandbox. Up to three DNS servers can be defined. Use this option if you don't trust the DNS setup on your network ๐Ÿ‘€

Example:

$ firejail --dns=8.8.8.8 --dns=8.8.4.4 /usr/bin/firefox
Note: this feature is not supported on systemd-resolved setups. sad but true ๐Ÿ˜”
  • --dns.print=name|pid โ€” print DNS configuration for a sandbox identified by name or by PID ๐Ÿ–จ๏ธ

Example:

$ firejail --name=mygame --caps.drop=all /usr/bin/warzone2100 &
$ firejail --dns.print=mygame

Example:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --dns.print=3272
  • --dnstrace[=name|pid] โ€” monitor DNS queries ๐Ÿ‘๏ธ The sandbox can be specified by name or pid. Only networked sandboxes created with --net are supported. This option is only available when running the sandbox as root.

Without a name/pid, Firejail will monitor the main system network namespace. fr fr it just watches everything ๐ŸŒ

Example:

$ sudo firejail --dnstrace
11:31:43  9.9.9.9        linux.com (type 1)
11:31:45  9.9.9.9        fonts.googleapis.com (type 1) NXDOMAIN
11:31:45  9.9.9.9        js.hs-scripts.com (type 1) NXDOMAIN
11:31:45  9.9.9.9        www.linux.com (type 1)
11:31:45  9.9.9.9        fonts.googleapis.com (type 1) NXDOMAIN
11:31:52  9.9.9.9        js.hs-scripts.com (type 1) NXDOMAIN
11:32:05  9.9.9.9        secure.gravatar.com (type 1)
11:32:06  9.9.9.9        secure.gravatar.com (type 1)
11:32:08  9.9.9.9        taikai.network (type 1)
11:32:08  9.9.9.9        cdn.jsdelivr.net (type 1)
11:32:08  9.9.9.9        taikai.azureedge.net (type 1)
11:32:08  9.9.9.9        www.youtube.com (type 1)
  • --env=name=value โ€” set an environment variable in the new sandbox ๐ŸŒธ so your app gets the tea it needs

Example:

$ firejail --env=LD_LIBRARY_PATH=/opt/test/lib
  • --fs.print=name|pid โ€” print the filesystem log for the sandbox identified by name or by PID ๐Ÿ“‚ receipts, basically

Example:

$ firejail --name=mygame --caps.drop=all /usr/bin/warzone2100 &
$ firejail --fs.print=mygame

Example:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --fs.print=3272
  • --get=name|pid filename โ€” get a file from a sandbox container ๐Ÿซณ see the FILE TRANSFER section for more details, bestie
  • -?, --help โ€” print options and exit. (yes, the original page says "end exit" โ€” typos are canon, we do not fix, we respect the artifact ๐Ÿ’€) anyway it's the help flag, it helps ๐Ÿ’–
  • --hostname=name โ€” set sandbox hostname. This is incompatible with --hostname-randomize. For valid names, see the NAME VALIDATION section ๐Ÿ‘‘

Example:

$ firejail --hostname=officepc /usr/bin/firefox
  • --hostname-randomize โ€” set sandbox hostname to a random value generated by firejail. This is incompatible with --hostname. chaos mode activated ๐ŸŽฒ

Example:

$ firejail --hostname-randomize /usr/bin/firefox
Note: changing the hostname may cause breakage related to networking (see #7048) and may cause X11 programs to crash on startup due to not being able to authenticate to the X server (see #7062). not to be dramatic but ๐Ÿ˜ญ
  • --hosts-file=file โ€” use file as /etc/hosts ๐Ÿ““

Example:

$ firejail --hosts-file=~/myhosts /usr/bin/firefox
  • --icmptrace[=name|pid] โ€” monitor ICMP traffic ๐Ÿ“ก The sandbox can be specified by name or pid. Only networked sandboxes created with --net are supported. This option is only available when running the sandbox as root.

Without a name/pid, Firejail will monitor the main system network namespace. same energy as --dnstrace but for pings ๐Ÿ“

Example

$ sudo firejail --icmptrace
20:53:54  192.168.1.60 -> 142.250.65.174 - 98 bytes - Echo request/0
20:53:54  142.250.65.174 -> 192.168.1.60 - 98 bytes - Echo reply/0
20:53:55  192.168.1.60 -> 142.250.65.174 - 98 bytes - Echo request/0
20:53:55  142.250.65.174 -> 192.168.1.60 - 98 bytes - Echo reply/0
20:53:55  192.168.1.60 -> 1.1.1.1 - 154 bytes - Destination unreachable/Port unreachable
  • --ignore=command โ€” ignore command in the profile file ๐Ÿšซ like a soft block, but for profile lines

Example:

$ firejail --ignore=seccomp --ignore=caps /usr/bin/firefox
$ firejail --ignore="net eth0" /usr/bin/firefox
  • --include=file.profile โ€” include a profile file before the regular profiles are used ๐Ÿงš stacking profiles like accessories

Example:

$ firejail --include=/etc/firejail/disable-devel.inc /usr/bin/gedit
  • --interface=interface โ€” move interface into a new network namespace. Up to four --interface options can be specified. ๐Ÿ”Œ
Note: wlan devices are not supported for this option. wifi girlies, this one's not for you ๐Ÿ˜”

Example:

$ firejail --interface=eth1 --interface=eth0.vlan100
  • --ip=address โ€” assign IP addresses to the last network interface defined by a --net option. A default gateway is assigned by default ๐Ÿ 

Example:

$ firejail --net=eth0 --ip=10.10.20.56 /usr/bin/firefox
  • --ip=none โ€” no IP address and no default gateway are configured for the last interface defined by a --net option. nothing. void. empty. ๐Ÿ’€

Example:

$ firejail --net=eth0 --ip=none

If the corresponding interface doesn't have an IP address configured, this option is enabled by default. so sometimes it's just, like, the vibe already โœจ

  • --ip6=address โ€” assign IPv6 addresses to the last network interface defined by a --net option ๐ŸŒˆ

Example:

$ firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64 /usr/bin/firefox
Note: you don't need this option if you obtain your ip6 address from the router via SLAAC (your ip6 address and default route will be configured by the kernel automatically). the kernel handles it, she's got this ๐Ÿ’…
  • --iprange=address,address โ€” assign an IP address in the provided range to the last network interface defined by a --net option. A default gateway is assigned by default ๐ŸŽฏ

Example:

$ firejail --net=eth0 --iprange=192.168.1.100,192.168.1.150
  • --ipc-namespace โ€” enable a new IPC namespace if the sandbox was started as a regular user. IPC namespace is enabled by default for sandboxes started as root ๐Ÿ”
Note: This only affects the IPC resources that are mentioned in ipc_namespaces(7). It does not affect other IPC resources, such as Unix sockets (see unix(7)). important distinction bestie, don't let anyone tell you otherwise ๐Ÿซถ

Example:

$ firejail --ipc-namespace /usr/bin/firefox
  • --join=name|pid โ€” join the sandbox identified by name or by PID ๐Ÿค By default a /bin/bash shell is started after joining the sandbox. If a program is specified, the program is run in the sandbox.

If --join is issued as a regular user, all security filters are configured for the new process the same they are configured in the sandbox. If --join is issued as root, the security filters and cpus configurations are not applied to the process joining the sandbox. yes this is a whole thing, read it twice ๐Ÿ‘€

Example:

$ firejail --name=mygame --caps.drop=all /usr/bin/warzone2100 &
$ firejail --join=mygame

Ok so we left off mid-example for --join, and bestie the payoff is this:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --join=3272

Like, you see the PID, you slide into its DMs. Iconic. ๐Ÿ’…


  • --join-filesystem=name|pid โ€” hop into the mount namespace of the sandbox that matches that name or PID. By default you land in a /bin/bash shell once you're in there, but if you hand it a program, that program runs inside the sandbox instead. ๐Ÿšชโœจ Only the root user can do this one โ€” sorry bestie, it's a VIP-only door. Also important: security filters and cpus configurations are not applied to the process that joins the sandbox. So it's like sneaking in through a window, not going through the metal detector.
  • --join-network=name|pid โ€” same deal but for the network namespace, identified by name. By default you get a /bin/bash shell after joining; give it a program and that program runs inside the sandbox. Again, root user only. Again, security filters and cpus configurations are not applied to the joining process. Here's the whole glow-up in action:
# start firefox
$ firejail --net=eth0 --name=browser /usr/bin/firefox &

# change netfilter configuration
$ sudo firejail --join-network=browser bash -c "cat /etc/firejail/nolocal.net | /sbin/iptables-restore"

# verify netfilter configuration
$ sudo firejail --join-network=browser /sbin/iptables -vL

# verify IP addresses
$ sudo firejail --join-network=browser ip addr
Switching to pid 1932, the first child process inside the sandbox
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0-1931: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 76:58:14:42:78:e4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.158/24 brd 192.168.1.255 scope global eth0-1931
       valid_lft forever preferred_lft forever
    inet6 fe80::7458:14ff:fe42:78e4/64 scope link
       valid_lft forever preferred_lft forever

Look at all those addresses. She's thriving. ๐ŸŒˆ

  • --join-or-start=name โ€” the "either way I'm getting what I want" option ๐Ÿซถ. It joins the sandbox identified by name, or starts a brand new one if there isn't one. Same as firejail --join=name if a sandbox with that name exists, otherwise same as firejail --name=name .... Peep --name for the details. And heads up: in contrary to other join options there is a respective profile option for this one. Lowkey special like that.
  • --keep-config-pulse โ€” turns off the automatic ~/.config/pulse init. For complex setups, like remote pulse servers or non-standard socket paths. If that's your situation, you already know. ๐ŸŽง

Example:

$ firejail --keep-config-pulse /usr/bin/firefox
  • --keep-dev-ntsync โ€” lets the sandbox touch the /dev/ntsync character device (even with --private-dev), which is blocked by default. This device is mostly intended to boost performance and compatibility when running certain programs through Wine. ๐Ÿท

Example:

$ firejail --keep-dev-ntsync --private-dev
  • --keep-dev-shm โ€” leaves the /dev/shm directory untouched (even with --private-dev). Hands off, she's fine. ๐Ÿ™…โ€โ™€๏ธ

Example:

$ firejail --keep-dev-shm --private-dev
  • --keep-dev-tpm โ€” lets the sandbox reach the Trusted Cryptography Module (TCM) and Trusted Platform Module (TPM) devices (even with --private-dev), because yeah, they're blocked by default. The paths it covers:
/dev/tcm[0-9]*
/dev/tcmrm[0-9]*
/dev/tpm[0-9]*
/dev/tpmrm[0-9]*

Example:

$ firejail --keep-dev-tpm --private-dev
  • --keep-fd=all โ€” inherit all open file descriptors into the sandbox. By default only file descriptors 0, 1 and 2 are inherited, and all the others get closed. Like, evicted. ๐Ÿ’€

Example:

$ firejail --keep-fd=all
  • --keep-fd=file_descriptor โ€” don't close the specific open file descriptors you name. Same default story: only file descriptors 0, 1 and 2 are inherited, everything else is closed. This is the "no bestie, not that one" version. ๐ŸŽ€

Example:

$ firejail --keep-fd=3,4,5
  • --keep-shell-rc โ€” ok context: when you're using a private home directory, firejail copies files from the system's user home template (/etc/skel) into it, which overrides any attempts to whitelist your original files (things like ~/.bashrc and ~/.zshrc). Rude, honestly. This option disables that feature and lets you whitelist the original files. Your rc files, your rules. ๐Ÿš
  • --keep-var-tmp โ€” the /var/tmp directory is left untouched. ๐Ÿซง

Example:

$ firejail --keep-var-tmp

๐Ÿงš Landlock era (experimental, tread lightly) ๐Ÿงš

Every single one of these is marked (experimental). Do not come crying to me if it's quirky. ๐Ÿ˜ญ
  • --landlock.enforce โ€” enforces the Landlock ruleset. Without it, the other Landlock commands have no effect โ€” they're literally just vibes. See the LANDLOCK section for more info.
  • --landlock.fs.read=path โ€” creates a Landlock ruleset (if it doesn't already exist) and adds a read access rule for path.
  • --landlock.fs.write=path โ€” creates a Landlock ruleset (if it doesn't already exist) and adds a write access rule for path.
  • --landlock.fs.makeipc=path โ€” creates a Landlock ruleset (if it doesn't already exist) and adds a rule that allows the creation of named pipes (FIFOs) and Unix domain sockets beneath the given path. Very "I made this little corner for myself" energy. ๐Ÿช†
  • --landlock.fs.makedev=path โ€” creates a Landlock ruleset (if it doesn't already exist) and adds a rule that allows the creation of block devices and character devices beneath the given path.
  • --landlock.fs.execute=path โ€” creates a Landlock ruleset (if it doesn't already exist) and adds an execution permission rule for path.

Example:

$ firejail --landlock.fs.read=/ --landlock.fs.write=/home --landlock.fs.execute=/usr --landlock.enforce

  • --list โ€” lists all the sandboxes. See the MONITORING section for more details. It's the group photo. ๐Ÿ“ธ

Example:

$ firejail --list
7015:netblue:browser:firejail /usr/bin/firefox
7056:netblue:torrent:firejail --net=eth0 /usr/bin/transmission-gtk
7064:netblue::firejail --noroot /usr/bin/xterm
  • --ls=name|pid dir_or_filename โ€” lists the files inside a sandbox container. See the FILE TRANSFER section for more details. Peeking in the windows, respectfully. ๐Ÿ‘€
  • --mac=address โ€” assigns a MAC address to the last network interface defined by a --net option. Just so you know: this option is not supported for wireless interfaces. Fed. โœ‹

Example:

$ firejail --net=eth0 --mac=00:11:22:33:44:55 /usr/bin/firefox
  • --machine-id โ€” spoofs the id number in the /etc/machine-id file โ€” a fresh random id gets generated inside the sandbox. ๐ŸŽญ But bestie, note that this breaks audio support, so enable it when sound is not required.

Example:

$ firejail --machine-id
  • --memory-deny-write-execute โ€” installs a seccomp filter to block attempts to create memory mappings that are both writable and executable, to change mappings to be executable, or to create executable shared memory. The filter examines the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create and shmat system calls, and returns error EPERM to the process if necessary (or kills it, or logs the attempt โ€” see --seccomp-error-action below). ๐Ÿ›ก๏ธ
Note: shmat is not implemented as a system call on some platforms including i386, and it cannot be handled by seccomp-bpf. So on those, this bit simply can't happen. ๐Ÿ’€
  • --mkdir=dirname โ€” creates a directory in user home. Parent directories are created as needed. Very build-your-own-adventure. ๐Ÿ“

Example:

$ firejail --mkdir=~/work/project
  • --mkfile=filename โ€” creates an empty file in user home. Blank canvas, main character energy. ๐Ÿ“„

Example:

$ firejail --mkfile=~/work/project/readme
  • --mtu=number โ€” assigns an MTU value to the last network interface defined by a --net option. Tuning, but make it fashion. โœจ

Example:

$ firejail --net=eth0 --mtu=1492
  • --name=name โ€” sets the sandbox name. Several options, such as --join and --shutdown, can use this name to identify a sandbox. ๐Ÿท๏ธ Important rules, though:
    • The name cannot contain only digits, because that's treated as a PID in the other options โ€” like in --join.
    • For valid names, see the NAME VALIDATION section.
    • If the name you supplied is already in use by another sandbox, Firejail will assign a new name as name-PID, where PID is the process ID of the sandbox. This functionality can be disabled at run time in /etc/firejail/firejail.config, by setting the "name-change" flag to "no".

Example:

$ firejail --name=browser /usr/bin/firefox &
$ firejail --name=browser --private /usr/bin/firefox --no-remote &
$ firejail --list
1198:netblue:browser:firejail --name=browser /usr/bin/firefox
1312:netblue:browser-1312:firejail --name=browser --private /usr/bin/firefox --no-remote
  • --net=bridge_interface โ€” spins up a new network namespace and connects it to this bridge interface. Unless you specify it with --ip and --defaultgw, an IP address and a default gateway get assigned automatically to the sandbox. The IP address is verified using ARP before assignment, and the address configured as default gateway is the bridge device IP address. You can stack up to four --net options. Four! ๐ŸŒ‰

Example:

$ sudo brctl addbr br0
$ sudo ifconfig br0 10.10.20.1/24
$ sudo brctl addbr br1
$ sudo ifconfig br1 10.10.30.1/24
$ firejail --net=br0 --net=br1
  • --net=ethernet_interface|wireless_interface โ€” same idea, new network namespace, but this time connected to an ethernet or wireless interface using the standard Linux macvlan|ipvlan driver. Unless specified with --ip and --defaultgw, an IP address and a default gateway are assigned automatically to the sandbox. The IP address is verified using ARP before assignment. The address configured as default gateway is the default gateway of the host. Up to four --net options can be specified. ๐Ÿ”Œ And a lore drop: support for the ipvlan driver was introduced in Linux kernel 3.19.

Example:

$ firejail --net=eth0 --ip=192.168.1.80 --dns=8.8.8.8 /usr/bin/firefox
$ firejail --net=wlan0 /usr/bin/firefox
  • --net=none โ€” okay so this one gives you a whole new network namespace with nothing in it. The only interface chilling in there is a fresh loopback (lo). Perfect for denying network access to programs that genuinely don't need it โ€” like, why does your calculator want wifi bestie ๐Ÿ’€

Example:

$ firejail --net=none /usr/bin/vlc
Heads up ๐Ÿ’… --net=none can crash the application on some platforms. If that happens to you, swap it for --protocol=unix โ€” same energy, less chaos.
  • --net=tap_interface โ€” new network namespace, and we're hooking it up to this ethernet tap interface using the standard Linux macvlan driver. Slay ๐ŸŒˆ But listen: if the tap interface isn't configured, the sandbox will not try to configure the interface inside the sandbox. That's your job, bestie โ€” use --ip, --netmask and --defaultgw to specify the configuration.

Example:

$ firejail --net=tap0 --ip=10.10.20.80 --netmask=255.255.255.0
--defaultgw=10.10.20.1 /usr/bin/firefox
  • --net.print=name|pid โ€” when a new network namespace is enabled, this prints the network interface configuration for the sandbox you name (by name or PID). It's giving receipts โœจ Example:
$ firejail --net.print=browser
Switching to pid 1853, the first child process inside the sandbox
Interface  MAC               IP            Mask        Status
lo                           127.0.0.1     255.0.0.0     UP
eth0-1852  5e:fb:8e:27:29:26 192.168.1.186 255.255.255.0 UP
  • --netfilter โ€” turns on a default firewall if a new network namespace is created inside the sandbox. Lowkey important: this option has no effect for sandboxes using the system network namespace. Periodt.

The default firewall is optimized for regular desktop applications โ€” no incoming connections are accepted:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# allow ping
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# drop STUN (WebRTC) requests
-A OUTPUT -p udp --dport 3478 -j DROP
-A OUTPUT -p udp --dport 3479 -j DROP
-A OUTPUT -p tcp --dport 3478 -j DROP
-A OUTPUT -p tcp --dport 3479 -j DROP
COMMIT

Example:

$ firejail --net=eth0 --netfilter /usr/bin/firefox
  • --netfilter=filename โ€” enable the firewall specified by filename, again only if a new network namespace is created inside the sandbox. (Say it with me: no effect for sandboxes using the system network namespace ๐Ÿซถ)

Use the regular iptables-save/iptables-restore format for the filter file. These examples live in /etc/firejail:

webserver.net is a webserver firewall that allows access only to TCP ports 80 and 443. Example:

$ firejail --netfilter=/etc/firejail/webserver.net --net=eth0 \
/etc/init.d/apache2 start

nolocal.net/nolocal6.net is a desktop client firewall that disables access to the local network. Example:

$ firejail --netfilter=/etc/firejail/nolocal.net \
--net=eth0 /usr/bin/firefox
  • --netfilter=filename,arg1,arg2,arg3 ... โ€” the template version of the previous one, icon behavior honestly ๐Ÿ‘‘ $ARG1, $ARG2, $ARG3 โ€ฆ in the firewall script get replaced with arg1, arg2, arg3 โ€ฆ passed on the command line. Up to 16 arguments are supported. Example:
$ firejail --net=eth0 --ip=192.168.1.105 \
--netfilter=/etc/firejail/tcpserver.net,5001 server-program
  • --netfilter.print=name|pid โ€” prints the firewall installed in the sandbox specified by name or PID. Look at it go โœจ Example:
$ firejail --name=browser --net=eth0 --netfilter /usr/bin/firefox &
$ firejail --netfilter.print=browser
  • --netfilter6=filename โ€” the IPv6 sibling ๐Ÿ’œ enables the IPv6 firewall specified by filename if a new network namespace is created inside the sandbox. (Yep โ€” no effect for sandboxes using the system network namespace.) Use the regular iptables-save/iptables-restore format for the filter file.
  • --netfilter6.print=name|pid โ€” prints the IPv6 firewall installed in the sandbox specified by name or PID. Example:
$ firejail --name=browser --net=eth0 --netfilter /usr/bin/firefox &
$ firejail --netfilter6.print=browser
  • --netlock โ€” okay so picture this: several types of programs (email clients, multiplayer games, etc.) only talk to a very small number of IP addresses. But the best example is tor browser โ€” it only talks to a guard node, plus two or three more on standby in case the main one fails. During startup, the browser contacts all of them, and after that it keeps talking to the main oneโ€ฆ for weeks ๐Ÿ˜ญ

Use the network locking feature to build and deploy a custom network firewall in your sandbox. The firewall allows only the traffic to the IP addresses detected during the program startup. Traffic to any other address is quietly dropped. By default the network monitoring time is one minute.

A network namespace (--net=eth0) is required for this feature to work. No namespace, no vibes ๐Ÿ’…

Example:

$ firejail --net=eth0 --netlock \
--private=~/tor-browser_en-US ./start-tor-browser.desktop
  • --netmask=address โ€” use this when you want to assign an IP address in a new namespace and the parent interface specified by --net is not configured. You also gotta add an IP address and a default gateway address. By default the new namespace interface comes without IP address and default gateway configured. Example:
$ sudo /sbin/brctl addbr br0
$ sudo /sbin/ifconfig br0 up
$ firejail --ip=10.10.20.67 --netmask=255.255.255.0
--defaultgw=10.10.20.1
  • --netns=name โ€” run the program in a named, persistent network namespace. These can be created and configured using "ip netns". Persistent bestie stays around ๐Ÿฆ‹
  • --netstats โ€” monitors network namespace statistics, see the MONITORING section for more details.

Example:

$ firejail --netstats
PID  User    RX(KB/s) TX(KB/s) Command
1294 netblue 53.355   1.473    firejail --net=eth0
/usr/bin/firefox
7383 netblue 9.045    0.112    firejail --net=eth0
/usr/bin/transmission
  • --nettrace[=name|pid] โ€” monitors received TCP, UDP, and ICMP traffic ๐Ÿ”ฅ The sandbox can be specified by name or pid. Only networked sandboxes created with --net are supported. And ngl this one's only available when running the sandbox as root.

Without a name/pid, Firejail will monitor the main system network namespace.

Example:

$ sudo firejail --nettrace
                       93 KB/s  address:port (protocol) network
  14 B/s  **                    104.24.8.4:443(QUIC) Cloudflare
  80 KB/s *****************     192.187.97.90:443(TLS) BitChute
   1 B/s                        149.56.228.45:443(DoH) Canada
(D)isplay, (S)ave, (C)lear, e(X)it

If /usr/bin/geoiplookup is installed (the geoip-bin package in Debian), the country the traffic originates from gets added to the trace. We also use the static IP map in /usr/lib/firejail/static-ip-map to print the domain names for some of the more common websites and cloud platforms. And no cap โ€” no external services are contacted for reverse IP lookup ๐ŸŽ€

  • --nice=value โ€” sets the nice value for all processes running inside the sandbox. Only root may specify a negative value ๐Ÿ‘‘

Example:

$ firejail --nice=2 /usr/bin/firefox
  • --no3d โ€” disables 3D hardware acceleration. Your GPU is on a break bestie ๐Ÿ’…

Example:

$ firejail --no3d /usr/bin/firefox
  • --noautopulse (deprecated) โ€” see --keep-config-pulse. That's it, that's the whole option.
  • --noblacklist=dirname_or_filename โ€” disables blacklist for this directory or file. Un-blacklisting, the rebel era ๐ŸŒธ
Note that blacklist entries containing ${PATH} can not currently be partially disabled for individual expanded paths. Only the whole unexpanded path including ${PATH} can be disabled, which then applies to all expansions. This limitation does not apply to expansions of other variables or wildcards. For details, see #6360.

Example:

$ firejail
$ nc dict.org 2628
bash: /bin/nc: Permission denied
$ exit

$ firejail --noblacklist=/bin/nc
bash: /bin/nc: Permission denied
$ exit

$ firejail --noblacklist='${PATH}/nc'
$ nc dict.org 2628
220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64
  • --nodbus (deprecated) โ€” disables D-Bus access (both system and session buses). Equivalent to --dbus-system=none --dbus-user=none. Old but iconic ๐Ÿ’€

Example:

$ firejail --nodbus --net=none
  • --nodvd โ€” disables DVD and audio CD devices. No disc, no drama.

Example:

$ firejail --nodvd
  • --noexec=dirname_or_filename โ€” remounts the directory or file noexec, nodev and nosuid. File globbing is supported, see the FILE GLOBBING section for more details.

Example:

$ firejail --noexec=/tmp

/etc and /var are noexec by default if the sandbox was started as a regular user โœจ

  • --nogroups โ€” disables supplementary groups. Without this option, supplementary groups are enabled for the user starting the sandbox. For root user, supplementary groups are always disabled.
Note: by default all regular user groups are removed with the exception of the current user. This can be changed using the --allusers command option.

Example:

$ id
uid=1000(netblue) gid=1000(netblue)
groups=1000(netblue),24(cdrom),25(floppy),27(sudo),29(audio)
$ firejail --nogroups
Parent pid 8704, child pid 8705
Child process initialized
$ id
uid=1000(netblue) gid=1000(netblue) groups=1000(netblue)
$
  • --noinput โ€” disables input devices. Keyboard and mouse are officially uninvited ๐Ÿšซ

Example:

$ firejail --noinput
  • --nonewprivs โ€” sets the NO_NEW_PRIVS prctl ๐Ÿ›ก๏ธ. What that means in bestie terms: child processes literally cannot gain new privileges through execve(2). So if something tries to call a suid binary (or one of those sneaky files with file capabilities), the privilege level does not go up. Blocked. Periodt. This one is on by default whenever the seccomp filter is activated, so you're already slaying ๐Ÿ’….
  • --noprinters โ€” printers? gone. disabled. we don't know her ๐Ÿ–จ๏ธ๐Ÿ’€.
  • --noprofile โ€” do not use a security profile. just raw vibes, no profile.

Example:

$ firejail
Reading profile /etc/firejail/default.profile
Parent pid 8553, child pid 8554
Child process initialized
[...]

$ firejail --noprofile
Parent pid 8553, child pid 8554
Child process initialized
[...]
  • --noroot โ€” installs a user namespace with a single user: the current user. the root user straight up does not exist in the new namespace ๐Ÿ˜ค. Requires Linux kernel version 3.8 or newer. Heads up though โ€” this option is not supported for --chroot and --appimage configurations, or for sandboxes started as root ๐Ÿšซ.

Example:

$ firejail --noroot
Parent pid 8553, child pid 8554
Child process initialized
$ ping google.com
ping: icmp open socket: Operation not permitted
$
  • --nosound โ€” disable the sound system ๐Ÿ”‡. silence, but make it cute.

Example:

$ firejail --nosound /usr/bin/firefox
  • --notpm โ€” (deprecated) ignored, kept around for compatibility only. TPM devices are now blocked by default anyway, see --keep-dev-tpm ๐ŸŽ€.
  • --notv โ€” disable DVB (Digital Video Broadcasting) TV devices ๐Ÿ“บโœจ.

Example:

$ firejail --notv /usr/bin/vlc
  • --nou2f โ€” disable U2F devices ๐Ÿ”‘.

Example:

$ firejail --nou2f
  • --novideo โ€” disable video devices ๐Ÿ“น๐Ÿ™ˆ.
  • --nowhitelist=dirname_or_filename โ€” disable the whitelist for this specific directory or file. one tiny exception, no cap.
  • --oom=value โ€” configures the kernel's OutOfMemory-killer score for this sandbox ๐Ÿ’€. acceptable score values are between 0 and 1000 for regular users, and -1000 to 1000 for root. want the full lore on the OOM kernel feature? see man choom.

Example:

$ firejail --oom=300 /usr/bin/firefox
  • --output=logfile โ€” stdout logging and log rotation ๐Ÿ”ฅ. copies stdout to logfile, and keeps the size of the file under 500KB using log rotation. five files with prefixes .1 to .5 are used in rotation.

Example:

$ firejail --output=sandboxlog /bin/bash
[...]
$ ls -l sandboxlog*
-rw-r--r-- 1 netblue netblue 333890 Jun  2 07:48 sandboxlog
-rw-r--r-- 1 netblue netblue 511488 Jun  2 07:48 sandboxlog.1
-rw-r--r-- 1 netblue netblue 511488 Jun  2 07:48 sandboxlog.2
-rw-r--r-- 1 netblue netblue 511488 Jun  2 07:48 sandboxlog.3
-rw-r--r-- 1 netblue netblue 511488 Jun  2 07:48 sandboxlog.4
-rw-r--r-- 1 netblue netblue 511488 Jun  2 07:48 sandboxlog.5
  • --output-stderr=logfile โ€” same energy as --output, except stderr is also stored ๐Ÿซถ.
  • --private โ€” mounts a brand new /root and /home/user directory inside temporary filesystems ๐Ÿงš. every single modification is discarded when the sandbox closes. literally a clean slate every time, iconic.

Example:

$ firejail --private /usr/bin/firefox
  • --private=directory โ€” use directory as the user home ๐Ÿ . note that --private and --private=directory cannot be used together โ€” pick one, bestie.

Example:

$ firejail --private=/home/netblue/firefox-home /usr/bin/firefox
๐Ÿ› Bug: even with this enabled, some firejail commands (such as mkdir, mkfile and private-cache) will still operate on the original home directory. Workaround: disable the incompatible commands, such as by using "ignore mkdir" and "ignore mkfile". for details, see #903.
  • --private-bin=file,file โ€” builds a whole new /bin in a temporary filesystem and copies the programs in the list into it ๐ŸŒธ. the files in the list must be expressed as relative to the /bin, /sbin, /usr/bin, /usr/sbin, or /usr/local/bin directories. if no listed files are found, the /bin directory will be empty ๐Ÿ˜ญ. the same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin. all modifications are discarded when the sandbox is closed. multiple private-bin commands are allowed and they accumulate. file globbing is supported, see FILE GLOBBING section for more details.

Example:

$ firejail --private-bin=bash,cat,ls,sed
Parent pid 20841, child pid 20842
Child process initialized
$ ls /bin
bash  cat  ls  sed
  • --private-cache โ€” mounts an empty temporary filesystem on top of the .cache directory in user home ๐ŸŽ€. all modifications are discarded when the sandbox is closed.

Example:

$ firejail --private-cache /usr/bin/openbox
  • --private-cwd โ€” sets the working directory inside the jail to the home directory, and failing that, the root directory ๐Ÿ“. does not impact the working directory of profile include paths.

Example:

$ pwd
/tmp
$ firejail --private-cwd
$ pwd
/home/user
  • --private-cwd=directory โ€” set the working directory inside the jail to directory ๐Ÿ—‚๏ธ. a full directory path is required. symbolic links are not allowed ๐Ÿšซ. does not impact the working directory of profile include paths.

Example:

$ pwd
/tmp
$ firejail --private-cwd=/opt
$ pwd
/opt
  • --private-dev โ€” creates a new /dev directory โœจ. only these devices are available: disc, dri, dvb, full, hidraw, log, null, ptmx, pts, random, shm, snd, tty, urandom, usb, video and zero. want even more restrictions? use the options --no3d, --nodvd, --nosound, --notv, --nou2f and --novideo ๐Ÿ’….

Example:

$ firejail --private-dev
Parent pid 9887, child pid 9888
Child process initialized
$ ls /dev
cdrom  cdrw  dri  dvd  dvdrw  full  log  null  ptmx  pts  random
shm  snd  sr0  tty  urandom  zero
$
  • --private-etc, --private-etc=@group,file,directory โ€” the files installed by --private-etc are copies of the original system files from the /etc directory ๐Ÿงš. by default, the command brings in a skeleton of files and directories used by most console tools:
$ firejail --private-etc /usr/bin/dig debian.org

for X11/GTK/QT/Gnome/KDE programs, add the @x11 group as a parameter. Example:

$ firejail --private-etc=@x11,gcrypt,python* /usr/bin/gimp

so gcrypt and the /etc/python* directories are not part of the generic @x11 group. file globbing is supported โœจ.

for games, add the @games group:

$ firejail --private-etc=@games,@x11 /usr/bin/warzone2100

sound and networking files are included automatically, unless --nosound or --net=none are specified. files for encrypted TLS/SSL protocol live in the @tls-ca group ๐Ÿ”.

$ firejail --private-etc=@tls-ca,wgetrc /usr/bin/wget
https://debian.org
๐Ÿ’ก Note: the easiest way to extract the list of /etc files accessed by your program is by using the strace utility.

Example:

$ strace -f --trace=%file /usr/bin/transmission-qt 2>&1 | grep
etc

$ firejail --allow-debuggers
--profile=/etc/firejail/transmission-qt.profile strace -f
--trace=%file /usr/bin/transmission-qt 2>&1 | grep etc

see also --allow-debuggers and --trace ๐Ÿ‘€.

  • --private-opt=file,directory โ€” builds a new /opt in a temporary filesystem and copies the files and directories in the list ๐Ÿ—ƒ๏ธ. the files and directories in the list must be expressed as relative to the /opt directory, and must not contain the / character (e.g., /opt/foo must be expressed as foo, but /opt/foo/bar โ€” expressed as foo/bar โ€” is disallowed ๐Ÿšซ). if no listed file is found, the /opt directory will be empty. all modifications are discarded when the sandbox is closed.

Example:

$ firejail --private-opt=firefox /opt/firefox/firefox
โš ๏ธ Note: program installations in /opt tend to be relatively large, and private-opt copies the entire path(s) into RAM, which may significantly increase RAM usage and break file-copy-limit in firejail.config ๐Ÿ’€. therefore, in general it's recommended to use "whitelist /opt/PATH" instead of "private-opt PATH". for details, see #5307.
  • --private-srv=file,directory โ€” builds a new /srv in a temporary filesystem and copies the files and directories in the list ๐ŸŒˆ. the files and directories in the list must be expressed as relative to the /srv directory, and must not contain the / character (e.g., /srv/foo must be expressed as foo, but /srv/foo/bar โ€” expressed as srv/bar โ€” is disallowed). if no listed file is found, the /srv directory will be empty. all modifications are discarded when the sandbox is closed.

Example:

# firejail --private-srv=www /etc/init.d/apache2 start
  • --private-tmp โ€” mounts an empty temporary filesystem on top of the /tmp directory, whitelisting X11 and PulseAudio sockets ๐ŸŽงโœจ.

Example:

$ firejail --private-tmp
$ ls -al /tmp
drwxrwxrwt  4 nobody nogroup   80 Apr 30 11:46 .
drwxr-xr-x 30 nobody nogroup 4096 Apr 26 22:18 ..
drwx------  2 nobody nogroup 4096 Apr 30 10:52 pulse-PKdhtXMmr18n
drwxrwxrwt  2 nobody nogroup 4096 Apr 30 10:52 .X11-unix
  • --profile=filename|appname โ€” loads a custom security profile from filename, or uses the name of a specific application ๐Ÿ“œ๐Ÿ‘‘.

if the command line option --profile is not provided, Firejail will attempt to extract the appname from the target program filename. it will then search the ~/.config/firejail directory for a suitable profile, followed by a search in /etc/firejail/directory.

Example:

$ firejail /usr/bin/firefox
Reading profile /home/netblue/.config/firejail/firefox.profile
Reading profile /etc/firejail/firefox.profile
Reading profile /etc/firejail/firefox-common.profile
[...]

when using a filename, please include a full path or a relative path ๐Ÿซถ.

$ firejail --profile=./firefox.profile /usr/bin/firefox
Reading profile ./firefox.profile
Reading profile /etc/firejail/firefox.profile
Reading profile /etc/firejail/firefox-common.profile
[...]

And lowkey the --profile=appname form is that girl when you're messing with appimages:

$ firejail --appimage --profile=firefox firefox-nightly-148.0.r20260103-x86_64.AppImage
Reading profile /home/netblue/.config/firejail/firefox.profile
Reading profile /etc/firejail/firefox.profile
Reading profile /etc/firejail/firefox-common.profile
[...]

See man 5 firejail-profile for the whole profile file syntax tea โ˜•, and for the profile resolution lore (like, how does it pick which file, bestie) see https://github.com/netblue30/firejail/wiki/Creating-Profiles.

  • --profile.print=name|pid โ€” prints the name of the profile file for the sandbox you point at with name or PID. Like a little name tag for your sandbox ๐Ÿท๏ธ

Example:

$ firejail --profile.print=browser
/etc/firejail/firefox.profile
  • --protocol=protocol,protocol,protocol โ€” turns on the protocol filter, periodt. This filter is seccomp-based and it checks the first argument passed to the socket system call. The recognized values are: unix, inet, inet6, netlink, packet, and bluetooth. Heads up: this option is not supported on i386 architecture ๐Ÿ’€. You can stack multiple --protocol commands and they accumulate.

Example:

$ firejail --protocol=unix,inet,inet6 /usr/bin/firefox
  • --protocol.print=name|pid โ€” prints the protocol filter for the sandbox identified by name or PID.

Example:

$ firejail --name=mybrowser /usr/bin/firefox &
$ firejail --protocol.print=mybrowser
unix,inet,inet6,netlink

Example:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --protocol.print=3272
unix,inet,inet6,netlink
  • --put=name|pid src-filename dest-filename โ€” drops a file into the sandbox container ๐ŸŽ. More deets live in the FILE TRANSFER section, iykyk.
  • --quiet โ€” silences Firejail's output. Shhh ๐Ÿคซ

You can get the exact same energy by setting the environment variable FIREJAIL_QUIET to yes.

  • --read-only=dirname_or_filename โ€” locks a directory or file to read-only ๐Ÿ”’. File globbing is supported โ€” check the FILE GLOBBING section for the details.

Example:

$ firejail --read-only=~/.mozilla /usr/bin/firefox
  • --read-write=dirname_or_filename โ€” makes a directory or file read-write again โœ๏ธ. Only files or directories that belong to the current user are allowed for this one, no cap. File globbing is supported, see FILE GLOBBING.

Example:

$ mkdir ~/test
$ touch ~/test/a
$ firejail --read-only=~/test --read-write=~/test/a
  • --restrict-namespaces โ€” installs a seccomp filter that blocks any attempt to create new cgroup, ipc, net, mount, pid, time, user or uts namespaces. No new namespace era for you ๐Ÿšซ

Example:

$ firejail --restrict-namespaces
  • --restrict-namespaces=cgroup,ipc,net,mnt,pid,time,user,uts โ€” same vibe but picky: installs a seccomp filter that blocks attempts to create any of the namespaces you actually listed. The filter peeks at the arguments of the clone, unshare and setns system calls, and returns error EPERM to the process (or kills it, or logs the attempt โ€” see --seccomp-error-action below) when it needs to. Important caveat bestie: the filter can't examine the arguments of clone3 system calls, and it always responds to those with error ENOSYS.

Example:

$ firejail --restrict-namespaces=user,net
  • --rlimit-as=number โ€” sets the maximum size of the process's virtual memory (address space) in bytes. You can use K(ibibyte), M(ebibyte) or G(ibibyte) as a suffix, like "100M" (which is literally equivalent to 104857600 bytes).
  • --rlimit-cpu=number โ€” caps, in seconds, how much CPU time each sandboxed process is allowed to eat. Hit the limit and the processes get killed ๐Ÿ’€.

Fr fr though: the CPU limit is a limit on CPU seconds, not elapsed/wall-clock time. CPU seconds is basically how many seconds the CPU has actually been in use, so it doesn't necessarily line up with the elapsed time you feel. The Linux kernel keeps track of CPU seconds for each process independently.

  • --rlimit-fsize=number โ€” sets the maximum file size that a process can create. Same suffix deal: K(ibibyte), M(ebibyte) or G(ibibyte), like "100M" (which is equivalent to 104857600 bytes).
  • --rlimit-nofile=number โ€” sets the max number of files a process can have open at once ๐Ÿ“‚.
  • --rlimit-nproc=number โ€” sets the max number of processes that can be created for the real user ID of the calling process.
  • --rlimit-sigpending=number โ€” sets the max number of pending signals a process can have queued up ๐Ÿ“ถ.
  • --rmenv=name โ€” removes an environment variable inside the new sandbox ๐Ÿงน.

Example:

$ firejail --rmenv=DBUS_SESSION_BUS_ADDRESS
  • --scan โ€” ARP-scan all the networks from inside a network namespace. This makes it possible to detect macvlan kernel device drivers running on the current host ๐Ÿ•ต๏ธโ€โ™€๏ธ.

Example:

$ firejail --net=eth0 --scan
  • --seccomp โ€” enables the seccomp filter and blacklists the syscalls in the default list, which is @default-nodebuggers unless --allow-debuggers is specified โ€” in which case it's @default. Iconic security behavior, honestly ๐Ÿ‘‘

So you can build useful seccomp filters without losing your mind, these system call groups are defined: @aio, @basic-io, @chown, @clock, @cpu-emulation, @debug, @default, @default-nodebuggers, @default-keep, @file-system, @io-event, @ipc, @keyring, @memfd, @memlock, @module, @mount, @network-io, @obsolete, @privileged, @process, @program-keep, @raw-io, @reboot, @resources, @sandbox, @setuid, @swap, @sync, @system-service and @timer. More info about the groups lives in /usr/share/doc/firejail/syscalls.txt, and also go look at --debug-syscall-groups.

The default list can be customized โ€” see --seccomp= for the description โœจ. It can also be customized globally in the /etc/firejail/firejail.config file.

System architecture is strictly imposed only if the flag --seccomp.block-secondary is used. The filter gets applied at run time only if the correct architecture was detected. For the I386 and AMD64 case, both 32-bit and 64-bit filters are installed.

Firejail will print seccomp violations to the audit log if the kernel was compiled with audit support (the CONFIG_AUDIT flag).

Example:

$ firejail --seccomp
  • --seccomp=syscall,@group,!syscall2 โ€” enables the seccomp filter, blacklists the default list and the syscalls or syscall groups you name in the command, but does not blacklist syscall2 (that ! is a hard no ๐Ÿ™…โ€โ™€๏ธ). On a 64 bit architecture, you can install an additional filter for 32 bit system calls with --seccomp.32.

Example:

$ firejail --seccomp=utime,utimensat,utimes /usr/bin/firefox
$ firejail --seccomp=@clock,mkdir,unlinkat /usr/bin/transmission-gtk
$ firejail '--seccomp=@ipc,!pipe,!pipe2' audacious

You can also name syscalls by their number โ€” just slap a $ prefix on it, so for example "$165" corresponds to "mount" on the x86_64 architecture. You can find the syscall numbers and names for --seccomp by using --debug-syscalls and --debug-syscalls32 for --seccomp.32.

Instead of dropping the syscall by returning EPERM, you can return a different error number using the syscall:errno syntax ๐ŸŽฏ. This can also be changed globally with --seccomp-error-action or in the /etc/firejail/firejail.config file. You can also straight-up kill the process using the syscall:kill syntax, or log the attempt without blocking the syscall using syscall:log.

Example:

$ firejail --seccomp=unlinkat:ENOENT,utimensat,utimes
Parent pid 10662, child pid 10663
Child process initialized
$ touch testfile
$ ls testfile
testfile
$ rm testfile
rm: cannot remove `testfile': No such file or directory

If the blocked system calls would also block Firejail from operating (oops), they're handled by adding a preloaded library that performs the seccomp system calls later. But โ€” warning bestie โ€” this is incompatible with 32 bit seccomp filters โš ๏ธ.

Example:

$ firejail --noprofile --seccomp=execve sh
Parent pid 32751, child pid 32752
Post-exec seccomp protector enabled
list in: execve, check list: @default-keep prelist: (null), postlist: execve
Child process initialized in 46.44 ms
$ ls
Operation not permitted
  • --seccomp.block-secondary โ€” enables the seccomp filter and filters system call architectures so that only the native architecture is allowed ๐ŸŒ. For example, on amd64, i386 and x32 system calls are blocked, and so is changing the execution domain with the personality(2) system call.
  • --seccomp.drop=syscall,@group โ€” enables the seccomp filter and blacklists the syscalls or the syscall groups you name in the command. On a 64 bit architecture, you can install an additional filter for 32 bit system calls with --seccomp.32.drop.

Example:

$ firejail --seccomp.drop=utime,utimensat,utimes,@clock

Instead of dropping the syscall by returning EPERM, you can return another error number using the syscall:errno syntax ๐Ÿ’…. This can also be changed globally with --seccomp-error-action or in the /etc/firejail/firejail.config file. You can kill the process too with the syscall:kill syntax, or log the attempt without blocking the syscall with syscall:log.

Example:

$ firejail --seccomp.drop=unlinkat:ENOENT,utimensat,utimes
Parent pid 10662, child pid 10663
Child process initialized
$ touch testfile
$ ls testfile
testfile
$ rm testfile
rm: cannot remove `testfile': No such file or directory
  • --seccomp.keep=syscall,@group,!syscall2 โ€” okay bestie, this one switches the seccomp filter ON โœจ โ€” it blacklists every syscall you didn't list, plus syscall2. The syscalls Firejail itself needs (group @default-keep: prctl, execve, execveat) get handled by the preload library ๐Ÿซถ. On a 64-bit architecture you can stack an extra filter for 32-bit system calls using --seccomp.32.keep.

Example, because vibes need receipts:

$ firejail --seccomp.keep=poll,select,[...]
/usr/bin/transmission-gtk
  • --seccomp.print=name|pid โ€” prints out the seccomp filter for the sandbox you name (or point at with a PID). It's giving raw BPF realness ๐Ÿ’…
$ firejail --name=browser /usr/bin/firefox &
$ firejail --seccomp.print=browser
 line  OP JT JF    K
=================================
 0000: 20 00 00 00000004   ld  data.architecture
 0001: 15 01 00 c000003e   jeq ARCH_64 0003 (false 0002)
 0002: 06 00 00 7fff0000   ret ALLOW
 0003: 20 00 00 00000000   ld  data.syscall-number
 0004: 35 01 00 40000000   jge X32_ABI true:0006 (false 0005)
 0005: 35 01 00 00000000   jge read 0007 (false 0006)
 0006: 06 00 00 00050001   ret ERRNO(1)
 0007: 15 41 00 0000009a   jeq modify_ldt 0049 (false 0008)
 0008: 15 40 00 000000d4   jeq lookup_dcookie 0049 (false 0009)
 0009: 15 3f 00 0000012a   jeq perf_event_open 0049 (false 000a)
 000a: 15 3e 00 00000137   jeq process_vm_writev 0049 (false 000b)
 000b: 15 3d 00 0000009c   jeq _sysctl 0049 (false 000c)
 000c: 15 3c 00 000000b7   jeq afs_syscall 0049 (false 000d)
 000d: 15 3b 00 000000ae   jeq create_module 0049 (false 000e)
 000e: 15 3a 00 000000b1   jeq get_kernel_syms 0049 (false 000f)
 000f: 15 39 00 000000b5   jeq getpmsg 0049 (false 0010)
 0010: 15 38 00 000000b6   jeq putpmsg 0049 (false 0011)
 0011: 15 37 00 000000b2   jeq query_module 0049 (false 0012)
 0012: 15 36 00 000000b9   jeq security 0049 (false 0013)
 0013: 15 35 00 0000008b   jeq sysfs 0049 (false 0014)
 0014: 15 34 00 000000b8   jeq tuxcall 0049 (false 0015)
 0015: 15 33 00 00000086   jeq uselib 0049 (false 0016)
 0016: 15 32 00 00000088   jeq ustat 0049 (false 0017)
 0017: 15 31 00 000000ec   jeq vserver 0049 (false 0018)
 0018: 15 30 00 0000009f   jeq adjtimex 0049 (false 0019)
 0019: 15 2f 00 00000131   jeq clock_adjtime 0049 (false 001a)
 001a: 15 2e 00 000000e3   jeq clock_settime 0049 (false 001b)
 001b: 15 2d 00 000000a4   jeq settimeofday 0049 (false 001c)
 001c: 15 2c 00 000000b0   jeq delete_module 0049 (false 001d)
 001d: 15 2b 00 00000139   jeq finit_module 0049 (false 001e)
 001e: 15 2a 00 000000af   jeq init_module 0049 (false 001f)
 001f: 15 29 00 000000ad   jeq ioperm 0049 (false 0020)
 0020: 15 28 00 000000ac   jeq iopl 0049 (false 0021)
 0021: 15 27 00 000000f6   jeq kexec_load 0049 (false 0022)
 0022: 15 26 00 00000140   jeq kexec_file_load 0049 (false 0023)
 0023: 15 25 00 000000a9   jeq reboot 0049 (false 0024)
 0024: 15 24 00 000000a7   jeq swapon 0049 (false 0025)
 0025: 15 23 00 000000a8   jeq swapoff 0049 (false 0026)
 0026: 15 22 00 000000a3   jeq acct 0049 (false 0027)
 0027: 15 21 00 00000141   jeq bpf 0049 (false 0028)
 0028: 15 20 00 000000a1   jeq chroot 0049 (false 0029)
 0029: 15 1f 00 000000a5   jeq mount 0049 (false 002a)
 002a: 15 1e 00 000000b4   jeq nfsservctl 0049 (false 002b)
 002b: 15 1d 00 0000009b   jeq pivot_root 0049 (false 002c)
 002c: 15 1c 00 000000ab   jeq setdomainname 0049 (false 002d)
 002d: 15 1b 00 000000aa   jeq sethostname 0049 (false 002e)
 002e: 15 1a 00 000000a6   jeq umount2 0049 (false 002f)
 002f: 15 19 00 00000099   jeq vhangup 0049 (false 0030)
 0030: 15 18 00 000000ee   jeq set_mempolicy 0049 (false 0031)
 0031: 15 17 00 00000100   jeq migrate_pages 0049 (false 0032)
 0032: 15 16 00 00000117   jeq move_pages 0049 (false 0033)
 0033: 15 15 00 000000ed   jeq mbind 0049 (false 0034)
 0034: 15 14 00 00000130   jeq open_by_handle_at 0049 (false 0035)
 0035: 15 13 00 0000012f   jeq name_to_handle_at 0049 (false 0036)
 0036: 15 12 00 000000fb   jeq ioprio_set 0049 (false 0037)
 0037: 15 11 00 00000067   jeq syslog 0049 (false 0038)
 0038: 15 10 00 0000012c   jeq fanotify_init 0049 (false 0039)
 0039: 15 0f 00 00000138   jeq kcmp 0049 (false 003a)
 003a: 15 0e 00 000000f8   jeq add_key 0049 (false 003b)
 003b: 15 0d 00 000000f9   jeq request_key 0049 (false 003c)
 003c: 15 0c 00 000000fa   jeq keyctl 0049 (false 003d)
 003d: 15 0b 00 000000ce   jeq io_setup 0049 (false 003e)
 003e: 15 0a 00 000000cf   jeq io_destroy 0049 (false 003f)
 003f: 15 09 00 000000d0   jeq io_getevents 0049 (false 0040)
 0040: 15 08 00 000000d1   jeq io_submit 0049 (false 0041)
 0041: 15 07 00 000000d2   jeq io_cancel 0049 (false 0042)
 0042: 15 06 00 000000d8   jeq remap_file_pages 0049 (false 0043)
 0043: 15 05 00 00000116   jeq vmsplice 0049 (false 0044)
 0044: 15 04 00 00000087   jeq personality 0049 (false 0045)
 0045: 15 03 00 00000143   jeq userfaultfd 0049 (false 0046)
 0046: 15 02 00 00000065   jeq ptrace 0049 (false 0047)
 0047: 15 01 00 00000136   jeq process_vm_readv 0049 (false 0048)
 0048: 06 00 00 7fff0000   ret ALLOW
 0049: 06 00 01 00000000   ret KILL
$
  • --seccomp-error-action= kill | ERRNO | log โ€” so by default, when a seccomp filter blocks a system call, the process gets EPERM as its error ๐Ÿ˜ค. With --seccomp-error-action=error you can hand back a different error number instead โ€” think ENOSYS or EACCES. You can also just kill the process (the way versions <0.9.63 of Firejail did it) with the --seccomp-error-action=kill syntax, or log the attempt using --seccomp-error-action=log.
Real talk: not killing the process weakens Firejail slightly when it's trying to contain an intrusion โ€” but it can also let you keep tighter filters when the only other option is allowing a system call. Trade-offs, bestie ๐Ÿ’€

  • --shutdown=name|pid โ€” shuts down the sandbox you point at by name or PID ๐Ÿ›‘ bye felicia.
$ firejail --name=mygame --caps.drop=all /usr/bin/warzone2100 &
$ firejail --shutdown=mygame

And with a PID:

$ firejail --list
3272:netblue::firejail --private /usr/bin/firefox
$ firejail --shutdown=3272
  • --snitrace[=name|pid] โ€” monitors Server Name Indication (TLS/SNI) ๐Ÿ‘€โœจ. You can point it at a sandbox by name or pid. Only networked sandboxes created with --net are supported โ€” and this option is only available when you're running the sandbox as root.

If you don't give it a name/pid, Firejail just monitors the main system network namespace. Main character energy fr fr ๐ŸŒˆ

$ sudo firejail --snitrace
07:49:51  23.185.0.3       linux.com
07:49:51  23.185.0.3       www.linux.com
07:50:05  192.0.73.2       secure.gravatar.com
07:52:35  172.67.68.93     www.howtoforge.com
07:52:37  13.225.103.59    sf.ezoiccdn.com
07:52:42  142.250.176.3    www.gstatic.com
07:53:03  173.236.250.32   www.linuxlinks.com
07:53:05  192.0.77.37      c0.wp.com
07:53:08  192.0.78.32      jetpack.wordpress.com
07:53:09  192.0.77.32      s0.wp.com
07:53:09  192.0.77.2       i0.wp.com
07:53:10  192.0.77.2       i0.wp.com
07:53:11  192.0.73.2       1.gravatar.com
  • --tab โ€” turns on shell tab completion inside sandboxes that use private or whitelisted home directories ๐ŸŽ€ because typing full paths is not the vibe.
$ firejail --private --tab
  • --timeout=hh:mm:ss โ€” kills the sandbox automatically once that much time has elapsed โฐ๐Ÿ’€. Time goes in hours/minutes/seconds format.
$ firejail --timeout=01:30:00 /usr/bin/firefox
  • --tmpfs=dirname โ€” mounts a writable tmpfs filesystem on the directory dirname โœจ. Directories outside the user's home, or ones not owned by the user, are not allowed โ€” sandboxes running as root are exempt from those restrictions ๐Ÿ‘‘. File globbing is supported, so peep the FILE GLOBBING section for the deets.
$ firejail --tmpfs=~/.local/share
  • --top โ€” monitors the most CPU-intensive sandboxes ๐Ÿฅต๐Ÿ”ฅ, see the MONITORING section for more.
$ firejail --top

  • --trace[=filename] โ€” traces open, access and connect system calls ๐Ÿ•ต๏ธโ€โ™€๏ธโœจ. Give it a filename and the trace output gets logged there; leave it out and it goes to the console.
$ firejail --trace /usr/bin/wget -q www.debian.org
Reading profile /etc/firejail/wget.profile
3:wget:fopen64 /etc/wgetrc:0x5c8e8ce6c0
3:wget:fopen /etc/hosts:0x5c8e8cfb70
3:wget:socket AF_INET SOCK_DGRAM IPPROTO_IP:3
3:wget:connect 3 8.8.8.8 port 53:0
3:wget:socket AF_INET SOCK_STREAM IPPROTO_IP:3
3:wget:connect 3 130.89.148.14 port 80:0
3:wget:fopen64 index.html:0x5c8e8d1a60

parent is shutting down, bye...

See also --allow-debuggers and --private-etc. iykyk ๐Ÿ’…

  • --tree โ€” prints a tree of all sandboxed processes ๐ŸŒณโœจ, see the MONITORING section for the full picture.
$ firejail --tree
11903:netblue:firejail /usr/bin/iceweasel
  11904:netblue:iceweasel
    11957:netblue:/usr/lib/iceweasel/plugin-container
11969:netblue:firejail --net=eth0 /usr/bin/transmission-gtk
  11970:netblue:transmission-gtk
  • --unhide-pid1 โ€” so pid 1 is always present inside a Firejail sandbox, but by restricting access to the /proc kernel interface, general tools like ps can't view or access this process ๐Ÿ™ˆ. The --unhide-pid1 option disables that functionality. Example:
$ firejail --name=test    ### by default pid 1 is not visible
[...]
Child process initialized in 59.41 ms
$  ps a
    PID TTY      STAT   TIME COMMAND
      4 ?        S      0:00 /bin/bash
      5 ?        R+     0:00 ps a
$ exit
Parent is shutting down, byeโ€ฆ
$ firejail --name=test --unhide-pid1  ### pid 1 is visible
[...]
Child process initialized in 58.29 ms
$ ps a
   PID TTY      STAT   TIME COMMAND
      1 ?        S      0:00 firejail --name=test --unhide-pid1
      4 ?        S      0:00 /bin/bash
      6 ?        R+     0:00 ps a
$ exit
Parent is shutting down, byeโ€ฆ
  • --version โ€” prints the program version and the compile-time support list, then dips out. Straight to the point, no cap.
$ firejail --version
firejail version 0.9.81

Compile time support:
    - always force nonewprivs support is disabled
    - AppArmor support is enabled
    - AppImage support is enabled
    - chroot support is disabled
    - D-BUS proxy support is enabled
    - file transfer support is enabled
    - Landlock support is enabled
    - networking support is enabled
    - output logging is enabled
    - SELinux support is disabled
    - user namespace support is enabled
    - X11 sandboxing support is enabled
    - Xorg security extension and xvfb support is enabled
  • --veth-name=name โ€” picks the name for the interface that's plugged into the bridge for --net=bridge_interface commands, instead of the default name it'd normally use. Name your little network baby whatever you want ๐Ÿ’–
$ firejail --net=br0 --veth-name=if0
  • --whitelist=dirname_or_filename โ€” whitelist a directory or a file, bestie. Firejail mounts a temporary file system on top of the top directory. And in firejail-speak, "top directory" means: if the whitelisted file's path is, like, /etc/somedir/somefile, then the top directory is /etc. Every other top directory โ€” /opt, /usr, all of them โ€” hasn't changed, so every file in them is still accessible, unless you also whitelist a file or directory inside them. That's why sometimes it's genuinely beneficial to use blacklist together with whitelist, if you're using them for different top directories. Combo move โœจ

The whitelisted files get mount-binded inside. Modifications to whitelisted files are persistent; literally everything else in the same top directory gets discarded when the sandbox closes. Gone. Ghosted. ๐Ÿ’€

The top directory can be most directories in /, but there are some special cases. The /proc and /sys top directories aren't allowed, but /sys/module is. Also /run/user/$UID, $HOME and all directories in /usr are treated as a top directory.

Symbolic link handling, listen up: whitelisting a path that's a symbolic link will also whitelist the path it points to. So like, if ~/foo is whitelisted and it points to ~/bar, then ~/bar gets whitelisted too. Restrictions though: with the exception of the user home directory, both the link and the real file should be in the same top directory. And for symbolic links in the user home directory, both the link and the real file should be owned by the user.

File globbing is supported โ€” go check the FILE GLOBBING section for the deets.

$ firejail --noprofile --whitelist=~/.mozilla
$ firejail --whitelist=/tmp/.X11-unix --whitelist=/dev/null
$ firejail --whitelist="/home/username/My Virtual Machines"
$ firejail --whitelist=/home/username/My\ Virtual\ Machines
$ firejail --whitelist=~/work* --whitelist=/var/backups*
  • --writable-etc โ€” mounts the /etc directory read-write. Yeah, actually writable. Be normal about it ๐Ÿ™ˆ
$ sudo firejail --writable-etc
  • --writable-run-user โ€” disables the default blacklisting of /run/user/$UID/systemd and /run/user/$UID/gnupg.
$ sudo firejail --writable-run-user
  • --writable-var โ€” mounts the /var directory read-write.
$ sudo firejail --writable-var
  • --writable-var-log โ€” uses the real /var/log directory, not a clone. Because by default a tmpfs is mounted on top of the /var/log directory, and a skeleton filesystem is created based on the original /var/log. So this is the "give me the actual logs" button ๐Ÿซถ
$ sudo firejail --writable-var-log
  • --x11 โ€” sandboxes the app using the Xephyr X11 server. The sandbox stops screenshot and keylogger apps started inside the sandbox from reaching clients running outside it. Main character security behaviour, honestly ๐Ÿ‘‘

The default window size is 800x600. You can change that in the /etc/firejail/firejail.config file.

Note: a network namespace needs to be instantiated in order to deny access to the X11 abstract Unix domain socket. So yeah, that's a whole thing.

Xephyr is developed by the Xorg project. On Debian platforms it's installed with the command sudo apt-get install xserver-xephyr. Heads up though: this feature is not available when running as root.

$ firejail --x11 --net=eth0 /usr/bin/firefox

You can also run a display server inside the sandbox, which is lowkey iconic:

$ firejail --x11 --net=eth0 /usr/bin/openbox

A security profile for openbox is provided. Slay.

  • --x11=none โ€” blacklists the /tmp/.X11-unix directory, ${HOME}/.Xauthority and the file specified in the ${XAUTHORITY} environment variable. Removes the DISPLAY and XAUTHORITY environment variables. And it stops with an error message if the X11 abstract socket would be accessible in the jail. No X11 for you, periodt.
  • --xephyr-extra-params=OPTIONS โ€” sets extra parameters for the Xephyr server command, for the Xephyr X11 server. This setting overwrites the default set in /etc/firejail/firejail.config, but only for the current sandbox. Run Xephyr -help to get the list of available options ๐Ÿฆ‹
$ firejail --net=eth0 --x11 --xephyr-extra-params="-title
firefox" /usr/bin/firefox
  • --xephyr-screen=WIDTHxHEIGHT โ€” sets the screen size for the Xephyr X11 server. This setting overwrites the default set in /etc/firejail/firejail.config for the current sandbox. Run xrandr to get a list of supported resolutions on your computer ๐ŸŒธ
$ firejail --net=eth0 --x11 --xephyr-screen=640x480
/usr/bin/firefox

๐Ÿ›ก๏ธ APPARMOR

AppArmor support is disabled by default at compile time. Use the --enable-apparmor configuration option to enable it, okay?

$ ./configure --prefix=/usr --enable-apparmor

During software install, a generic AppArmor profile file, firejail-default, is placed in the /etc/apparmor.d directory. Any local customizations have to go in /etc/apparmor.d/local/firejail-local. The profile needs to be loaded into the kernel by reloading apparmor.service, rebooting the system, or running the following command as root:

# apparmor_parser -r /etc/apparmor.d/firejail-default

The installed profile is supplemental for the main firejail functions and, among other things, does the following:

  • Disable ptrace. With ptrace it's possible to inspect and hijack running programs. Usually this is needed only for debugging. You should have no problems running Chromium or Firefox. This feature is available only on Ubuntu kernels.
  • Whitelist write access to several files under /run, /proc and /sys.
  • Allow running programs only from well-known system paths, such as /bin, /sbin, /usr/bin etc. Those paths are available as read-only. Running programs and scripts from user home or other directories writable by the user is not allowed.
  • Prevent using non-standard network sockets. Only unix, inet, inet6, netlink, raw and packet are allowed.
  • Deny access to known sensitive paths like .snapshots.

To enable AppArmor confinement on top of your current Firejail security features, pass the --apparmor flag to the Firejail command line. You can also include the apparmor command in a Firejail profile file ๐Ÿ’œ

$ firejail --apparmor /usr/bin/firefox

๐Ÿ–ฅ๏ธ DESKTOP INTEGRATION

Okay so this is the part that's genuinely magic: a symbolic link to /usr/bin/firejail under the name of a program will start that program in a Firejail sandbox. The symlink should be placed in the first $PATH position. On most systems, a good place is the /usr/local/bin directory โœจ

Make a firefox symlink to /usr/bin/firejail:

$ sudo ln -s /usr/bin/firejail /usr/local/bin/firefox

Verify $PATH:

$ which -a firefox
/usr/local/bin/firefox
/usr/bin/firefox

Starting firefox in this moment automatically invokes โ€œfirejail /usr/bin/firefoxโ€.

This works for clicking on desktop environment icons, menus, etc. Use firejail --tree to verify the program is sandboxed ๐ŸŽ€

$ firejail --tree
1189:netblue:firejail /usr/bin/firefox
  1190:netblue:firejail /usr/bin/firefox
    1220:netblue:/bin/sh -c "/usr/lib/firefox/firefox"
      1221:netblue:/usr/lib/firefox/firefox

We provide a tool that automates all this integration โ€” please see firecfg(1) for more details, bestie ๐Ÿซถ


๐Ÿ” FILE GLOBBING

Globbing is the operation that expands a wildcard pattern into the list of pathnames matching the pattern. This pattern is matched at firejail start, and is NOT UPDATED at runtime. So like, files that match a blacklist but were created after firejail started will still be accessible within the jail. The matching is defined by:

  • ? matches any character
  • * matches any string
  • [ denotes a range of characters

The globbing feature is implemented using the glibc glob command. For more info on the wildcard syntax see man 7 glob.

The following command line options are supported: --blacklist, --private-bin, --noexec, --read-only, --read-write, --tmpfs, and --whitelist.

Examples:

$ firejail --private-bin=sh,bash,python*
$ firejail --blacklist=~/dir[1234]
$ firejail --read-only=~/dir[1-4]

โœจ FILE TRANSFER โœจ

Okay bestie, this whole section is about peeking inside a sandbox's filesystem container and moving files back and forth between the container and the host. It's giving "window shopping but for your own sandbox" ๐Ÿ’…

  • --cat=name|pid filename โ€” writes the content of a container file to standard out. The container gets picked by name or PID. And ooh, cute detail: if standard out is a terminal, all ASCII control characters except new line and horizontal tab get replaced. So no weird escape-code chaos on your screen ๐Ÿซถ
  • --get=name|pid filename โ€” grabs the container file and stores it on the host in the current working directory. Container is specified by name or PID.
  • --ls=name|pid dir_or_filename โ€” lists container files. Container is specified by name or PID.
  • --put=name|pid src-filename dest-filename โ€” puts src-filename into the sandbox container. Container is specified by name or PID.

๐ŸŒธ Examples โœจ

$ firejail --name=mybrowser --private /usr/bin/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

$ firejail --get=mybrowser ~/Downloads/x11-x305.png

$ firejail --put=mybrowser x11-x305.png ~/Downloads/x11-x305.png

$ firejail --cat=mybrowser ~/.bashrc

๐Ÿฆ‹ LANDLOCK ๐Ÿฆ‹

โš ๏ธ Warning, and I mean it: Landlock support in firejail is considered experimental and unstable. The contents of landlock-common.inc are likely to change, and the feature is still being expanded upon in the Linux kernel. Also note that its functionality overlaps with existing firejail features, such as the blacklist, read-only and read-write commands. Its filesystem access rules can currently only restrict direct access to paths; it is not able to make only select paths appear in the sandbox such as with the whitelist and private-etc commands (see also unveil(2) on OpenBSD). Lastly, note that depending on the Linux kernel version, Landlock may not protect all of the relevant syscalls (see the kernel's Landlock documentation for details). Therefore, it is recommended to treat Landlock as an extra layer of protection, to be used together with other firejail features (rather than as a bulletproof mechanism by itself). No cap, it's a bonus layer, not the whole outfit ๐Ÿ’€

So here's the lore: Landlock is a Linux security module first introduced in version 5.13 of the Linux kernel. It allows unprivileged processes to restrict their access to the filesystem. Once imposed, these restrictions can never be removed, and all child processes created by a Landlock-restricted process inherit these restrictions. Firejail supports Landlock as an additional sandboxing feature. It can be used to ensure that a sandboxed application can only access files and directories that it was explicitly allowed to access. Firejail supports populating the ruleset with both a basic set of rules (see landlock-common.inc) and with a custom set of rules. Slay ๐Ÿ‘‘

๐Ÿ’œ Important notes ๐Ÿ’œ

  • Currently only Landlock ABI version 1 is supported.
  • If lsm= is used in the kernel command line, it should contain landlock (such as lsm=apparmor,landlock), or else it will be disabled.
  • A process can install a Landlock ruleset only if it has either CAP_SYS_ADMIN in its effective capability set, or the "No New Privileges" restriction enabled. Because of this, enabling the Landlock feature will also cause Firejail to enable the "No New Privileges" restriction, regardless of the profile or the --nonewprivs command line option.
  • Access to the /etc directory is automatically allowed. To override this, use the --writable-etc command line option. You can also use the --private-etc option to restrict access to the /etc directory.

To enable Landlock self-restriction on top of your current Firejail security features, pass --landlock.enforce flag to the Firejail command line. Without it, the other Landlock commands have no effect โ€” like, zero, they're just standing there being decorative ๐Ÿ™ˆ Example:

$ firejail --landlock.enforce --landlock.fs.read=/media /usr/bin/mc

To disable Landlock self-restriction, use --ignore=landlock.enforce.


๐Ÿ‘€ MONITORING ๐Ÿ‘€

Option --list prints a list of all sandboxes. The format for each process entry is as follows:

PID:USER:Sandbox Name:Command

Option --tree prints the tree of processes running in the sandbox. The format for each process entry is as follows:

PID:USER:Sandbox Name:Command

Option --top is similar to the UNIX top command, however it applies only to sandboxes.

Option --netstats prints network statistics for active sandboxes installing new network namespaces.

Listed below are the available fields (columns) in alphabetical order for --top and --netstats options:

๐ŸŽ€ The columns ๐ŸŽ€

Command : Command used to start the sandbox.

CPU% : CPU usage, the sandbox share of the elapsed CPU time since the last screen update

PID : Unique process ID for the task controlling the sandbox.

Prcs : Number of processes running in sandbox, including the controlling process.

RES : Resident Memory Size (KiB), sandbox non-swapped physical memory. It is a sum of the RES values for all processes running in the sandbox.

RX(KB/s) : Network receive speed.

Sandbox Name : The name of the sandbox, if any.

SHR : Shared Memory Size (KiB), it reflects memory shared with other processes. It is a sum of the SHR values for all processes running in the sandbox, including the controlling process.

TX(KB/s) : Network transmit speed.

Uptime : Sandbox running time in hours:minutes:seconds format.

USER : The owner of the sandbox.


๐ŸŽ€ NAME VALIDATION ๐ŸŽ€

For simplicity, the same name validation is used for multiple options. Rules, and yes there are rules babe:

The name must be 1-253 characters long. The name can only contain ASCII letters, digits and the special characters -._ (that is, the name cannot contain spaces or control characters). The name cannot contain only digits. The first and last characters must be an ASCII letter or digit and the name may contain special characters in the middle. So mybrowser? iconic. 12345? not it. _nope_? also not it ๐Ÿ˜ญ


๐ŸŒˆ GLOBAL CONFIG FILE ๐ŸŒˆ

firejail.config is the global configuration file, and resides in /etc/firejail directory. Most major Firejail features can be enabled or disabled. Uncomment the line and switch the yes/no flag. Examples:

# restricted-network no : Enable or disable restricted network support, default disabled. If enabled, Firejail grants access to --interface, --net=ethXXX and --netfilter features only to root user. Regular users are only allowed --net=none.

Note: When restricted-network is disabled on a multiuser system, Firejail allows the user to bypass the firewall installed by the system administrator. Some distributions such as Debian and Ubuntu ship with restricted-network yes in the configuration file. So like, heads up ๐Ÿ‘€

# browser-disable-u2f yes : Disable U2F in browsers, default enabled.

Note: Universal Two-Factor (U2F) devices are used as a password store for online accounts. These devices usually come in a form of a USB key.

# browser-allow-drm no : Allow DRM execution in browsers, default disabled.

# force-nonewprivs no : Force use of nonewprivs on all programs, default disabled.

Note: nonewprivs is a Linux kernel feature that prevents programs from rising privileges. It is also a strong mitigation against exploits in Firejail. However, some programs like chromium, wireshark, or even ping might not work.

# seccomp-error-action EPERM : Seccomp error action, kill, log or errno (EPERM, ENOSYS etc). By default seccomp prevents the program from running the syscall and returns an error.

Note: Change EPERM to KILL if you want the program to exit immediately.

๐Ÿ”ฅ EXAMPLES ๐Ÿ”ฅ

firejail

Sandbox a regular shell session.

firejail /usr/bin/firefox

Start Mozilla Firefox.

firejail --debug /usr/bin/firefox

Debug Firefox sandbox.

firejail --private /usr/bin/firefox

Start Firefox with a new, empty home directory.

firejail --net=none /usr/bin/vlc

Start VLC in an unconnected network namespace.

firejail --net=eth0 /usr/bin/firefox

Start Firefox in a new network namespace. An IP address is assigned automatically.

firejail --net=br0 --ip=10.10.20.5 --net=br1 --net=br2

Start a shell session in a new network namespace and connect it to br0, br1, and br2 host bridge devices. IP addresses are assigned automatically for the interfaces connected to br1 and br2.

firejail --list

List all sandboxed processes.


โญ LICENSE โญ

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Homepage: https://firejail.wordpress.com


๐Ÿซถ SEE ALSO ๐Ÿซถ

firemon(1), firecfg(1), firejail-profile(5), firejail-login(5), firejail-users(5), jailcheck(1)

https://github.com/netblue30/firejail/wiki, https://github.com/netblue30/firejail


okay that's the whole page bestie, you're officially a firejail scholar ๐ŸŽ“โœจ go forth and sandbox responsibly ๐Ÿ’– This lil beauty is 0.9.82.2, dated Nov 2026, and it answers to the name FIREJAIL(1) โ€” periodt ๐Ÿฆ‹๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from