Install and isolate apps using Firejail on Slackware

       2036 words, 10 minutes

Since I started using other Desktop OS than OpenBSD, I’m obsessed with limiting filesystem resources access from applications; especially Web browsers. This already applied to FreeBSD Web browsers here and there . This now has to be applied to Linux.

Context choices

I had to make technology choices when looking at “can I get rid of Microsoft Windows in my current $WORK environment while having colleagues not noticing it”. They already have a mixed Windows / mac OS environment that raises compatibility issues; so I was pretty confident I could blame the software from time to time 😈

I’ve used Microsoft Edge only for a week on Windows and had a few mic and screen sharing issues. So I wanted to be able to run the Microsoft Teams native apps. After trying Edge on FreeBSD and not being able to login to the MS account, I went for a try on Linux.

I had a look at Linux Mint, Debian, Fedora and OpenSUSE. So I also read about AppArmor and SELinux. Fedora and OpenSUSE implement SELinux but it felt very complicated to me after a day or two trying to limit resources access. AppArmor on Debian and Linux Mint also looked quite complicated. None of those went with a simple way to just run an App isolated; or maybe I just missed it.

I was told about Firejail on the Fediverse and really liked it. There are still way too includes in the conf to my likings but it looks like OpenBSD pledge/unveil. Not sure why, but the Linux distros I tried either didn’t have it available or packaged it in a way there were missing profiles. The cleanest and better installation I got was on Slackware Linux. But, there is no doubt I’m heavily biased here.

Slackware Linux comes with Firefox and SeaMonkey. But since the Mozilla Terms of Use drama, I must admit I trust them nearly to none anymore. I’d rather use Librewolf these days. Neither Librewolf, nor Edge come preinstalled in Slackware. They have to be manually installed.

Installing and running applications

I’ll concentrate on Web browsers here, but those notes apply to any kind of application.

Linux binary applications

Slackware comes with Firefox and Thunderbird. Still I removed the packages and installed the binary versions provided by Mozilla. This is because, this way, I can install those somewhere not in $PATH and this will prevent running the application without Firejail.

Browse to Mozilla’s website and look for the “Download options and other languages”. This allows to download the application for the “Linux 64-bit” platform using the language you need.

The installation is then as simple as getting the archive, exploding it and running the software.

# mkdir -p /opt/mozilla
# cd /opt/mozilla

# wget -O firefox-128.9.0esr.tar.bz2 \
  'https://download.mozilla.org/?product=firefox-esr-latest-ssl&os=linux64&lang=fr'
# wget -O thunderbird-128.9.2esr.tar.bz2 \
  'https://download.mozilla.org/?product=thunderbird-128.9.2esr-SSL&os=linux64&lang=fr'

# tar xpf firefox-128.9.0esr.tar.bz2
# tar xpf thunderbird-128.9.2esr.tar.bz2

$ /opt/mozilla/firefox/firefox
$ /opt/mozilla/thunderbird/thunderbird

Enabling Firejail and creating a Desktop file to launch the applications is described later on.

AppImage

Another way of running “third-party” applications on Linux is to use AppImage. There are other formats like Flatpak and Snap. But after reading a few “what’s the difference” documentation, I decided to go for AppImage. And, it is also the format used by the SlackBuilds project.

Using AppImage is even simpler than Linux binaries. Just download the AppImage, make it executable and run it.

# mkdir /opt
# cd /opt

# wget -O LibreWolf-137.0.2-1.x86_64.AppImage \
  https://gitlab.com/api/v4/projects/24386000/packages/generic/librewolf/137.0.2-1/LibreWolf.x86_64.AppImage
# chmod +x LibreWolf-137.0.2-1.x86_64.AppImage

$ /opt/LibreWolf-137.0.2-1.x86_64.AppImage

Enabling Firejail and creating a Desktop file to launch the applications is described later on.

Debian packages

In the Microsoft case, only Debian and Fedora packages are provided. There is a SlackBuilds script for Microsoft Edge and Teams. But for the same reason I didn’t want to use the packaged Firefox, I did install the Edge DEB package manually.

# mkdir /tmp/msedge
# cd /tmp/msedge

# wget https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/microsoft-edge-stable_131.0.2903.99-1_amd64.deb
# ar xv microsoft-edge-stable_131.0.2903.99-1_amd64.deb
# tar xpf data.tar.xz

# tar cpf - opt | tar xpf - -C /

# cd -
# rm -rf /tmp/msedge

