Firefox

Disable search in address bar

These settings disable search engine queries in the search bar.

Vedi anche

  • I want to disable search in the address bar and browser.urlbar.unifiedcomplete is not an option anymore | Firefox Support Forum | Mozilla Support 1

  1. open Firefox

  2. open about:config in the address bar

  3. Set 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

Vedi anche

  • A collection of scripts I have written and/or adapted that I currently use on my systems as automated tasks 2

  • GitHub - netblue30/firejail: Linux namespaces and seccomp-bpf sandbox 3

  1. 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 <https://github.com/netblue30/firejail#debian>` this version for Debian.
    
  2. install fpyutils. See reference

  3. 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
    
  4. create the script

    /home/jobs/scripts/myuser/firefox_profile_runner.py
      1#!/usr/bin/env python3
      2#
      3# firefox_profile_runner.py
      4#
      5# Copyright (C) 2021-2022 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com)
      6#
      7# This program is free software: you can redistribute it and/or modify
      8# it under the terms of the GNU General Public License as published by
      9# the Free Software Foundation, either version 3 of the License, or
     10# (at your option) any later version.
     11#
     12# This program is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
     19#
     20#
     21r"""A menu to run different Firefox profiles in sandboxes."""
     22
     23import copy
     24import os
     25import shlex
     26import shutil
     27import sys
     28
     29import fpyutils
     30import yaml
     31from yad import YAD
     32
     33
     34def ask_profile_question(profile_names: list, type: str, yad) -> str:
     35    prf: str
     36    profiles: list = copy.deepcopy(profile_names)
     37    profiles.sort()
     38    data: list = profiles
     39    text: str = 'Select a profile'
     40    window_title: str = 'Firefox profile selection'
     41    width: int = 640
     42    height: int = 480
     43    profile: str = None
     44
     45    if type == 'entry':
     46        profile = yad.Entry(
     47            label=text,
     48            title=window_title,
     49            width=width,
     50            height=height,
     51            fixed=True,
     52            center=True,
     53            quoted=True,
     54            no_markup=True,
     55            use_completion='true',
     56            data=data,
     57        )
     58    elif type == 'list':
     59        data = [[x] for x in data]
     60        profile = yad.List(
     61            text=text,
     62            title=window_title,
     63            width=width,
     64            height=height,
     65            fixed=True,
     66            center=True,
     67            colnames=[("profile", "TEXT")],
     68            quoted=True,
     69            no_markup=True,
     70            data=data,
     71        )
     72
     73    if profile is None:
     74        sys.exit(0)
     75    else:
     76        if type == 'entry':
     77            prf = profile
     78        else:
     79            prf = profile[0]
     80
     81    return prf
     82
     83
     84def build_command(profile: dict, firefox_executable: str, firejail_executable: str) -> str:
     85    command = str()
     86
     87    firefox_command = firefox_executable + ' -P ' + shlex.quote(profile['firefox']['profile_name'])
     88    for o in profile['firefox']['options']:
     89        firefox_command += ' ' + shlex.quote(o)
     90
     91    if profile['firejail']['enabled']:
     92
     93        firejail_command = firejail_executable
     94
     95        for o in profile['firejail']['options']:
     96            firejail_command += ' ' + shlex.quote(o)
     97
     98        command = firejail_command + ' ' + firefox_command
     99
    100    else:
    101        command += firefox_command
    102
    103    return command
    104
    105
    106def show_configuration_error(error: str, yad):
    107    message = 'Check configuration or arguments'
    108    yad.execute(args=['--title="Configuration error"', '--width=640', '--height=480', '--text="' + message + '\n\n' + repr(error) + '"', '--button="Ok:0"', '--no-markup'])
    109
    110
    111def show_profile_message(profile: str, sandbox_enabled: bool, load: bool, yad):
    112    sandbox_status = 'disabled'
    113    if sandbox_enabled:
    114        sandbox_status = 'enabled'
    115
    116    if load:
    117        message = 'Loading profile **' + profile + '** with sandbox **' + sandbox_status + '**. Please wait...'
    118        title = 'Loading Firefox profile'
    119    else:
    120        message = 'Quit profile **' + profile + '** with sandbox **' + sandbox_status + '**.'
    121        title = 'Exited from Firefox profile'
    122
    123    yad.execute(args=['--title="' + title + '"', '--width=640', '--height=480', '--text="' + message + '"', '--timeout=5', '--timeout-indicator=bottom', '--button="Ok:0"', '--no-markup'])
    124
    125
    126def binaries_exist(binaries: dict) -> bool:
    127    binaries_present = False
    128    if (shutil.which(binaries['firefox']) is not None
    129       and shutil.which(binaries['firejail']) is not None):
    130        binaries_present = True
    131
    132    return binaries_present
    133
    134
    135def check_configuration_structure(configuration: dict) -> bool:
    136    ok = True
    137    if ('binaries' in configuration
    138       and 'firefox' in configuration['binaries']
    139       and 'firejail' in configuration['binaries']
    140       and isinstance(configuration['binaries']['firefox'], str)
    141       and isinstance(configuration['binaries']['firejail'], str)):
    142        ok = True
    143    else:
    144        ok = False
    145    if (ok
    146       and 'message' in configuration
    147       and 'start' in configuration['message']
    148       and 'end' in configuration['message']
    149       and 'errors' in configuration['message']
    150       and isinstance(configuration['message']['start'], bool)
    151       and isinstance(configuration['message']['end'], bool)
    152       and isinstance(configuration['message']['errors'], bool)):
    153        ok = True
    154    else:
    155        ok = False
    156    if (ok
    157       and 'profile_list_type' in configuration
    158       and isinstance(configuration['profile_list_type'], str)
    159       and configuration['profile_list_type'] in ['entry', 'list']):
    160        ok = True
    161    else:
    162        ok = False
    163    if (ok
    164       and 'profiles' in configuration
    165       and isinstance(configuration['profiles'], dict)):
    166
    167        # At least one profile must be present.
    168        if len(configuration['profiles']) <= 0:
    169            ok = False
    170        else:
    171            profiles = configuration['profiles']
    172            profiles_keys = list(profiles.keys())
    173
    174            i = 0
    175            while ok and i < len(profiles_keys):
    176                prf = profiles[profiles_keys[i]]
    177
    178                if not isinstance(prf, dict):
    179                    ok = ok & False
    180
    181                if (ok
    182                   and 'firefox' in prf
    183                   and 'firejail' in prf
    184                   and 'profile_name' in prf['firefox']
    185                   and isinstance(prf['firefox']['profile_name'], str)
    186                   and 'options' in prf['firefox']
    187                   and isinstance(prf['firefox']['options'], list)
    188                   and 'enabled' in prf['firejail']
    189                   and isinstance(prf['firejail']['enabled'], bool)
    190                   and 'options' in prf['firejail']
    191                   and isinstance(prf['firejail']['options'], list)):
    192                    ok = ok & True
    193
    194                    j = 0
    195                    options = prf['firefox']['options']
    196                    while ok and j < len(options):
    197                        if isinstance(options[j], str):
    198                            ok = ok & True
    199                        else:
    200                            ok = ok & False
    201                        j += 1
    202
    203                    j = 0
    204                    options = prf['firejail']['options']
    205                    while ok and j < len(options):
    206                        if isinstance(options[j], str):
    207                            ok = ok & True
    208                        else:
    209                            ok = ok & False
    210                        j += 1
    211                else:
    212                    ok = ok & False
    213
    214                i += 1
    215    else:
    216        ok = False
    217
    218    return ok
    219
    220
    221if __name__ == '__main__':
    222    def main():
    223        yad = YAD()
    224
    225        try:
    226            configuration_file = shlex.quote(sys.argv[1])
    227            config = yaml.load(open(configuration_file, 'r'), Loader=yaml.SafeLoader)
    228            if not check_configuration_structure(config):
    229                raise ValueError
    230            if not binaries_exist(config['binaries']):
    231                raise FileNotFoundError
    232        except (IndexError, FileNotFoundError, yaml.parser.ParserError, ValueError, FileNotFoundError) as e:
    233            if config['message']['errors']:
    234                show_configuration_error(str(e), yad)
    235            sys.exit(1)
    236
    237        profile = ask_profile_question(list(config['profiles'].keys()), config['profile_list_type'], yad)
    238        command = build_command(config['profiles'][profile], config['binaries']['firefox'], config['binaries']['firejail'])
    239
    240        pid = os.fork()
    241        if pid > 0:
    242            if config['message']['start']:
    243                show_profile_message(profile, config['profiles'][profile]['firejail']['enabled'], True, yad)
    244        else:
    245            r = fpyutils.shell.execute_command_live_output(command)
    246            if config['message']['errors'] and r != 0:
    247                show_configuration_error('error: returned ' + str(r), yad)
    248            elif config['message']['end']:
    249                show_profile_message(profile, config['profiles'][profile]['firejail']['enabled'], False, yad)
    250        try:
    251            pid, status = os.waitpid(pid, 0)
    252        except ChildProcessError as e:
    253            print(e)
    254            sys.exit(1)
    255
    256    main()
    
  5. import the configuration file

    /home/jobs/scripts/myuser/firefox_profile_runner.yaml
      1#
      2# firefox_profile_runner.yaml
      3#
      4# Copyright (C) 2021-2022 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com)
      5#
      6# This program is free software: you can redistribute it and/or modify
      7# it under the terms of the GNU General Public License as published by
      8# the Free Software Foundation, either version 3 of the License, or
      9# (at your option) any later version.
     10#
     11# This program is distributed in the hope that it will be useful,
     12# but WITHOUT ANY WARRANTY; without even the implied warranty of
     13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14# GNU General Public License for more details.
     15#
     16# You should have received a copy of the GNU General Public License
     17# along with this program.  If not, see <https://www.gnu.org/licenses/>.
     18
     19binaries:
     20    firefox: '/usr/bin/firefox-esr'
     21    firejail: '/usr/bin/firejail'
     22
     23# Show starting, quitting and error messages for each profile.
     24message:
     25    start: true
     26    end: true
     27    errors: true
     28
     29# Possible values: 'entry', 'list'
     30profile_list_type: 'list'
     31
     32profiles:
     33    personal:
     34        firefox:
     35            profile_name: 'personal'
     36            options: []
     37        firejail:
     38            enabled: true
     39            options:
     40            - '--apparmor'
     41
     42            # IMPORTANT: this directory must exist prior running the scipt.
     43            - '--private=/home/myuser/firefox-firejail/personal'
     44
     45            - '--private-cache'
     46            - '--private-dev'
     47            - '--private-tmp'
     48            - '--disable-mnt'
     49    internal:
     50        firefox:
     51            profile_name: 'internal'
     52            options: []
     53        firejail:
     54            enabled: true
     55            options:
     56            - '--apparmor'
     57            - '--private-cache'
     58            - '--private-dev'
     59            - '--private-tmp'
     60            - '--disable-mnt'
     61    isolated:
     62        firefox:
     63            profile_name: 'isolated'
     64            options: []
     65        firejail:
     66            enabled: true
     67            options:
     68            - '--whitelist=~/my_network_files'
     69            - '--nosound'
     70            - '--net=none'
     71    work:
     72        firefox:
     73            profile_name: 'work'
     74            options: []
     75        firejail:
     76            enabled: true
     77            options:
     78            - '--apparmor'
     79            - '--private=/home/myuser/firefox-firejail/work'
     80            - '--private-cache'
     81            - '--private-dev'
     82            - '--private-tmp'
     83            - '--disable-mnt'
     84    shopping:
     85        firefox:
     86            profile_name: 'shopping'
     87            options: []
     88        firejail:
     89            enabled: true
     90            options:
     91            - '--apparmor'
     92            - '--nosound'
     93            - '--dns=8.8.8.8'
     94            - '--private=/home/myuser/firefox-firejail/shopping'
     95            - '--private-cache'
     96            - '--private-dev'
     97            - '--private-tmp'
     98            - '--disable-mnt'
     99    cryptocurrencies:
    100        firefox:
    101            profile_name: 'cryptocurrencies'
    102            options: []
    103        firejail:
    104            enabled: true
    105            options:
    106            - '--apparmor'
    107            - '--nosound'
    108            - '--dns=8.8.8.8'
    109            - '--private=/home/myuser/firefox-firejail/cryptocurrencies'
    110            - '--private-cache'
    111            - '--private-dev'
    112            - '--private-tmp'
    113            - '--disable-mnt'
    
  6. if your configuration uses private home directories through the --private= option you must create them before running the script

  7. go back to your regular desktop user

    exit
    
  8. install python-yad

    pip3 install --user yad
    
  9. run the script

    pushd /home/jobs/scripts/by-user/myuser && ./firefox_profile_runner.py ./firefox_profile_runner.yaml && popd
    

    Nota

    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:

  1. open Firefox

  2. install the uBlock Origin extension

  3. go into uBlock Origin’s settings and open the My Filters section

  4. add this content

    https://*.*
    http://*.*
    @@||my.domain.org
    

    where my.domain.org is the whitelisted domain

Footnotes

Disable all images

Set permissions.default.images = 2 in about:config

1

https://support.mozilla.org/en-US/questions/1213978 unknown license

2

https://software.franco.net.eu.org/frnmst/automated-tasks GNU GPLv3+, copyright (c) 2019-2022, Franco Masotti

3

https://github.com/netblue30/firejail GNU GPL v2.0, Copyright (C) 2014-2022, Firejail Authors