Firefox

Disable search in address 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

Run as user

Instruction number

myuser

*

These settings disable search engine queries in the search bar.

  1. open about:config in the address bar

  2. Set these values to false

    keyword.enabled                     false
    browser.fixup.alternate.enabled     false
    

Profiles

Vedi anche

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

Run as user

Instruction number

root

1-4

myuser

5-8

You can handle multiple Firefox profiles in separate sandboxes with this script

  1. install the dependencies

    apt-get install firejail yad python3-yaml
    
  2. install fpyutils. See reference

  3. install python-yad

    pip3 install --user yad
    
  4. 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
    
  5. 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 isinstance(configuration['message']['start'], bool)
    150       and isinstance(configuration['message']['end'], bool)):
    151        ok = True
    152    else:
    153        ok = False
    154    if (ok
    155       and 'profile_list_type' in configuration
    156       and isinstance(configuration['profile_list_type'], str)
    157       and configuration['profile_list_type'] in ['entry', 'list']):
    158        ok = True
    159    else:
    160        ok = False
    161    if (ok
    162       and 'profiles' in configuration
    163       and isinstance(configuration['profiles'], dict)):
    164
    165        # At least one profile must be present.
    166        if len(configuration['profiles']) <= 0:
    167            ok = False
    168        else:
    169            profiles = configuration['profiles']
    170            profiles_keys = list(profiles.keys())
    171
    172            i = 0
    173            while ok and i < len(profiles_keys):
    174                prf = profiles[profiles_keys[i]]
    175
    176                if not isinstance(prf, dict):
    177                    ok = ok & False
    178
    179                if (ok
    180                   and 'firefox' in prf
    181                   and 'firejail' in prf
    182                   and 'profile_name' in prf['firefox']
    183                   and isinstance(prf['firefox']['profile_name'], str)
    184                   and 'options' in prf['firefox']
    185                   and isinstance(prf['firefox']['options'], list)
    186                   and 'enabled' in prf['firejail']
    187                   and isinstance(prf['firejail']['enabled'], bool)
    188                   and 'options' in prf['firejail']
    189                   and isinstance(prf['firejail']['options'], list)):
    190                    ok = ok & True
    191
    192                    j = 0
    193                    options = prf['firefox']['options']
    194                    while ok and j < len(options):
    195                        if isinstance(options[j], str):
    196                            ok = ok & True
    197                        else:
    198                            ok = ok & False
    199                        j += 1
    200
    201                    j = 0
    202                    options = prf['firejail']['options']
    203                    while ok and j < len(options):
    204                        if isinstance(options[j], str):
    205                            ok = ok & True
    206                        else:
    207                            ok = ok & False
    208                        j += 1
    209                else:
    210                    ok = ok & False
    211
    212                i += 1
    213    else:
    214        ok = False
    215
    216    return ok
    217
    218
    219if __name__ == '__main__':
    220    def main():
    221        yad = YAD()
    222
    223        try:
    224            configuration_file = shlex.quote(sys.argv[1])
    225            config = yaml.load(open(configuration_file, 'r'), Loader=yaml.SafeLoader)
    226            if not check_configuration_structure(config):
    227                raise ValueError
    228            if not binaries_exist(config['binaries']):
    229                raise FileNotFoundError
    230        except (IndexError, FileNotFoundError, yaml.parser.ParserError, ValueError, FileNotFoundError) as e:
    231            show_configuration_error(str(e), yad)
    232            sys.exit(1)
    233
    234        profile = ask_profile_question(list(config['profiles'].keys()), config['profile_list_type'], yad)
    235        command = build_command(config['profiles'][profile], config['binaries']['firefox'], config['binaries']['firejail'])
    236
    237        pid = os.fork()
    238        if pid > 0:
    239            if config['message']['start']:
    240                show_profile_message(profile, config['profiles'][profile]['firejail']['enabled'], True, yad)
    241        else:
    242            r = fpyutils.shell.execute_command_live_output(command)
    243            if r != 0:
    244                show_configuration_error('error: returned ' + str(r), yad)
    245            elif config['message']['end']:
    246                show_profile_message(profile, config['profiles'][profile]['firejail']['enabled'], False, yad)
    247        try:
    248            pid, status = os.waitpid(pid, 0)
    249        except ChildProcessError as e:
    250            print(e)
    251            sys.exit(1)
    252
    253    main()
    
  6. 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 and quitting messages for each profile.
     24message:
     25    start: true
     26    end: true
     27
     28# Possible values: 'entry', 'list'
     29profile_list_type: 'list'
     30
     31profiles:
     32    personal:
     33        firefox:
     34            profile_name: 'personal'
     35            options: []
     36        firejail:
     37            enabled: true
     38            options:
     39            - '--apparmor'
     40
     41            # IMPORTANT: this directory must exist prior running the scipt.
     42            - '--private=/home/myuser/firefox-firejail/personal'
     43
     44            - '--private-cache'
     45            - '--private-dev'
     46            - '--private-tmp'
     47            - '--disable-mnt'
     48    internal:
     49        firefox:
     50            profile_name: 'internal'
     51            options: []
     52        firejail:
     53            enabled: true
     54            options:
     55            - '--apparmor'
     56            - '--private-cache'
     57            - '--private-dev'
     58            - '--private-tmp'
     59            - '--disable-mnt'
     60    isolated:
     61        firefox:
     62            profile_name: 'isolated'
     63            options: []
     64        firejail:
     65            enabled: true
     66            options:
     67            - '--whitelist=~/my_network_files'
     68            - '--nosound'
     69            - '--net=none'
     70    work:
     71        firefox:
     72            profile_name: 'work'
     73            options: []
     74        firejail:
     75            enabled: true
     76            options:
     77            - '--apparmor'
     78            - '--private=/home/myuser/firefox-firejail/work'
     79            - '--private-cache'
     80            - '--private-dev'
     81            - '--private-tmp'
     82            - '--disable-mnt'
     83    shopping:
     84        firefox:
     85            profile_name: 'shopping'
     86            options: []
     87        firejail:
     88            enabled: true
     89            options:
     90            - '--apparmor'
     91            - '--nosound'
     92            - '--dns=8.8.8.8'
     93            - '--private=/home/myuser/firefox-firejail/shopping'
     94            - '--private-cache'
     95            - '--private-dev'
     96            - '--private-tmp'
     97            - '--disable-mnt'
     98    cryptocurrencies:
     99        firefox:
    100            profile_name: 'cryptocurrencies'
    101            options: []
    102        firejail:
    103            enabled: true
    104            options:
    105            - '--apparmor'
    106            - '--nosound'
    107            - '--dns=8.8.8.8'
    108            - '--private=/home/myuser/firefox-firejail/cryptocurrencies'
    109            - '--private-cache'
    110            - '--private-dev'
    111            - '--private-tmp'
    112            - '--disable-mnt'
    
  7. if your configuration uses private home directories through the --private= option you must create them before running the script

  8. 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. install the uBlock Origin extension

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

  3. add this content

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

    where my.domain.org is the whitelisted domain

Footnotes

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