
做浏览器定制这件事很多人第一反应是“不就是换个主题皮吗”。但当你真正把浏览器的隐私策略、界面布局、默认扩展全部按自己的标准重新捏过一遍之后就会发现这事完全不是换皮肤那么简单它是一套叫“配置工程”的东西。camofox-browser就是这么来的一个以Firefox内核为基础的隐私向定制浏览器。camo是迷彩fox是火狐合在一起就是“披着普通外衣、内里却做了严格隐私策略配置的火狐”。这个项目能解决的核心问题很明确主流浏览器开箱即用的隐私配置太宽松普通用户又不会手动去折腾关于隐私的那几十个开关。它适合两类人一类是关注个人数据、不喜欢被追踪的普通上网用户另一类是Firefox的深度玩家、想自己做点增量改造的开发者。下面我把我整个设计思路、配置过程、踩坑记录全部分享出来。1. 项目定位为什么我还要自己做一款浏览器1.1 camofox-browser到底做了什么我先把话放在前面camofox-browser不是一个从零写的浏览器内核它是在Firefox基础上做的一套完整定制方案。整个方案分三层第一层是内核配置通过prefs.js和user.js预先写入一批隐私策略让浏览器启动时就处于一个相对保守、少收集数据的状态第二层是界面定制用userChrome.css把默认UI重新收拾一遍去掉商店按钮、推荐位、标签页同步入口这些我不需要的东西视觉上保持克制第三层是扩展策略通过distribution/policies.json预置少量必要的扩展比如内容拦截类的uBlock Origin同时禁止用户意外安装那些我不想要的插件。这三层做完之后你拿到的就是一个可以独立运行、独立命名的浏览器变体。它不是魔改到面目全非的那种反而在界面上看起来非常接近原生Firefox但实际行为已经完全不同默认不强联、启动不加载个性化推荐、cookie和站点数据关闭时自动清理、指纹采集被大幅干扰。换句话说它从“一个默认帮你收集点数据的商业浏览器”变成了“一个默认帮你挡数据的私人浏览器”。我选择用Firefox而不是别的内核还有一个务实原因Firefox对用户自定义开放得比较彻底。关于隐私的配置项多到能写一本手册UI样式可以自由改企业策略接口policies.json是公开文档支持的。这意味着我做出来的这套东西不仅自己能跑本来习惯用火狐的人也能直接套用降低了迁移成本。1.2 为什么不从Chromium系下手这个问题我纠结过毕竟Chromium系占了浏览器大头网上现成的定制脚本也很多。但我最终放弃原因有四个。第一Chromium的代码库非常庞大编译环境要求比Firefox高得多如果你想改点默认行为需要熟悉一整套Chromium的构建体系和GN参数这对个人项目来说太重了。第二Chromium系浏览器的默认行为受上游策略影响很大很多配置项虽然在桌面版还存在但官方推进的方向是“统一化”和“云同步”你想保留本地化、离线化的操作空间被一步步压缩。第三从隐私定制角度看Firefox的about:config里有一批现成的反指纹、清理缓存、禁用预取类参数这些参数经历过大量隐私研究者测试直接写进配置就可以形成一套组合拳。当然更重要的是一点私心生态不能一边倒。如果所有定制爱好者都去做Chromium套壳那开源浏览器的多样性会越来越弱。Firefox虽然市场份额不大但它保持了完整的独立浏览器引擎在渲染、扩展接口、配置系统上有自己的坚持。我做camofox-browser也是想给这个独立的生态添一个微小的可参考样本。2. 核心设计隐私策略、界面伪装与扩展选型2.1 隐私配置的四个层次与关键参数这一部分是整个项目的基础也是最容易让人迷惑的地方。隐私配置不是把所有开关都关上就完事那样浏览器基本没法用。我做了一个分层第一层管数据残留第二层管网络预连接第三层管指纹采集第四层管传输链路。数据残留层是我最先动的。上过网的人都知道网站最常用的是cookie和本地缓存来记录你是谁、上次干了什么。我的处理是cookie的生命周期设置为会话级也就是浏览器一关就清掉缓存、离线站点数据、站点设置也都在关闭浏览器时自动清理。相关的核心参数是这几个network.cookie.lifetimePolicy 2 privacy.clearOnShutdown.cache true privacy.clearOnShutdown.cookies true privacy.clearOnShutdown.offlineApps true privacy.clearOnShutdown.sessions true privacy.sanitize.sanitizeOnShutdown true这里有个值得说明的地方privacy.sanitize.sanitizeOnShutdown是一个总闸打开之后它会让Firefox在退出时按白名单清理指定类型的数据。如果只设置单个clearOnShutdown项有时会因为其他策略冲突不生效所以建议总闸和分项一起设。我自己第一次只写了分项结果退出之后再开浏览器cookie还在排查了半天才发现是总闸没开。第二层是网络预连接。浏览器为了让你打开网页更快会在你敲完URL之前就偷偷做DNS解析、预连接、预渲染这些操作确实能提升加载速度但也会暴露你的兴趣偏好。我的做法是把这类“提前动作”全部关掉参数如下network.dns.disablePrefetch true network.prefetch-next false network.predictor.enabled false network.http.speculative-parallel-limit 0 browser.urlbar.suggest.searches false browser.search.suggest.enabled false代价也很明显在部分网页上第一次点击链接时的加载时间会比开着预连接时略长一点。这个取舍我接受。如果你更在意速度可以把dns.disablePrefetch留成false只关掉predictor这样速度损失会小一些。第三层是指纹采集。这里要引入一个概念浏览器指纹。就算网站不种cookie它也能通过读取你的屏幕分辨率、操作系统、显卡型号、字体列表、Canvas渲染结果等一系列信息组合出一个大概率能识别到你的编号。Firefox的应对机制是privacy.resistFingerprinting开启后会对一部分接口返回虚假或泛化信息比如把时区强制固定、降低分辨率精度、干扰Canvas读取。我同时开启了letterboxing它会在窗口尺寸上做变化处理让网站在读取窗口宽高时得不到精准值。这两个开关的副作用也必须说明开启后部分站点会出现地图白屏、WebGL渲染异常偶尔布局会乱。所以它不适合所有人但如果你对指纹追踪敏感答案是利大于弊。第四层是传输链路。主要是强制HTTPS优先让浏览器在访问支持加密的站点时优先走加密连接避免明文传输。对应参数是dom.security.https_only_mode。另外我还关掉了click追踪ping这个参数是browser.send_pings关闭后网站通过js或a标签发送的轻量级追踪请求就不会被浏览器代发。2.2 界面定制让浏览器看起来足够“普通”我刻意用了“普通”这个词。很多时候一个浏览器能不能在日常场景里被放心使用取决于它看起来是否足够低调。如果界面上全是各种推荐位、账号入口、云同步图标旁边的同事扫一眼就知道你用的是一套高度个性化配置反而容易引来闲聊和注意。camofox的界面目标就是剥掉这些多余元素只保留地址栏、标签栏、导航按钮颜色上尽量贴近系统原生。实现方式不是改Firefox源码而是用一个叫userChrome.css的样式文件。Firefox从较新的版本开始默认不再加载这个文件需要在about:config里先把toolkit.legacyUserProfileCustomizations.stylesheets设为true然后在配置文件的chrome目录里手动创建userChrome.css。我放一段实际在用的精简样式你可以直接抄/* 收窄标签栏高度 */ #TabsToolbar { min-height: 30px !important; max-height: 32px !important; } /* 收窄导航栏去掉多余内边距 */ #nav-bar { padding-top: 2px !important; padding-bottom: 2px !important; min-height: 32px !important; } /* 隐藏Pocket按钮、账号菜单、扩展菜单等入口 */ #pocket-button, #fxa-toolbar-menu-button, #unified-extensions-button, #library-button { display: none !important; } /* 地址栏字体稍小一点视觉更紧凑 */ .urlbar-input { font-size: 13px !important; } /* 让激活标签页和未激活标签页的对比弱一点整体更素 */ .tabbrowser-tab { background-color: transparent !important; }这套样式我实际用了几个月最大的感受是“省心”。少了那些红点、角标、徽标之后浏览器的视觉噪音明显降低你会更专注地把它当作一个纯粹的工具。另外有一点要提醒Firefox每次大版本升级之后UI结构可能会微调比如某几个选器失效样式就没效果了。所以这个文件不是写完就能一直用遇到版本更新后界面突然变回原样先打开浏览器控制台重新审查元素看看对应按钮的id是不是变了。2.3 扩展选型坚持少而精扩展是把双刃剑。一个优秀的扩展能补足浏览器的能力但装得越多浏览器指纹里的插件特征就越明显反而容易暴露自己。camofox的扩展策略只有两条能少装就少装装就装真正开源的。我确定的必装项是uBlock Origin。它虽然被叫广告拦截器但实际是一把网络请求过滤的瑞士军刀能在请求发出前就把它拦掉意味着统计脚本、追踪像素根本不会执行。第二顺位是CanvasBlocker它专门针对Canvas指纹做随机化处理和Firefox内置的resistFingerprinting形成互补但我安装在另一台机器上测试时发现部分在线表单的canvas控件会异常所以默认配置里没有加进去。如果你想用建议先开“仅拦截有记录指纹行为的网站”模式而不是全局拦截。localCDN也是我比较推荐的扩展它能把公共CDN上常见的前端库缓存到本地减少向第三方域名发起的请求。第三方请求减少一来降低被追踪面二来也降低页面加载时的依赖风险。它的副作用是偶尔会让某些依赖极老版本库的页面渲染异常遇到时候直接在扩展面板里临时禁用即可。在扩展这一块我的心得是每装一个扩展都要问自己一个问题这个扩展是否在做浏览器本身做不了的事如果浏览器设置里就能实现那就不要装扩展。比如“右键搜索图片”这种功能Firefox原生就支持不需要额外装一个不停读取点击行为的扩展。扩展越少整个配置的可解释性和可维护性就越高。3. 实操过程从零做一套自己的camofox3.1 轻量路线在官方Firefox上叠加配置如果你不打算啃源码又想快速拥有一个camofox体验最稳妥的方式是把配置做成一套“皮肤”叠加到官方Firefox上。我这里说的并不是改变视觉皮肤而是指一套可重复执行的配置文件。具体操作分三步。第一步为camofox单独创建一个配置文件。Firefox默认的配置文件里往往带了一堆你常用网站的状态直接在上面改隐私策略会把日常使用习惯搅乱。我建议这样firefox -no-remote -P camofox在弹出的配置管理器里新建一个配置文件并命名。关闭浏览器用about:support页面找到这个配置文件的目录路径之后所有文件都往这个文件夹里放。第二步写入user.js。user.js会在每次浏览器启动时被自动读取并合并进prefs.js它是一个比直接在about:config里改选项更利于维护的方案。在刚才的配置文件目录下新建一个文件名为user.js的文件把我上面列出的所有参数都写进去保存。注意编码用UTF-8不要带BOM否则个别版本的Firefox会有解析问题。第三步放置界面样式和策略文件。在同一个配置目录下新建chrome子目录把userChrome.css放进去。如果profile目录里本身有prefs.js记得在修改配置文件前先备份一份出问题时能快速还原。轻量路线的好处是即时生效、回滚容易。它适合大多数普通用户因为我并不需要重新编译整个浏览器改的只是运行时配置。缺点也很明显你依然依赖官方Firefox的更新节奏官方升级后某些参数可能作废你需要在下一个大版本发布后重新检查一遍。3.2 进阶路线编译一个真正改名的Firefox如果你是开发者想把camofox做成一个独立的浏览器产品而不是一个profiel配置那就需要走源码编译路线。这个过程不会很轻松但做完之后你会拥有一个真正改名换标、默认配置内建的Firefox衍生版。先准备好环境。我是在Linux下做的命令如下sudo apt install mercurial python3 python3-pip build-essential \ libgtk-3-dev libgtk-3-0 libgdk-pixbuf2.0-dev libdbus-glib-1-dev \ libasound2-dev libx11-dev libxext-dev libxt-dev libpango1.0-dev \ libxcomposite-dev libxdamage-dev libxrandr-dev libxrender-dev \ libxtst-dev libgconf2-dev libnss3-dev libnspr4-dev然后拉取Firefox源码。Mozilla现在推荐用Mercurial而不是Git来拉主库hg clone https://hg.mozilla.org/mozilla-unified cd mozilla-unified hg update central ./mach bootstrapmach bootstrap会自动检测系统缺少的依赖并安装这一步建议全程联网耗时比较久。接着是创建mozconfig这是Firefox编译的核心配置文件我用的关键参数如下ac_add_options --enable-applicationbrowser ac_add_options --enable-release ac_add_options --disable-tests ac_add_options --disable-debug ac_add_options --without-google-location-api ac_add_options --with-brandingbrowser/branding/camofox ac_add_options --enable-official-branding这里要特别解释一下最后两行。camofox想要拥有独立的品牌名称、图标和about页面标识就必须在browser/branding/camofox目录下放一套属于自己的品牌资源。最简单的方式是复制Mozilla自带的unofficial品牌目录然后改其中字符串和图标cp -r browser/branding/unofficial browser/branding/camofox cd browser/branding/camofox # 然后编辑里面的 configure.sh、brands.properties 等相关文件把Firefox命名改为camofox品牌目录里通常有icon64.png、icon128.png、firefox.ico以及若干个文本文件。如果你想让它看起来完全独立这几个图标和名字都建议统一替换。一切就绪之后开始编译./mach build这一步非常吃硬件。我在32GB内存、8核CPU的机器上首次全量构建大约花了两小时。如果你内存小于16GB建议在mozconfig里加一条ac_add_options --disable-jemalloc之类的减压选项同时关闭其他大型应用否则很容易出现内存耗尽导致编译器被杀掉的情况。构建完成后用./mach run可以启动这个自制浏览器先用它确认配置和品牌没问题再执行./mach package打出一个可分发的安装压缩包。3.3 把扩展预置进浏览器在官方Firefox里扩展是用户自己去插件商店装的。但在camofox里我希望某些扩展是浏览器自带的用户拿到手就有效果不用额外配置。实现方法是在源码的distribution目录里放置扩展文件。具体做法是在mozilla-unified根目录下创建distribution/extensions/然后把要内置的扩展xpi文件复制进去并且文件名必须是扩展的ID。以uBlock Origin为例扩展ID是uBlock0raymondhill.net所以复制后应该是distribution/extensions/uBlock0raymondhill.net.xpi如何确定一个xpi的扩展ID直接把xpi用压解工具打开看里面的manifest.json找browser_specific_settings.gecko.id字段即可。这样构建出来的浏览器在首次启动时就会自动加载这个扩展用户不需要安装操作。3.4 品牌化与分发如果你不是要分发给别人只是为了自己用那么一路编译下来到这里就可以停。但camofox项目如果想让其他朋友也能用上还需要做一点品牌化和分发层面的工作。一是把about页面的Logo、产品名改成你的项目名这在前面品牌目录里已经做了。二是把源码里的隐私策略直接写进branding相关的默认pref文件我是在browser/app/profile/firefox.js里追加了一批默认参数这样即使之后用户手动改坏了配置重置到默认值时这些隐私参数也会立即恢复而不是回到Mozilla的宽松默认。打包输出的tar.bz2或安装包可以直接拷贝到目标机器上解压运行。4. 常见问题与排查技巧实录4.1 网站登录状态总是掉线怎么办这个问题我遇到得非常早。配置完清理策略之后我发现很多网站每次重开浏览器都要重新登录后来甚至有一部分网站在同一个会话内都会掉。排查思路是先把privacy.sanitize.sanitizeOnShutdown关闭刷新页面测试登录状态是否恢复。如果恢复说明问题出在清理策略太激进。我的解决办法是cookie的lifetimePolicy不设成强制2而是保留默认只依赖关闭时的clearOnShutdown清理。这样会话内cookie保留退出再清兼顾了登录体验和清理需求。4.2 开启resistFingerprinting后页面布局错乱这是反指纹带来的最典型副作用。某些地图、在线设计工具、可视化页面对Canvas精度要求很高一旦Firefox对Canvas读取注入噪声或者对接糢域化参数就会出现文本重叠、按钮错位甚至整个白屏。我的处理方式并不是放弃指纹保护而是判断这个站点是不是必须依赖精确Canvas。手动打开站点并临时关闭resistFingerprinting使用完再开回来。如果你不想频繁切换也可以安装一个叫Vytal的扩展作为补充手段但记住扩展越多指纹特征越明显需要自己权衡。4.3 userChrome.css写了完全不生效排除CSS本身写错的情况最可能的原因就是你没开启userChrome的加载开关。新版Firefox为了安全默认禁止样式文件加载你必须先在about:config里创建toolkit.legacyUserProfileCustomizations.stylesheets并将值设为true重启后样式才会生效。另一个容易忽略的地方是配置文件目录搞错了。在about:support页面找到“配置文件文件夹”和“本地服务文件夹”userChrome.css要放在“配置文件文件夹”下的chrome目录里两个位置别混淆。很多人在网上问样式不生效一查都是放错目录或者没开开关。4.4 源码编译总在中间报错编译Firefox的报错信息很多我遇到频率最高的有三类。第一类是依赖缺失mach bootstrap其实已经能解决大部分但如果你用的是较新的发行版或者某种精简安装的环境还是会漏报某些库。建议在编译前用ldd命令检查一下系统现有的动态库依赖常见缺的是libdbus-glib、libgtk-3-dev这几种。第二类是内存不足链接阶段特别容易触发OOM解决方法是给swap分区扩大一些空间或者降低并行编译任务数比如用./mach build -j4限制到4个任务。第三类是磁盘空间不足Firefox编译的中间文件非常占地方保持根目录剩余50GB以上比较放心。4.5 常见问题速查表症状可能原因解决办法关闭浏览器后cookie未清除sanitize总闸未打开设置privacy.sanitize.sanitizeOnShutdowntrue页面样式错乱或地图白屏反指纹干扰Canvas读取在隐私设置里临时关闭resistFingerprinting自制浏览器更新后被重置配置文件路径变更检查distribution/policies.json是否丢失重新复制userChrome.css不生效未开启legacy学习式加载设置toolkit.legacyUserProfileCustomizations.stylesheetstrue内置扩展不自动加载xpi文件名与扩展ID不符检查manifest.json中ID并重命名网页总是强制跳转HTTPS后报错HTTPS-only模式误伤未完全支持加密的站点在地址栏点击锁形图标临时允许此站点加密例外部分视频会议页面无法加入WebRTC相关功能被关闭检查media.peerconnection.enabled是否为true5. 一点个人体会做完camofox-browser这套东西之后我看着浏览器里那些被关闭的开关反而更加敬畏浏览器引擎的复杂度。每一个关于隐私的选项背后都是平衡关闭预连接速度会受影响开启反指纹画布会受影响。你不可能在隐私和易用性之间同时拿满分只能根据自己最在意的方向做取舍。我个人实际用下来最大的收获并不是“我拥有了一个改名的浏览器”而是我终于弄明白Firefox的配置体系里哪些参数是纸老虎、哪些参数是真的在起作用。camofox-browser现在的配置依然会随着Firefox版本更替继续迭代升级我也越来越不急着把它做成多么大众的产品能照顾好我自己的上网习惯偶尔把方法分享出来让同好少踩几个坑这件事就已经很值了。最后再分享一个小技巧最好把user.js和userChrome.css放入一个Git仓库里做版本管理每次改配置前先提交一次出现问题时用git回滚比手动删文件要省心得多。