Firefox#
Disable search in address bar#
These settings disable search engine queries in the search bar.
See also
I want to disable search in the address bar and browser.urlbar.unifiedcomplete is not an option anymore | Firefox Support Forum | Mozilla Support [1]
open Firefox
open
about:config
in the address barSet these values to false
keyword.enabled false browser.fixup.alternate.enabled false
Profiles#
You can handle multiple Firefox profiles in separate sandboxes with this script
See also
install the dependencies
apt-get install firejail/bullseye-backports yad python3-yaml firefox-esr
Note
You need to enable the backports before installing firejail. The upstream repository recommends this version for Debian.
install fpyutils. See reference
create the jobs directories. See reference
mkdir -p /home/jobs/scripts/by-user/myuser chown -R myuser:myuser /home/jobs/scripts/by-user/myuser chmod 700 -R /home/jobs/scripts/by-user/myuser usermod -aG jobs myuser
create the
script
#!/usr/bin/env python3 # # firefox_profile_runner.py # # Copyright (C) 2021-2022 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com) # # 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 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # r"""A menu to run different Firefox profiles in sandboxes.""" import copy import os import shlex import shutil import sys import fpyutils import yaml from yad import YAD def ask_profile_question(profile_names: list, type: str, yad) -> str: prf: str profiles: list = copy.deepcopy(profile_names) profiles.sort() data: list = profiles text: str = 'Select a profile' window_title: str = 'Firefox profile selection' width: int = 640 height: int = 480 profile: str = None if type == 'entry': profile = yad.Entry( label=text, title=window_title, width=width, height=height, fixed=True, center=True, quoted=True, no_markup=True, use_completion='true', data=data, ) elif type == 'list': data = [[x] for x in data] profile = yad.List( text=text, title=window_title, width=width, height=height, fixed=True, center=True, colnames=[('profile', 'TEXT')], quoted=True, no_markup=True, data=data, ) if profile is None: sys.exit(0) else: if type == 'entry': prf = profile else: prf = profile[0] return prf def build_command(profile: dict, firefox_executable: str, firejail_executable: str) -> str: command = '' firefox_command = firefox_executable + ' -P ' + shlex.quote( profile['firefox']['profile_name']) for o in profile['firefox']['options']: firefox_command += ' ' + shlex.quote(o) if profile['firejail']['enabled']: firejail_command = firejail_executable for o in profile['firejail']['options']: firejail_command += ' ' + shlex.quote(o) command = firejail_command + ' ' + firefox_command else: command += firefox_command return command def show_configuration_error(error: str, yad): message = 'Check configuration or arguments' yad.execute(args=[ '--title="Configuration error"', '--width=640', '--height=480', '--text="' + message + '\n\n' + repr(error) + '"', '--button="Ok:0"', '--no-markup' ]) def show_profile_message(profile: str, sandbox_enabled: bool, load: bool, yad): sandbox_status = 'disabled' if sandbox_enabled: sandbox_status = 'enabled' if load: message = 'Loading profile **' + profile + '** with sandbox **' + sandbox_status + '**. Please wait...' title = 'Loading Firefox profile' else: message = 'Quit profile **' + profile + '** with sandbox **' + sandbox_status + '**.' title = 'Exited from Firefox profile' yad.execute(args=[ '--title="' + title + '"', '--width=640', '--height=480', '--text="' + message + '"', '--timeout=5', '--timeout-indicator=bottom', '--button="Ok:0"', '--no-markup' ]) def binaries_exist(binaries: dict) -> bool: binaries_present = False if (shutil.which(binaries['firefox']) is not None and shutil.which(binaries['firejail']) is not None): binaries_present = True return binaries_present def check_configuration_structure(configuration: dict) -> bool: ok = True if ('binaries' in configuration and 'firefox' in configuration['binaries'] and 'firejail' in configuration['binaries'] and isinstance(configuration['binaries']['firefox'], str) and isinstance(configuration['binaries']['firejail'], str)): ok = True else: ok = False if (ok and 'message' in configuration and 'start' in configuration['message'] and 'end' in configuration['message'] and 'errors' in configuration['message'] and isinstance(configuration['message']['start'], bool) and isinstance(configuration['message']['end'], bool) and isinstance(configuration['message']['errors'], bool)): ok = True else: ok = False if (ok and 'profile_list_type' in configuration and isinstance(configuration['profile_list_type'], str) and configuration['profile_list_type'] in ['entry', 'list']): ok = True else: ok = False if (ok and 'profiles' in configuration and isinstance(configuration['profiles'], dict)): # At least one profile must be present. if len(configuration['profiles']) <= 0: ok = False else: profiles = configuration['profiles'] profiles_keys = list(profiles.keys()) i = 0 while ok and i < len(profiles_keys): prf = profiles[profiles_keys[i]] if not isinstance(prf, dict): ok = ok & False if (ok and 'firefox' in prf and 'firejail' in prf and 'profile_name' in prf['firefox'] and isinstance(prf['firefox']['profile_name'], str) and 'options' in prf['firefox'] and isinstance(prf['firefox']['options'], list) and 'enabled' in prf['firejail'] and isinstance(prf['firejail']['enabled'], bool) and 'options' in prf['firejail'] and isinstance(prf['firejail']['options'], list)): ok = ok & True j = 0 options = prf['firefox']['options'] while ok and j < len(options): if isinstance(options[j], str): ok = ok & True else: ok = ok & False j += 1 j = 0 options = prf['firejail']['options'] while ok and j < len(options): if isinstance(options[j], str): ok = ok & True else: ok = ok & False j += 1 else: ok = ok & False i += 1 else: ok = False return ok if __name__ == '__main__': def main(): yad = YAD() try: configuration_file = shlex.quote(sys.argv[1]) try: config = yaml.load(open(configuration_file), Loader=yaml.SafeLoader) except yaml.parser.ParserError as e: show_configuration_error(str(e), yad) sys.exit(1) if not check_configuration_structure(config): raise ValueError if not binaries_exist(config['binaries']): raise FileNotFoundError except (IndexError, FileNotFoundError, ValueError) as e: if config['message']['errors']: show_configuration_error(str(e), yad) sys.exit(1) profile = ask_profile_question(list(config['profiles'].keys()), config['profile_list_type'], yad) command = build_command(config['profiles'][profile], config['binaries']['firefox'], config['binaries']['firejail']) pid = os.fork() if pid > 0: if config['message']['start']: show_profile_message( profile, config['profiles'][profile]['firejail']['enabled'], True, yad) else: r = fpyutils.shell.execute_command_live_output(command) if config['message']['errors'] and r != 0: show_configuration_error('error: returned ' + str(r), yad) elif config['message']['end']: show_profile_message( profile, config['profiles'][profile]['firejail']['enabled'], False, yad) try: pid, status = os.waitpid(pid, 0) except ChildProcessError as e: print(e) sys.exit(1) main()
import the
configuration file
# # firefox_profile_runner.yaml # # Copyright (C) 2021-2022 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com) # # 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 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. binaries: firefox: '/usr/bin/firefox-esr' firejail: '/usr/bin/firejail' # Show starting, quitting and error messages for each profile. message: start: true end: true errors: true # Possible values: 'entry', 'list' profile_list_type: 'list' profiles: personal: firefox: profile_name: 'personal' options: [] firejail: enabled: true options: - '--apparmor' # IMPORTANT: this directory must exist prior running the scipt. - '--private=/home/myuser/firefox-firejail/personal' - '--private-cache' - '--private-dev' - '--private-tmp' - '--disable-mnt' internal: firefox: profile_name: 'internal' options: [] firejail: enabled: true options: - '--apparmor' - '--private-cache' - '--private-dev' - '--private-tmp' - '--disable-mnt' isolated: firefox: profile_name: 'isolated' options: [] firejail: enabled: true options: - '--whitelist=~/my_network_files' - '--nosound' - '--net=none' work: firefox: profile_name: 'work' options: [] firejail: enabled: true options: - '--apparmor' - '--private=/home/myuser/firefox-firejail/work' - '--private-cache' - '--private-dev' - '--private-tmp' - '--disable-mnt' shopping: firefox: profile_name: 'shopping' options: [] firejail: enabled: true options: - '--apparmor' - '--nosound' - '--dns=8.8.8.8' - '--private=/home/myuser/firefox-firejail/shopping' - '--private-cache' - '--private-dev' - '--private-tmp' - '--disable-mnt' cryptocurrencies: firefox: profile_name: 'cryptocurrencies' options: [] firejail: enabled: true options: - '--apparmor' - '--nosound' - '--dns=8.8.8.8' - '--private=/home/myuser/firefox-firejail/cryptocurrencies' - '--private-cache' - '--private-dev' - '--private-tmp' - '--disable-mnt'
if your configuration uses private home directories through the
--private=
option you must create them before running the scriptgo back to your regular desktop user
exit
install python-yad
pip3 install --user yad
run the script
pushd /home/jobs/scripts/by-user/myuser && ./firefox_profile_runner.py ./firefox_profile_runner.yaml && popd
Note
You can create, for example, a launcher on your desktop or a key combination to launch the script. This is what I use in my specrtwm configuration
program[firefox] = bash -c "pushd /home/jobs/scripts/by-user/myuser && ./firefox_profile_runner.py ./firefox_profile_runner.yaml 1>/dev/null 2>/dev/null &" 1/dev/null 2>/dev/null' bind[firefox] = MOD+i
Block all domains except one#
If you use Firefox profiles for different purposes you might need to block some domains. I use this for example for my Gitea Firefox profile: when Gitea renders a markdown file, and there are images hosted on external websites, you can block them like this:
open Firefox
install the uBlock Origin extension
go into uBlock Origin’s settings and open the
My Filters
sectionadd this content
https://*.* http://*.* @@||my.domain.org
where
my.domain.org
is the whitelisted domain
Disable all images#
Set permissions.default.images = 2
in about:config
Footnotes