浏览器调教指南 - Firefox 篇

前言

前几天写 文本编辑器的基础方程式 顺带更新了 我的 Windows 软件之道#推荐 部分内容,介绍使用 Flash 插件的现代方案以及浏览器的调教大纲,这篇文章会略微详细地讲讲这部分内容。

定义

这里的「浏览器」特指桌面端,移动端、TV、车机系统等等各凭本事,不予介绍。 同样,本文仅介绍主流浏览器(Statcounter 市场占有率数据高于 5%),即 Chrome/Chromium, MSEdge, Firefox ESR1

由于 Safari 就是 Apple 写着玩的,完全不考虑企业市场,「调教」也无从说起。 Opera 曾经使用 Presto 还能聊一聊,如今已经是 Blink (Chromium) 的形状就没什么意思。 Vivaldi, Brave, Arc, Yandex 之类的套壳就更没有讨论的必要,自行替换代入关键词即可。

大致方案已经记录在 我的 Windows 软件之道#推荐,这里不再赘述,直接上内容。 由于每个人的需求都不一样,我就不贴自己的定制化配置了。

考虑到全文长度,先分割出一篇 Firefox,后续再补 Chrome/Chromium 和 MSEdge。

Firefox ESR

为什么要特地指定 ESR,因为 policy-templatesSearchEngines 策略仅适用于 ESR,手动添加十几个常用引擎实在是麻烦= =而且虽然名字叫 Extended Support Release,其实根据 发行时间 ESR 大版本一年更新一次,并不至于像 Debian stable 的软件包那样普遍落后 2 年。

user.js

如果尝试定制过 Firefox,或多或少都会接触到 about:config 这个 URL,在这里可以调节成百上千个浏览器的细节,当然,每次重装都需要一个个手动调整费时费力,肯定有个自动化的工具。在 Firefox 中,这个工具就是 user.js。

详细的使用就不介绍了,本文的重点仅在方法论,关联阅读:

目前使用 arkenfox/user.js,第一次将大部分内容检查一遍之后,把自定义的部分写到 user-overrides.js 中,部署、更新、备份和清理失效配置都很方便。未来可能转换到 Betterfox,但万变不离其宗,原理都是一样的。

有多简单?下面是我目前的 user.js 更新流程:

  1. 查看 release note 里的 diffs
  2. (可选)手动增删 user-overrides.js 里的配置
  3. 在 profile 目录运行 updater.bat/updater.sh,随后运行 pref-cleaner.sh
  4. (可选)备份 user-overrides.js 配置到 backup 文件夹

2 和 4 都是可选的,甚至整个流程都可以通过脚本自动化,更新一遍半分钟都不到。 参考上文提到的发行时间,基本一个月一次,初始化之后一年只需要泡两杯泡面的时间, 即可保证 about:config 的完全定制化。

user.js 虽然好用,但 Mozilla 三天两头作妖,时不时偷偷在新版本给你推送点侵犯隐私的内容,比如 Firefox 128 就默认开启了 Privacy-Preserving Attribution(广告追踪相关测试),连 ESR 都不放过。当然这种无法提前预知的情况没什么办法,但对于更新修改默认设置的情况,可以通过 autoconfig 锁定/清空默认配置。上面 program-think 的那篇文章也有介绍,不再赘述。

CSS

除了 user.js,Firefox 还支持通过 CSS 定制 UI。 首先需要在 about:config 或者 user.js / autoconfig 中启用 toolkit.legacyUserProfileCustomizations.stylesheets

  • userChrome.css 用于定制 Firefox 自身,注意这里的 Chrome 一词起源其实比 Chrome 浏览器还要久远,先来后到也是人家先来的= =
  • userContent.css 用于定制浏览网站的界面,就和那些冠名各种「净化」、「清理」的用户脚本(UserScript,也叫 user.js,注意和上文配置 about:config 的同名文件进行区分)一样

同样,详细使用就不介绍了,自行阅读 无需任何插件或扩展,定制 Firefox 外观。 简单列几个参考资源:

  • UserChrome-Tweaks,多年没更新,有一部分至今仍可用
  • r/FirefoxCSS,Reddit 板块
  • Userstyles.org,像 Stylish 之类的插件用的就是这种,Firefox 直接就能定制,复制到 CSS 重启即可,少装一个插件
  • 上文提到的各种用户脚本,使用 CSS 就能少装几个脚本
  • uBlock Origin,这是我目前 CSS 的主要来源,虽然 ubo 更通用,但很多网站根本不会用 Chromium 打开,直接写进 CSS 未尝不可,还能简化 ubo 规则。像我 Firefox ubo 自定义的过滤规则只有寥寥 20+(当然,订阅规则有很多),真的是可有可无

Policy Templates

终于聊到 policy-templates,为什么不叫「策略模板」,因为人家只有英文网站连这都看不懂就别配置了。Firefox 这方面基本就是照抄 Chrome,不过配置项要比人家少得多。但你能通过设置配置的东西,policy-templates 基本都有涉及,不需要每次重装都点点点。

这东西的目标群体大多是企业用户,感觉付费支持的多,所以网上介绍的文章也不多,简单提几点,后文在 Chrome policy template 还会介绍。

Firefox 的 policy-templates 相比于 Chrome 有一点非常好,就是跨平台,一个 policies.json 可以通用,Linux 配置到 /etc/firefox/policies3,Windows 在 firefox.exe 同级目录创建 distribution 即可。

不像 Chrome,Linux 用 JSON,Windows 用注册表或者组策略 4,macOS 又用其他什么办法,不够通用,牵一发而动全身。

需要注意 policies.json 的 EOL 需要设置为 CRLF,哪怕在 GNU/Linux 也是一样= = 配置结果可以在 about:policies 查看,无报错即一切正常。 此外 JSON 不能写注释,这点比较坑,Chrome 是可以的。

示例

下面根据我的部分配置文件举几个🌰🌰🌰,介绍一下 policy-templates 的用法。

先来个简单的:

  • 由于我始终启用 HTTPS-only 模式,部分 HTTP 网站(虽然这里只是懒得配置 SSL 的内网 mDNS 设备)会弹警告,配置策略绕过,普通网站不写端口当然也可以
  • 禁止导入默认的 Mozilla 书签
  • 禁用搜索建议(就是在搜索框输入就会自动发送文本内容,然后返回结果),不影响在搜索引擎页面的搜索建议功能(二者不一样,你细品)
{
    "policies": {
        "HttpAllowlist": [
            "http://rpi.local:3000"
        ],
        "NoDefaultBookmarks": true,
        "SearchSuggestEnabled": false
    }
}

