Skip to content

Instantly share code, notes, and snippets.

@mbbx6spp
Last active August 2, 2022 15:30
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbbx6spp/bb7bdc9b91f5a5cfa349282c1dc911fb to your computer and use it in GitHub Desktop.
Save mbbx6spp/bb7bdc9b91f5a5cfa349282c1dc911fb to your computer and use it in GitHub Desktop.
A gist of the commands, metadata file (.desktop), and script I wrote to delegate web URLs to the correct sandboxed web browser inside of the appropriate user profile in Linux. Should work in all distros.

Delegating web requests in Linux to correct browser profile

A few months ago I set this up and here is the write up on it since yesterday, while talking to a fellow Linux user, they found it intriguing.

My requirements

Any URL I click in Slack, Signal desktop app, or launch via terminal actions should launch into the correct sandboxed, user-profile web browser instance (in precedence order):

  • https://github.com/<workorg>.* should open in the work Firefox profile
  • https://github.com/<sideproj>.* should open in the sideproj Firefox profile
  • https://github.com/.* (all others) should open in the personal Firefox profile
  • All exclusively work related URLs should open in the work Firefox profile (gathered URLs)
  • https://twitter.com/.* should open in personal Firefox profile
  • All staging environment URLs should open in the qa Firefox profile (which doesn’t have AdBlock Plus installed)

Approach

  • Set BROWSER environment variable to an executable script in my PATH named web.
  • Create a web.desktop file in ~/.local/share/applications/ (see web.desktop in this snippet for the example)
  • Set this desktop file as the default web browser for GUI applications to know what to use to delegate URLs to open browsers, running: xdg-settings set default-web-browser web.desktop
  • Write ~/bin/web script that inspects the URL given by the forwarding application and decides which browser profile to open a tab in. Using firejail to sandbox firefox and opera.

Setting up a FireFox profiles

  • firefox -CreateProfile myemployer
  • firefox -CreateProfile sideproj
  • firefox -CreateProfile personal

Then downloaded the Firefox extensions I wanted to install:

rm -rf ~/.cache/web/addons
mkdir -p ~/.cache/web/addons
wget -O ~/.cache/web/addons/lastpass.xpi https://lastpass.com/lastpassffx/xpi.php
firefox -P myemployer ~/.cache/web/addons/lastpass.xpi

The last command launches the browser in GUI mode because installing an addon requires a prompt.

  • TODO research how to automate without the GUI prompt and use the headless command-line option.

Setting up a firejail profile

  • mkdir -p ~/.config/firejail
  • Find your profile directory paths, like so: readlink -f ~/.mozilla/firefox/*.myemployer
  • Find your cache directory paths, like so: readlink -f ~/.cache/mozilla/firefox/*.myemployer

These paths will be put into your firejail profile below:

Create ~/.config/firejail/web-myemployer.profile with the basic structure like so:

include firefox.local
include global.local

# You have to find the generated profile directory to put in here
noblacklist ${HOME}/.cache/mozilla/firefox/ydwbdjcx.myemployer
noblacklist ${HOME}/mozilla/firefox/ydwbdjcx.myemployer

whitelist ${HOME}/.cache/mozilla/firefox/ydwbdjcx.myemployer
whitelist ${HOME}/mozilla/firefox/ydwbdjcx.myemployer

Similarly for the other profiles needed.

NixOS tidbits

To make firejail work on NixOS (or any other Linux distro) you need setup firejail with a setuid wrapper. Here is how you do that in NixOS specifically (other distro users are on your own):

In your system’s configuration.nix you will need to add something like this:

security.wrappers.firejail = {
  source = "${pkgs.firejail}/bin/firejail";
};
#!/usr/bin/env bash
function getProfile() {
ls -lrc "~/.mozilla/firefox" \
| grep "$1" \
| tail -1
| awk '{ print $9 }'
}
function launchWebProfile() {
firejail --profile "${HOME}/.config/firejail/$1.profile" firefox --profile $(getProfile "$1") --no-remote $2
}
function main() {
# log all URLs visited via the app launch stuff
echo $* >> ~/.web_history
case $1 in
https://github.com/myemployer*)
launchWebProfile myemployer $1
;;
https://myemployer.*)
launchWebProfile myemployer $1
;;
https://app.datadoghq.com/*)
launchWebProfile myemployer $1
;;
https://app.clubhouse.io*)
launchWebProfile myemployer $1
;;
https://meet.google.com/*)
launchWebProfile myemployer $1
;;
https://zoom.us*)
launchWebProfile myemployer $1
;;
https://github.com/sideproj*)
launchWebProfile sideproj $1
;;
*)
launchWebProfile personal $1
;;
esac
}
set -euo pipefail
main $*
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Name[en_US]=Web
GenericName=Web browsing delegator
Exec=/home/spotter/bin/web
Terminal=false
Type=Application
Categories=
MimeType=x-scheme-handler/unknown;x-scheme-handler/about;x-scheme-handler/https;x-scheme-handler/http;text/html;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment