Firejail: Difference between revisions
imported>Onny Add usage examples |
|||
(26 intermediate revisions by 5 users not shown) | |||
Line 3: | Line 3: | ||
== Installation == | == Installation == | ||
Add following line to your system configuration to install Firejail globally | Add the following line to your system configuration to install and enable Firejail globally | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
programs.firejail.enable = true; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 21: | Line 21: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
firejail --profile=$(nix --extra-experimental-features nix-command --extra-experimental-features flakes eval -f '<nixpkgs>' --raw 'firejail')/etc/firejail/firefox.profile firefox | firejail --profile=$(nix --extra-experimental-features nix-command --extra-experimental-features flakes eval -f '<nixpkgs>' --raw 'firejail')/etc/firejail/firefox.profile firefox | ||
</syntaxhighlight> | |||
== Configuration == | |||
You can also use the Firejail NixOS module for a persistent usage of specific applications which should always run in Firejail. The following example wraps the browser Librewolf and the messenger Signal in a Firejail environment. The usual program path to <code>librewolf</code> and <code>signal-desktop</code> will be overwritten by the Firejail-wrapper. | |||
<syntaxhighlight lang="nix"> | |||
programs.firejail = { | |||
enable = true; | |||
wrappedBinaries = { | |||
librewolf = { | |||
executable = "${pkgs.librewolf}/bin/librewolf"; | |||
profile = "${pkgs.firejail}/etc/firejail/librewolf.profile"; | |||
extraArgs = [ | |||
# Required for U2F USB stick | |||
"--ignore=private-dev" | |||
# Enforce dark mode | |||
"--env=GTK_THEME=Adwaita:dark" | |||
# Enable system notifications | |||
"--dbus-user.talk=org.freedesktop.Notifications" | |||
]; | |||
}; | |||
signal-desktop = { | |||
# Enable tray icon otherwise Signal window might be hidden | |||
executable = "${pkgs.signal-desktop}/bin/signal-desktop --use-tray-icon"; | |||
profile = "${pkgs.firejail}/etc/firejail/signal-desktop.profile"; | |||
extraArgs = [ | |||
# Enforce dark mode | |||
"--env=GTK_THEME=Adwaita:dark" | |||
# Enable Wayland mode | |||
"--env=NIXOS_OZONE_WL=1" | |||
# Allow tray icon (should be upstreamed into signal-desktop.profile) | |||
"--dbus-user.talk=org.kde.StatusNotifierWatcher" | |||
]; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
== Tips & tricks == | |||
=== Torify application traffic === | |||
The following example configuration creates a virtual network bridge which can be used in Firejail as an isolated network namespace. All traffic originating from this interface will be routed through a local [[Tor]] service which will therefore anonymize your internet traffic. | |||
<syntaxhighlight lang="nix"> | |||
services.tor = { | |||
enable = true; | |||
openFirewall = true; | |||
settings = { | |||
TransPort = [ 9040 ]; | |||
DNSPort = 5353; | |||
VirtualAddrNetworkIPv4 = "172.30.0.0/16"; | |||
}; | |||
}; | |||
networking = { | |||
useNetworkd = true; | |||
bridges."tornet".interfaces = []; | |||
nftables = { | |||
enable = true; | |||
ruleset = '' | |||
table ip nat { | |||
chain PREROUTING { | |||
type nat hook prerouting priority dstnat; policy accept; | |||
iifname "tornet" meta l4proto tcp dnat to 127.0.0.1:9040 | |||
iifname "tornet" udp dport 53 dnat to 127.0.0.1:5353 | |||
} | |||
} | |||
''; | |||
}; | |||
nat = { | |||
internalInterfaces = [ "tornet " ]; | |||
forwardPorts = [ | |||
{ | |||
destination = "127.0.0.1:5353"; | |||
proto = "udp"; | |||
sourcePort = 53; | |||
} | |||
]; | |||
}; | |||
firewall = { | |||
enable = true; | |||
interfaces.tornet = { | |||
allowedTCPPorts = [ 9040 ]; | |||
allowedUDPPorts = [ 5353 ]; | |||
}; | |||
}; | |||
}; | |||
systemd.network = { | |||
enable = true; | |||
networks.tornet = { | |||
matchConfig.Name = "tornet"; | |||
DHCP = "no"; | |||
networkConfig = { | |||
ConfigureWithoutCarrier = true; | |||
Address = "10.100.100.1/24"; | |||
}; | |||
linkConfig.ActivationPolicy = "always-up"; | |||
}; | |||
}; | |||
boot.kernel.sysctl = { | |||
"net.ipv4.conf.tornet.route_localnet" = 1; | |||
}; | |||
</syntaxhighlight> | |||
Run your preferred application inside the isolated Tor network | |||
<syntaxhighlight lang="bash"> | |||
firejail --net=tornet --dns=46.182.19.48 --profile=$(nix --extra-experimental-features nix-command --extra-experimental-features flakes eval -f '<nixpkgs>' --raw 'firejail')/etc/firejail/firefox.profile firefox | |||
</syntaxhighlight> | |||
You can use a custom DNS server if you don't want to use the one of your system. In this example, it's a server by the German privacy NGO [https://digitalcourage.de/support/zensurfreier-dns-server Digitalcourage]. | |||
Using [[Systemd/networkd/dispatcher]] it is possible to restart the Tor daemon every time network reconnect is performaed. This avoids having to wait for Tor network timeouts and reastablishes a new connection faster. | |||
For a detailed explanation on this setup refer the [https://www.void.gr/kargig/blog/2016/12/12/firejail-with-tor-howto original guide]. Please note that this is a experimental setup which doesn't guarantee anonymity or security in any circumstances. | |||
=== Add Desktop Icons to Firejailed Apps === | |||
I wanted to use Firejail to lock down Google Chrome. It worked well, however, I wanted a pretty icon for the application. | |||
There are probably better ways to do this, but I accomplished it using Home Manager to symlink Chrome's actual icon set into your local icon directory. | |||
<syntaxhighlight lang="nix"> | |||
## Firejail Config | |||
programs.firejail = { | |||
enable = true; | |||
wrappedBinaries = { | |||
google-chrome-stable = { | |||
executable = "${pkgs.google-chrome}/bin/google-chrome-stable"; | |||
profile = "${pkgs.firejail}/etc/firejail/google-chrome.profile"; | |||
desktop = "${pkgs.google-chrome}/share/applications/google-chrome.desktop"; | |||
}; | |||
}; | |||
}; | |||
## Home Manager Config | |||
home.file.".local/share/icons/hicolor/16x16/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/16x16/apps/google-chrome.png"; | |||
home.file.".local/share/icons/hicolor/24x24/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/24x24/apps/google-chrome.png"; | |||
home.file.".local/share/icons/hicolor/32x32/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/32x32/apps/google-chrome.png"; | |||
home.file.".local/share/icons/hicolor/48x48/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/48x48/apps/google-chrome.png"; | |||
home.file.".local/share/icons/hicolor/64x64/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/64x64/apps/google-chrome.png"; | |||
home.file.".local/share/icons/hicolor/128x128/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/128x128/apps/google-chrome.png"; | |||
home.file.".local/share/icons/hicolor/256x256/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/256x256/apps/google-chrome.png"; | |||
</syntaxhighlight> | |||
Another way to do this is to create a package with the firejailed application icons. This way, it can be done without home manager, and thus have the icons for all users. | |||
<syntaxhighlight lang="nix"> | |||
environment.systemPackages = [ | |||
( | |||
let | |||
packages = with pkgs; [ | |||
electrum | |||
firefox | |||
mpv | |||
gajim | |||
tor-browser | |||
vlc | |||
]; | |||
in | |||
pkgs.runCommand "firejail-icons" | |||
{ | |||
preferLocalBuild = true; | |||
allowSubstitutes = false; | |||
meta.priority = -1; | |||
} | |||
'' | |||
mkdir -p "$out/share/icons" | |||
${lib.concatLines (map (pkg: '' | |||
tar -C "${pkg}" -c share/icons -h --mode 0755 -f - | tar -C "$out" -xf - | |||
'') packages)} | |||
find "$out/" -type f -print0 | xargs -0 chmod 0444 | |||
find "$out/" -type d -print0 | xargs -0 chmod 0555 | |||
'' | |||
) | |||
]; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
[[Category:Applications]] | [[Category:Applications]] | ||
[[Category:Security]] | [[Category:Security]] |
Latest revision as of 21:01, 25 June 2024
Firejail is an easy to use SUID sandbox program that reduces the risk of security breaches by restricting the running environment of untrusted applications using Linux namespaces, seccomp-bpf and Linux capabilities.
Installation
Add the following line to your system configuration to install and enable Firejail globally
programs.firejail.enable = true;
Usage
To start an application in a sandboxed enviroment use Firejail like this
firejail bash
For a graphical application like Firefox web browser, it is recommended to also use a profile
firejail --profile=$(nix --extra-experimental-features nix-command --extra-experimental-features flakes eval -f '<nixpkgs>' --raw 'firejail')/etc/firejail/firefox.profile firefox
Configuration
You can also use the Firejail NixOS module for a persistent usage of specific applications which should always run in Firejail. The following example wraps the browser Librewolf and the messenger Signal in a Firejail environment. The usual program path to librewolf
and signal-desktop
will be overwritten by the Firejail-wrapper.
programs.firejail = {
enable = true;
wrappedBinaries = {
librewolf = {
executable = "${pkgs.librewolf}/bin/librewolf";
profile = "${pkgs.firejail}/etc/firejail/librewolf.profile";
extraArgs = [
# Required for U2F USB stick
"--ignore=private-dev"
# Enforce dark mode
"--env=GTK_THEME=Adwaita:dark"
# Enable system notifications
"--dbus-user.talk=org.freedesktop.Notifications"
];
};
signal-desktop = {
# Enable tray icon otherwise Signal window might be hidden
executable = "${pkgs.signal-desktop}/bin/signal-desktop --use-tray-icon";
profile = "${pkgs.firejail}/etc/firejail/signal-desktop.profile";
extraArgs = [
# Enforce dark mode
"--env=GTK_THEME=Adwaita:dark"
# Enable Wayland mode
"--env=NIXOS_OZONE_WL=1"
# Allow tray icon (should be upstreamed into signal-desktop.profile)
"--dbus-user.talk=org.kde.StatusNotifierWatcher"
];
};
};
};
Tips & tricks
Torify application traffic
The following example configuration creates a virtual network bridge which can be used in Firejail as an isolated network namespace. All traffic originating from this interface will be routed through a local Tor service which will therefore anonymize your internet traffic.
services.tor = {
enable = true;
openFirewall = true;
settings = {
TransPort = [ 9040 ];
DNSPort = 5353;
VirtualAddrNetworkIPv4 = "172.30.0.0/16";
};
};
networking = {
useNetworkd = true;
bridges."tornet".interfaces = [];
nftables = {
enable = true;
ruleset = ''
table ip nat {
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
iifname "tornet" meta l4proto tcp dnat to 127.0.0.1:9040
iifname "tornet" udp dport 53 dnat to 127.0.0.1:5353
}
}
'';
};
nat = {
internalInterfaces = [ "tornet " ];
forwardPorts = [
{
destination = "127.0.0.1:5353";
proto = "udp";
sourcePort = 53;
}
];
};
firewall = {
enable = true;
interfaces.tornet = {
allowedTCPPorts = [ 9040 ];
allowedUDPPorts = [ 5353 ];
};
};
};
systemd.network = {
enable = true;
networks.tornet = {
matchConfig.Name = "tornet";
DHCP = "no";
networkConfig = {
ConfigureWithoutCarrier = true;
Address = "10.100.100.1/24";
};
linkConfig.ActivationPolicy = "always-up";
};
};
boot.kernel.sysctl = {
"net.ipv4.conf.tornet.route_localnet" = 1;
};
Run your preferred application inside the isolated Tor network
firejail --net=tornet --dns=46.182.19.48 --profile=$(nix --extra-experimental-features nix-command --extra-experimental-features flakes eval -f '<nixpkgs>' --raw 'firejail')/etc/firejail/firefox.profile firefox
You can use a custom DNS server if you don't want to use the one of your system. In this example, it's a server by the German privacy NGO Digitalcourage.
Using Systemd/networkd/dispatcher it is possible to restart the Tor daemon every time network reconnect is performaed. This avoids having to wait for Tor network timeouts and reastablishes a new connection faster.
For a detailed explanation on this setup refer the original guide. Please note that this is a experimental setup which doesn't guarantee anonymity or security in any circumstances.
Add Desktop Icons to Firejailed Apps
I wanted to use Firejail to lock down Google Chrome. It worked well, however, I wanted a pretty icon for the application.
There are probably better ways to do this, but I accomplished it using Home Manager to symlink Chrome's actual icon set into your local icon directory.
## Firejail Config
programs.firejail = {
enable = true;
wrappedBinaries = {
google-chrome-stable = {
executable = "${pkgs.google-chrome}/bin/google-chrome-stable";
profile = "${pkgs.firejail}/etc/firejail/google-chrome.profile";
desktop = "${pkgs.google-chrome}/share/applications/google-chrome.desktop";
};
};
};
## Home Manager Config
home.file.".local/share/icons/hicolor/16x16/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/16x16/apps/google-chrome.png";
home.file.".local/share/icons/hicolor/24x24/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/24x24/apps/google-chrome.png";
home.file.".local/share/icons/hicolor/32x32/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/32x32/apps/google-chrome.png";
home.file.".local/share/icons/hicolor/48x48/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/48x48/apps/google-chrome.png";
home.file.".local/share/icons/hicolor/64x64/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/64x64/apps/google-chrome.png";
home.file.".local/share/icons/hicolor/128x128/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/128x128/apps/google-chrome.png";
home.file.".local/share/icons/hicolor/256x256/apps/google-chrome.png".source = "${pkgs.google-chrome}/share/icons/hicolor/256x256/apps/google-chrome.png";
Another way to do this is to create a package with the firejailed application icons. This way, it can be done without home manager, and thus have the icons for all users.
environment.systemPackages = [
(
let
packages = with pkgs; [
electrum
firefox
mpv
gajim
tor-browser
vlc
];
in
pkgs.runCommand "firejail-icons"
{
preferLocalBuild = true;
allowSubstitutes = false;
meta.priority = -1;
}
''
mkdir -p "$out/share/icons"
${lib.concatLines (map (pkg: ''
tar -C "${pkg}" -c share/icons -h --mode 0755 -f - | tar -C "$out" -xf -
'') packages)}
find "$out/" -type f -print0 | xargs -0 chmod 0444
find "$out/" -type d -print0 | xargs -0 chmod 0555
''
)
];