$ /opt/microsoft/msedge/msedge

If you came here for the Microsoft stuff, installing and running the native Teams client is done the same way. The only difficult thing is to find the latest Teams package as it seems Microsoft have stopped it in favour of a complete PWA. In case you still want to use it, I found a version on Archive.org .

Enabling Firejail and creating a Desktop file to launch the applications is described later on.

Installing and using Firejail

When it comes to installing third-party software on Slackware Linux, I generally use sbpkg . There are also other software that deals with SlackBuilds but this one is my preferred one.

$ sudo sbpkg -i firejail

If you don’t use sbpkg, the simple Slackbuilds is enough and does not require extra dependencies.

# wget https://slackbuilds.org/slackbuilds/15.0/system/firejail.tar.gz
# tar xzf firejail.tar.gz
# cd firejail

# wget https://github.com/netblue30/firejail/releases/download/0.9.74/firejail-0.9.74.tar.xz
# bash firejail.SlackBuild

# installpkg /tmp/firejail-0.9.74-x86_64-1_SBo.tgz

The expected standard way of using Firejail is to enable the profiles for detected applications and allowed users.

$ sudo firecfg

firecfg version 0.9.74
                                               
Removing all firejail symlinks:
                                               
Looking for config files in /etc/firejail/firecfg.d/*.conf
No matches for glob pattern /etc/firejail/firecfg.d/*.conf                                     
Configuring symlinks in /usr/local/bin
Parsing /etc/firejail/firecfg.config
   Xephyr created
   akonadi_control created
   akregator created
   alpine created
(...)
   xmms created
   xpdf created
   zathura created
   zlib-flate created

Adding user joel to Firejail access database in /etc/firejail/firejail.users
Creating /etc/firejail/firejail.users

Configuring symlinks in /usr/local/bin based on local firejail config directory

Fixing desktop files in /home/joel/.local/share/applications
   org.kde.spectacle.desktop created
(...)
   ca.desrt.dconf-editor.desktop created

From the console, launching /usr/bin/mousepad will run it “as usual”. Launching /usr/local/bin/mousepad will run it via Firejail. Editing /etc/firejail/mousepad.local or /etc/firejail/globals.local can prevent software from accessing more data or allow them to access data that are blocked by default.

Linux binary applications and Debian packages

No matter how the application was installed, using it via Firejail is done the same way. Simply pass the application path as an argument. If Firejail already has a profile for it, it should recognise the application and apply the relevant profile.

As an example, the previously installed Firefox can be run this way:

# firejail /opt/mozilla/firefox/firefox
Reading profile /etc/firejail/firefox.profile
Reading profile /etc/firejail/firefox-common.profile
Reading profile /etc/firejail/disable-common.inc
Reading profile /etc/firejail/disable-devel.inc
Reading profile /etc/firejail/disable-exec.inc
Reading profile /etc/firejail/disable-interpreters.inc
Reading profile /etc/firejail/disable-proc.inc
Reading profile /etc/firejail/disable-programs.inc
Reading profile /etc/firejail/whitelist-common.inc
Reading profile /etc/firejail/whitelist-run-common.inc
Reading profile /etc/firejail/whitelist-runuser-common.inc
Reading profile /etc/firejail/whitelist-usr-share-common.inc
Reading profile /etc/firejail/whitelist-var-common.inc
firejail version 0.9.74

Seccomp list in: !chroot, check list: @default-keep, prelist: unknown,
Warning: /usr/bin/xdg-dbus-proxy was not found, downgrading dbus-user policy to allow.
To enable DBus filtering, install the xdg-dbus-proxy program.
Ignoring "dbus-user.own org.mozilla.*" and 2 other dbus-user filter rules.
Parent pid 32243, child pid 32244
Warning: An abstract unix socket for session D-BUS might still be available. Use --net or remove unix from --protocol set.
Private /etc installed in 55.42 ms
Base filesystem installed in 140.73 ms
Seccomp list in: !chroot, check list: @default-keep, prelist: unknown,
Child process initialized in 251.70 ms
(...)

Browsing the home folder from Firefox reveals that it cannot access the .ssh or Documents folder by default. If needed, this could be changed by editing the /etc/firejail/firefox.local configuration file. As I don’t use Firefox that much any more, I kept the default profile settings.

AppImage

Running an AppImage via Firejail can be as simple as:

$ firejail --profile=librewolf --appimage /opt/LibreWolf-137.0.2-1.x86_64.AppImage
Reading profile /etc/firejail/librewolf.profile
Reading profile /etc/firejail/firefox-common.profile
Reading profile /etc/firejail/disable-common.inc
Reading profile /etc/firejail/disable-devel.inc
Reading profile /etc/firejail/disable-exec.inc
Reading profile /etc/firejail/disable-interpreters.inc
Reading profile /etc/firejail/disable-proc.inc
Reading profile /etc/firejail/disable-programs.inc
Reading profile /etc/firejail/whitelist-common.inc
Reading profile /etc/firejail/whitelist-run-common.inc
Reading profile /etc/firejail/whitelist-runuser-common.inc
Reading profile /etc/firejail/whitelist-usr-share-common.inc
Reading profile /etc/firejail/whitelist-var-common.inc
firejail version 0.9.74
(...)
Parent is shutting down, bye...
AppImage detached

For even more isolation, one can use extra parameters.

–private
Mount new /root and /home/user directories in temporary filesystems.
All modifications are discarded when the sandbox is closed.
–x11
Sandbox the application using Xpra, Xephyr, Xvfb or Xorg security extension.
The sandbox will prevent screenshot and keylogger applications started inside the sandbox from acessing clients running outside the sandbox.

$ firejail --profile=librewolf --appimage --private --x11 /opt/LibreWolf-137.0.2-1.x86_64.AppImage

Custom profile

If the default profiles don’t suit your needs, for example you need access to some extra directories or want to be even more restrictive, your can write your own profiles. A detailed documentation is available online .

My own Librewolf profile looks like this:

# cat ~/.config/firejail/librewolf.profile 
noroot
blacklist ~/.config
blacklist ~/.ssh
blacklist ~/Bureau
blacklist ~/Documents
blacklist ~/Images
blacklist ~/ModĂšles
blacklist ~/Musique
blacklist ~/Vidéos

whitelist ~/.icons
read-only ~/.icons
whitelist ~/.local/share/fonts
read-only ~/.local/share/fonts
whitelist ~/.themes
read-only ~/.themes
whitelist ~/Public
read-only ~/Public

whitelist ~/.librewolf
whitelist ~/Téléchargements

I could have included the default librewolf profile but I wanted to be sure only hard-coded defaults and my settings were used. I run the exercice of flattering down all the included directives and considered it was too big to be auditable.

Without other extra parameters, Firejail confirms that it runs the program using my custom profile only.

$ firejail --profile=librewolf --appimage /opt/LibreWolf-137.0.2-1.x86_64.AppImage
Reading profile /home/joel/.config/firejail/librewolf.profile
firejail version 0.9.74
(...)
Parent is shutting down, bye...
AppImage detached

This profiles allows access to standard text and video browsing. I never tried to access the webcam or the microphone using this profile. This may be where the standard profiles would be useful.

Private directory

There are software that I really want to run isolated from the system. The securest way would be to not run it from a computer where the sensible data is but… usability vs security…

I run Microsoft Edge this way:

# ln -s /var/lib/dbus/machine-id /etc/machine-id
$ firejail --profile=microsoft-edge \
           --private=~/jails/msedge \
           --private-cache --noroot \
           /opt/microsoft/msedge/msedge

This allows standard text and video browsing. It also allows using the whole Office365 Web applications; including Teams with sound, mic and screen sharing.

The private directory is accessible from within MS Edge and from any other application on my laptop. I can copy/move downloaded file from Edge to some other directory. I can also copy/move files to this directory so that Edge can access them.

Desktop integration

The commands being quite long, I wrote starting scripts.
Those scripts are available from my $PATH and can be started easily.

$ cat ~/scripts/firefox
#!/bin/sh
JAIL_HOME="$HOME/jails/firefox"
[ ! -d "$JAIL_HOME" ] && mkdir -p "$JAIL_HOME"
exec firejail --profile=firefox        \
              --private="$JAIL_HOME"   \                                             
              --private-cache --noroot \                                             
              /opt/mozilla/firefox/firefox "$@"      
#EOF
$ cat ~/scripts/librewolf
#!/bin/sh
exec firejail --profile=librewolf \
              --appimage          \
              /opt/LibreWolf-137.0.2-1.x86_64.AppImage "$@"
#EOF
$ cat ~/scripts/msedge
#!/bin/sh
JAIL_HOME="$HOME/jails/msedge"
[ ! -d "$JAIL_HOME" ] && mkdir -p "$JAIL_HOME"
[ ! -e /etc/machine-id ] && {
    echo "Microsoft Edge requires a machine-id. As root, run:"
    echo "# ln -s /var/lib/dbus/machine-id /etc/machine-id"
    exit 1
}
exec firejail --profile=microsoft-edge \
              --private="$JAIL_HOME"   \
              --private-cache --noroot \
              /opt/microsoft/msedge/msedge "$@"
#EOF

The scripts can be integrated in desktop files so that applications can be used from the XDG-compatible menus and/or the file managers.

$ cat ~/.local/share/applications/firejail-firefox.desktop
[Desktop Entry]
Version=1.0
Name=Firejail Firefox
Name[fr]=Firejail Firefox
Comment=Browse the World Wide Web
Comment[fr]=Parcourir Internet
GenericName=Web Browser
GenericName[fr]=Navigateur Web
Keywords=Internet;WWW;Browser;Web;Explorer
Keywords[fr]=Internet;WWW;Browser;Web;Explorer;Fureteur;Surfer;Navigateur
Exec=/home/joel/scripts/firefox %U
Terminal=false
Type=Application
Icon=firefox-developer-icon
Categories=GNOME;GTK;Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;x-scheme-handler/chrome;video/webm;application/x-xpinstall;
StartupNotify=true
Actions=NewWindow;NewPrivateWindow;
Path=

[Desktop Action NewWindow]
Name=Open a New Window
Name[fr]=Ouvrir une nouvelle fenĂȘtre
Exec=/home/joel/scripts/firefox -new-window

[Desktop Action NewPrivateWindow]
Name=Open a New Private Window
Name[fr]=Ouvrir une nouvelle fenĂȘtre de navigation privĂ©e
Exec=/home/joel/scripts/firefox -private-window
$ cat ~/.local/share/applications/firejail-librewolf.desktop
[Desktop Entry]
Version=1.0
Name=Firejail Librewolf
Name[fr]=Firejail Librewolf
Comment=Browse the World Wide Web
Comment[fr]=Parcourir le Web
GenericName=Web Browser
GenericName[fr]=Navigateur Web
Keywords=Internet;WWW;Browser;Web;Explorer
Keywords[fr]=Internet;WWW;Browser;Web;Explorer;Fureteur;Surfer;Navigateur
Exec=/home/joel/scripts/librewolf %U
Terminal=false
Type=Application
Icon=librewolf
Categories=GNOME;GTK;Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;x-scheme-handler/chrome;video/webm;application/x-xpinstall;
StartupNotify=true
Actions=NewWindow;NewPrivateWindow;
Path=

[Desktop Action NewWindow]
Name=Open a New Window
Name[fr]=Ouvrir une nouvelle fenĂȘtre
Exec=/home/joel/scripts/librewolf -new-window

[Desktop Action NewPrivateWindow]
Name=Open a New Private Window
Name[fr]=Ouvrir une nouvelle fenĂȘtre de navigation privĂ©e
Exec=/home/joel/scripts/librewolf -private-window
$ cat ~/.local/share/applications/firejail-msedge.desktop
[Desktop Entry]
Version=1.0
Name=Firejail Microsoft Edge
GenericName=Web Browser
GenericName[fr]=Navigateur Web
Comment=Access the Internet
Comment[fr]=Accéder à Internet
Exec=/home/joel/scripts/msedge %U
StartupNotify=true
Terminal=false
Icon=microsoft-edge
Type=Application
Categories=Network;WebBrowser;
MimeType=application/pdf;application/rdf+xml;application/rss+xml;application/xhtml+xml;application/xhtml_xml;application/xml;image/gif;image/jpeg;image/png;image/webp;text/html;text/xml;x-scheme-handler/http;x-scheme-handler/https;
Actions=new-window;new-private-window;

[Desktop Action new-window]
Name=New Window
Name[fr]=Nouvelle fenĂȘtre
Exec=/home/joel/scripts/msedge --new-window

[Desktop Action new-private-window]
Name=New InPrivate Window
Name[fr]=Nouvelle fenĂȘtre InPrivate
Exec=/home/joel/scripts/msedge --inprivate

From now on, I run my Web browsers and a few other apps as if I was using pledge/unveil. Having no binary in $PATH and no system Desktop files is the key for not accidentally launching applications that are not locked in jail.

I was told about landrun on the Fediverse, by the author of the SlackBuilds, but I never tried it (yet). Maybe you should do and blog about it, so that I don’t have to ;-)