然后搞点复杂的,通过 ExtensionSettings 配置插件 5,一点说明:

  • 卸载自带的 DuckDuckGo
  • 强制安装 uBlock Origin,并且不能卸载不能禁用(可以在具体网站上停用)
  • 注意如果访问 add-ons for Firefox,会发现插件下载地址是带版本的 URL (e.g. https://addons.mozilla.org/firefox/downloads/file/4328681/ublock_origin-1.59.0.xpi),但其实可以用最新版本插件的直链 (https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi),具体的 URI 可以访问插件页面获取
  • 部分地区的商店不提供 uBlock Origin(比如谋智中国),可以使用 GitHub release 的 URL 安装(e.g. https://github.com/gorhill/uBlock/releases/download/1.59.0/uBlock0_1.59.0.firefox.signed.xpi),但是这样就是静态 URL,需要安装后手动更新,或者时不时更新 policies.json 中的版本,不推荐
  • 插件 ID 可以查看 about:support 页面的 Add-ons 信息,这里特地用 LocalCDN 举例,说明不一定都是正常的邮箱名,开发者可以自己配置,或者使用随机生成的 UUID
  • 从第三方安装插件也是可以的,这里是 Zotero Connector
{
    "policies": {
        "ExtensionSettings": {
            "ddg@search.mozilla.org": {
                "installation_mode": "blocked"
            },
            "uBlock0@raymondhill.net": {
                "install_url": "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi",
                "installation_mode": "force_installed"
            },
            "zotero@chnm.gmu.edu": {
                "install_url": "https://download.zotero.org/connector/firefox/release/Zotero_Connector-5.0.144.xpi",
                "installation_mode": "normal_installed"
            },
            "{b86e4813-687a-43e6-ab65-0bde4ab75758}": {
                "install_url": "https://addons.mozilla.org/firefox/downloads/latest/localcdn-fork-of-decentraleyes/latest.xpi",
                "installation_mode": "force_installed"
            }
        }
    }
}

接着来个亿点点复杂的,通过 SearchEngines 配置搜索引擎:

  • 前文已经提醒,本配置仅适用于 Firefox ESR
  • 移除自带的搜索引擎 6,配置默认搜索引擎为自定义的 DuckDuckGoLite
  • 对于大部分有搜索功能的网站(不说人话就是,适配了 OpenSearch 的网站),Firefox 本身就可以添加到搜索引擎,这点比 Chrome 好用很多,但定制要配置的参数也比 Chrome 多得多
  • 所以这些 technical 的信息怎么来的呢,其实都保存 ~/.mozilla/firefox/xxx.default/search.json.mozlz4,然鹅这个是压缩包,直接打开是不行的,经过这样那样的搜索,找到 mozlz4,下载二进制,解压打开,然后复制粘贴即可
  • 当然也有正常的方式,就是在网站的 sitemap 里寻找上面提到的 opensearch.xml(e.g. VNDB, Whoogle),相关信息都在里面
  • 请求方法分为 GET/POST,大部分都是 GET,POST 的配置起来略复杂,建议直接看 opensearch.xml
  • IconURL 不建议修改为网站 favicon 的动态 URL,这样在每次启动(不限于第一次启动)Firefox 的时候都会挨个请求一遍图标,增加不必要的网络流量。当然如果看图标(比如萌娘镜像站的猛男粉)不爽也可以不填。
{
    "policies": {
        "SearchEngines": {
            "Add": [
                {
                    "Alias": "vn, gal",
                    "Description": "Search visual novels on VNDB.org",
                    "IconURL": "data:image/x-icon;base64,后略",
                    "Method": "GET",
                    "Name": "VNDB",
                    "URLTemplate": "https://vndb.org/v?q={searchTerms}"
                },
                {
                    "Alias": "mw, dict",
                    "Description": "Dictionary by Merriam-Webster",
                    "IconURL": "",
                    "Method": "GET",
                    "Name": "Dictionary",
                    "URLTemplate": "https://www.merriam-webster.com/dictionary/{searchTerms}"
                },
                {
                    "Alias": "moe, mn, meng",
                    "Description": "泛 ACGN 向 Wiki(百科)站点,主要收录 Anime(动画)、Comic(漫画)、Game(游戏)、Novel(轻小说)及相关网络文化。",
                    "IconURL": "data:image/png;base64后略",
                    "Method": "GET",
                    "Name": "萌娘百科",
                    "URLTemplate": "https://moegirl.uk/index.php?title=Special:%E6%90%9C%E7%B4%A2&search={searchTerms}"
                },
                {
                    "Alias": "ddg",
                    "Description": "Search DuckDuckGo (Lite)",
                    "IconURL": "data:image/x-icon;base64后略",
                    "Method": "POST",
                    "Name": "DuckDuckGoLite",
                    "PostData": "q={searchTerms}",
                    "URLTemplate": "https://lite.duckduckgo.com/lite/"
                }
            ],
            "Default": "DuckDuckGoLite",
            "Remove": [
                "Amazon.com",
                "DuckDuckGo",
                "Google"
            ]
        }
    }
}

仅仅三个例子显然没办法覆盖全部内容,但麻烦的部分基本都有所涉及,其他配置项照猫画虎,看报错信息修补即可。还有一些很有用的配置,例如 Handlers(比如默认在 Firefox 中打开 RSS……)和 WebsiteFilter(网站的屏蔽/允许名单),没有配置,有缘再说。

插件

感觉这东西没什么好说的,过于烂大街,看到那些装一百多个插件,时刻开几十个页面的人大放厥词我常常感到无奈,因为很多内容其实不需要插件就能实现。只要能够完全掌握我上面提到的内容,你已经比地球上绝大部分人更能掌控浏览器的方方面面。工具始终就是工具,不要沦为工具控(aka. 工具的奴隶),而要当工具的奴隶主,亲自调教浏览器能让你对浏览器内部有更深刻的了解。

为什么我看不上 LibreWolf,一个是不基于 Firefox ESR,另一个是没有自动更新,最后就是它单纯 = Firefox + user.js + uBlock Origin + 杂七杂八会导致更多问题的 patch。实在要说审美也比 Mozilla 略微在线,仅此而已。它甚至没用上 CSS 和 policy-templates,而你在享受虚假的 7 隐私保护的同时,也面临着所有下游项目都无法避免的一点——更新延迟。

  • 不用 ESR = 更新更频繁 = 忽略更新的风险加大
  • 采用第三方 user.js = 存在浏览器更新,而 user.js 尚未更新的窗口期(个人可以通过及时自定义弥补)
  • 绑定 uBlock Origin 的用户潜在预期是一有更新就要发版
  • patch = 上游一更新就要重新做 patch,这个工作一般很简单但也很琐碎

后面会单独出一篇介绍浏览器插件 8,这里先按下不表。

吐槽

Firefox 的 policy-templates 数量级就比 Chromium 系要小,这点还可以用海量的 user.js 和 autoconfig 配置项来解释。匪夷所思的是 Cookies 配置功能比 Chromium 要弱很多,不支持通配符,也不能设置 A 网站只能读取 B 网站的 cookies,而是 all or nothing。举例:不能允许淘宝只获取天猫的 cookies,如果要读取第三方 cookies,那就得连同广告联盟、追踪脚本、用户行为分析等等垃圾第三方一起接收,颗粒度不够细。


  1. 本文仅介绍 Firefox ESR,Firefox/LibreWolf 等自行类推 ↩︎

  2. 注意,文中通过修改 omni.ja 定制按键的方法是错误的,实际上使用 autoconfig + JavaScript 脚本就能实现同样的效果(虽然我没成功= =),在 99.9% 的情况下(剩下那 0.1% 是 LibreWolf, Tor Browser 这种套娃浏览器定制打包的情况,虽然个人可以做得比这些浏览器更好,但过于耗费精力,不建议轻易尝试),你都不需要修改 omni.ja,延伸阅读 Don’t Unpack and Repack omni.ja ↩︎

  3. 这个路径视发行版和安装源的情况而定,可能会有所变动,像 Snap/Flatpak 的路径不一样 ↩︎

  4. 使用组策略配置需要加入域,这点对纯离线环境很不友好 ↩︎

  5. 目前尚可以通过 Extensions 配置,但这东西早晚要弃用,功能不如 ExtensionSettings,而且后者实际上和 Chrome 的对应配置类似,反正都要写还是早点写了吧 ↩︎

  6. 注意这里我又移除了 DuckDuckGo,实际上它在上一步的 ExtensionSettings 中已经被移除了,写进这里就是为了说明卸载的两种方法,也说明了 Firefox 自带的搜索引擎其实就是 extension,这也是为什么它们能够自动更新的原因。再扩展一下,其实你不需要这么麻烦地配置搜索引擎,也可以借助 ExtensionSettings 安装,但我秉持着少装一个是一个、多折腾一点是一点的理念,刻意选择 learn it the hard way ↩︎

  7. 这可能说得有点过,更好的说法是「不彻底的」 ↩︎

  8. 预告一下,我大概会在这篇里喷各种插件推荐列表,并且给出更加「原生」或可靠的方案 ↩︎

Vinfall's Geekademy

Sine īrā et studiō