
camofox-browser 是我维护了半年多的一个 Firefox 定制项目核心目标很简单把浏览器运行时暴露的“身份特征”收敛到最低让网站、广告平台和统计脚本难以通过浏览器指纹持续勾画我的画像。这个项目本身不算复杂没有从零写浏览器内核而是基于 Firefox 做了一套深度配置方案。名字里的 Camo 取“迷彩”的意思Fox 指 Firefox整体思路就是给浏览器穿上一件“迷彩服”让它在外网环境里报出一组不容易被关联的身份信息。这篇博文我会把项目从动机、技术选型、反指纹原理到具体的 user.js 配置、扩展搭配和问题排查完整过一遍。想解决隐私追踪问题的普通用户、做前端或数据分析的技术人员以及单纯想折腾 Firefox 的人都适合往下看。1. camofox-browser 的项目定位与核心思路1.1 为什么需要一款“迷彩”浏览器先说一个容易被忽略的事实清除 Cookie、开无痕模式其实只解决了很小一部分追踪问题。无痕模式清得掉 Cookie却清不掉浏览器指纹。广告平台只要拿到你的 Canvas 渲染结果、WebGL 参数、字体列表、时区这些信息换个 Cookie 照样能把你认出来。我当初做 camofox-browser起因是一次很直观的体验。我开了浏览器的“严格跟踪保护”然后去一个测试站点看自己的指纹信息页面居然还能精确读出我的显卡渲染器、系统安装的字体、显示器的分辨率、甚至我在哪个时区。那一刻我意识到所谓的“隐私浏览”在指纹追踪面前基本等于裸奔。项目定位也随之清晰了不做“完全匿名”只做“降低可关联性”。目标是让不同站点之间拿到的浏览器特征尽量不一致、不稳定或者统一成一套不容易区分用户的通用值。也就是说广告平台看到你的时候会觉得你和其他几千几万个人长得一模一样没办法用设备特征来长期锚定你。这个定位务实也适合日常使用。1.2 技术选型为什么要基于 Firefox这个项目不是从零写浏览器而是基于 Firefox 做深度定制。选 Firefox 而不是 Chromium 系我是认真对比过的原因主要有四点。其一Firefox 是开源项目核心代码公开可审阅隐私保护相关的改动你可以一条条追踪不存在“我替你做了某个你不知道的数据收集”这种黑箱。其二Firefox 内置了privacy.resistFingerprinting这类系统级反指纹开关一套机制覆盖 Canvas、WebGL、音频、时区、语言等多个维度Chromium 生态里类似的功能大多靠扩展拼接力度和一致性都不够理想。其三Firefox 所有偏好可以集中写进 user.js 文件随 profile 目录一起管理换机器、还原配置都非常方便非常适合“配置文件即项目”的维护方式。其四桌面端和 Android 端共用同一套偏好体系后续想移植到手机上也容易。Chromium 生态的优势是兼容性更好很多老旧的业务系统只对 Chromium 做了完整适配。但在隐私定制的自由度上Firefox 的 about:config 暴露的内部偏好项要丰富得多我可以精确控制每一个信息通道。就“做一款以隐私为第一优先级的个人浏览器”这个诉求来说Firefox 是更顺手的底子。2. 反指纹机制拆解浏览器到底暴露了什么2.1 常见的几类浏览器指纹要理解 camofox-browser 改了哪些东西得先知道浏览器在背后暴露了多少信息。简单分一下类。第一类是设备硬件信息。网站可以通过 JavaScript 读取屏幕分辨率、颜色深度、设备的硬件并发数hardwareConcurrency、设备内存deviceMemory等。这些参数在不同电脑上差异明显组合起来就是一组不错的标识。第二类是图形渲染指纹。网页把一段固定的图形绘制到 Canvas 上再读回像素数据不同显卡、不同驱动、不同操作系统的渲染结果会有细微差别这个差值就是 Canvas 指纹。WebGL 指纹更进一步可以拿到渲染器名称、显卡厂商甚至 GPU 驱动版本。第三类是音频指纹。通过 AudioContext 处理一段标准音频不同设备的声卡和底层音频栈会产生微小波形差异这个差异同样能被提取出来当标识。第四类是字体信息。页面用一段文字和一堆不存在的字体名去做测量通过渲染宽高的变化枚举出系统里实际安装了哪些字体这个列表非常个人化。第五类是环境信息包括时区、语言优先级、User-Agent、Accept-Language 头等。最后还有存储与行为特征比如 localStorage、IndexedDB、Service Worker 的存在与否以及页面上的鼠标轨迹、滚动行为等。其中图形渲染指纹和音频指纹是最难处理的一类因为它们来自设备底层能力不是你设置一个开关就能关掉的。很多人以为“清掉 Cookie 开无痕”就安全了实际上你的显卡渲染同一张画布输出结果就是和别人不一样这串输出就是你的数字胎记。2.2 camofox-browser 的应对思路针对这些暴露面我的配置思路不是“把所有接口都关掉”因为那样会制造一个特征过于明显的浏览器反而更容易被识别。更合理的思路可以概括成六个字统一、模糊、隔离。统一就是把设备信息的取值归一化。例如把时区固定到一个默认值把语言优先级固定成少数几项让所有网站看到的都是同一套“标准答案”。模糊是开启 resistFingerprinting 和相关保护后Canvas、WebGL、音频接口返回的结果会被加入轻微噪音。这样同一个设备每次拿到的指纹都不是精确值网站拿去做长期关联就不可靠了。隔离是把不同用途的站点放进不同容器Cookie、登录态、存储彼此隔离站点之间很难通过头信息和存储相互关联。这套组合比单独开无痕模式要激进得多。无痕模式是“我走后不留痕”而 camofox-browser 是“我在的时候看到的我也是假的”。两者的差别是隐私保护思路上的根本差异。3. 实战配置手把手搭一套 camofox-browser3.1 准备独立的浏览器配置环境我的建议是不要拿你日常使用的 Firefox 直接改而是单独建一个 profile。原因很简单反指纹配置会影响很多网站的正常使用把它和日常浏览混在一起哪天需要开发调试时你会被各种异常逼疯。创建独立 profile 的方法是先关闭所有 Firefox 进程然后在终端执行firefox -CreateProfile camofox firefox -P camofox --no-remote之后启动时都用-P camofox指定这个 profile。Linux 环境下我习惯把 profile 目录用 Git 管理user.js和扩展列表同步到私有仓库换机器后十分钟就能还原整套环境。Windows 上也可以把profile路径放到一个固定位置配合符号链接来管理思路是一样的。注意user.js文件放进 profile 根目录后每次 Firefox 启动都会读取它并覆盖 about:config 里对应的配置项。如果你在 about:config 里手动改过某个值下次启动又会被 user.js 拉回去所以修改配置时尽量集中在 user.js 这一处维护。3.2 核心参数清单与释义Firefox 的 user.js 是配置的入口每一行就是一个偏好项。我当前维护的配置核心如下不一定都要照抄刚开始可以先开最要紧的几个。// 开启严格反指纹模式 user_pref(privacy.resistFingerprinting, true); // 给窗口加 mailto:9000 信箱化处理避免用窗口尺寸推断屏幕大小 user_pref(privacy.resistFingerprinting.letterboxing, true); // 禁用 WebGL把 WebGL 指纹这个大头关掉 user_pref(webgl.disabled, true); // 禁用 DRM 相关组件减少可枚举的插件信息 user_pref(media.eme.enabled, false); // 关闭健康报告与遥测 user_pref(toolkit.telemetry.enabled, false); user_pref(toolkit.telemetry.unified, false); user_pref(datareporting.policy.dataSubmissionEnabled, false); // 关闭地理位置定位 user_pref(geo.enabled, false); user_pref(geo.provider.network.url, ); // 不主动发送会话历史给推荐系统 user_pref(browser.newtabpage.activity-stream.feeds.section.topstories, false); user_pref(browser.newtabpage.activity-stream.feeds.snippets, false); // 设置 referer 策略降低来源信息泄露 user_pref(network.http.sendRefererHeader, 0); user_pref(network.http.referer.XOriginPolicy, 2); // 关闭剪贴板事件防止页面在后台读取复制行为 user_pref(dom.event.clipboardevents.enabled, false);这些参数的作用我逐个说一下。privacy.resistFingerprinting是 Firefox 内置的反指纹总开关。开启后浏览器会用统一值替代大部分可枚举的设备信息并且会对 Canvas、WebGL、Audio 数据做噪点处理。它的影响面很大很多原本能拿到的精确值会变成模糊值这也是我建议用独立 profile 的原因之一。letterboxing会把窗口尺寸调整成固定网格的整数倍避免网站通过window.outerWidth和screen.availWidth的差值反推真实屏幕大小。这个行为在较新的 Firefox 里随总开关默认生效我这里显式写出来是为了防止有人单独关闭它。webgl.disabled比较激进直接放弃 WebGL 能力。如果你日常要看 3D 可视化或者玩网页游戏可以先不关靠 resistFingerprinting 自带的 WebGL 噪点应付如果追求最大确定性就关掉。我的使用场景很少依赖 WebGL所以选择关闭。media.eme.enabled的关闭会影响部分视频网站的加密播放后面第 4 章会细说。遥测相关参数主要是关闭向 Mozilla 上报使用数据的通道对反指纹没有直接关系但能减少一些网络层面的特征请求顺手就关了。地理位置和剪贴板事件也是同理不开白不开。再强调一次user.js不是越全越好。每一条配置都会带来兼容性成本建议分阶段开启跑一段时间再决定要不要加严。下面把关键参数整理成表格方便对照配置项作用风险privacy.resistFingerprinting系统级反指纹统一设备信息并加噪部分站点校验异常privacy.resistFingerprinting.letterboxing窗口尺寸信箱化无明显副作用webgl.disabled完全禁用 WebGL3D 可视化页面不可用geo.enabled禁用地理位置地图定位类功能失效network.http.sendRefererHeader控制 Referer 发送某些防盗链图片可能加载失败3.3 扩展搭配隐私保护组合拳如果只用官方设置仍然会留一些尾巴所以我会再配上几个固定扩展。这里的原则是少而精不是越多越好。第一推荐是 uBlock Origin。它拦截广告脚本和追踪器的能力非常强性能开销极小规则库更新也勤。这个扩展几乎没有替代方案。第二是 NoScript默认拦截 JavaScript。这个扩展比较硬核日常浏览会遇到页面白屏需要手动放行我一般是针对不熟悉的站点开启默认拦截常用站点全放行配合白名单用。第三是 CanvasBlocker它可以在 Firefox 内置反指纹基础上对 canvas 读取做更细的“放行、伪装、阻断”控制。如果已经依赖 resistFingerprinting这个扩展不一定需要想按站点放行部分绘图操作时它很有用。第四是 Firefox Multi-Account Containers用来把不同站点的会话隔离进独立容器比如工作、购物、社交各用一个容器能够进一步切断跨站追踪路径。我不太推荐装“全家桶”式的隐私扩展比如某些声称“一键加密浏览”的插件。这类插件往往只改了 User-Agent 就宣称保护隐私实际效果非常有限还容易与 uBlock Origin 的过滤规则冲突。3.4 怎么验证隐形效果配置完之后最重要的一步是验证。我每次调整配置都会去跑一遍指纹检测页面记录前后变化。这里以 browserleaks 这类公开的指纹检测站点为例操作流程分三步。第一步找一个能显示完整指纹信息的检测页面先记录一个“基线”也就是未开配置时报出来的值。第二步开启 camofox 配置刷新同一个页面对比信息量差异。第三步来回切换几个不同 profile看看它们之间是否还能被区分。我实测下来的效果很明显。未配置时页面能直接读出显卡渲染器型号、系统字体列表、时区、屏幕分辨率配置之后这些值要么变成了统一的默认值要么变成了带噪点的近似值而且前后两次刷新还有细微差别。也就是说站点拿到的不再是一把终身不变的钥匙而是一把每次都在略微变化的钥匙很难再把指纹关联到同一个人的长期行为上。不过这里要提醒一句指纹保护不等于网络出口不留痕迹。反指纹解决的是“设备身份”问题网络层的出口 IP 仍然会暴露大致地理位置和运营商。如果隐私需求真的极高你需要另做网络层的隔离方案但那已经超出浏览器配置的范畴这篇文章不展开。4. 兼容性排查我踩过的那些坑4.1 账号登录和支付类站点异常我遇到的第一类问题是登录和支付类站点突然“不认识我了”。具体表现是登录后跳回首页仍显示未登录支付页面提示环境异常或者反复弹出滑块验证。原因主要有两个一是 resistFingerprinting 会让浏览器报告的时区和语言变成统一值与账号之前记录的环境差异太大触发风控二是站点的验证码脚本在读 Canvas 或 WebGL 指纹时拿到了一串“假的、不稳定”的数据脚本校验直接失败。我的处理方式是不要为这一类站点修改全局参数而是把它们隔离到一个单独的容器或 profile 中使用相对正常的配置。日常浏览用严格配置登录和支付用另一个宽松配置两边互不干扰。这比在全局配置里“打洞”更容易维护也避免了一个站点开白名单导致所有站点都享受宽松待遇。4.2 视频卡顿与页面渲染异常第二个常见问题是视频播放和 WebGL 相关的页面异常。关掉 WebGL 之后部分地图类、可视化类页面直接白屏一些视频网站也会回退到低兼容性播放逻辑画面模糊或无法切换清晰度。排查思路很简单先用一个干净的 profile 加载同一页面如果不异常再把 user.js 按区块二分开启定位是哪一条配置引发的。我在实践中发现大部分视频播放问题与media.eme.enabled false有关因为部分站点的视频解密依赖这个组件关掉之后加密内容无法解码。如果你经常看视频建议保留media.eme.enabled为默认值只靠 resistFingerprinting 做其他保护即可。4.3 扩展之间的冲突与指纹测试结果不一致第三个坑来自扩展之间的互相干扰。最开始我同时装了 uBlock Origin、CanvasBlocker 和 NoScript结果指纹检测页面有时显示字体列表为空有时又显示完整字体列表前后不一致。排查了半天才发现是 NoScript 拦截了字体探测脚本而 CanvasBlocker 又对 Canvas 做了伪装两个扩展叠加产生了不确定的中间状态。这类问题没有一键修复的办法只能逐个开关扩展来定位。我的建议是扩展组合保持最小化Firefox 自带的 resistFingerprinting 已经覆盖了大部分反指纹需求扩展只做补充不要叠床架屋。4.4 问题速查表把日常维护中遇到的高频问题整理成下面的速查表排查的时候直接对照。现象常见原因解决办法登录后跳回未登录时区、语言、屏幕参数与之前差异过大用宽松配置的容器处理登录站点支付页提示环境异常指纹带噪点风控脚本校验失败登录与支付放到独立容器视频无法播放或回退清晰度media.eme.enabledfalse 导致解密失效放开 media.eme.enabled地图、3D 页面白屏WebGL 被禁用临时换用一个宽松 profile或打开 webgl指纹检测结果前后不一致扩展叠加产生不确定状态减少扩展数量保留核心组合图片防盗链失效Referer 被裁剪按站点调整 referer 策略最后再分享一点维护上的心得。camofox-browser 这个项目做下来我最大的体会是隐私保护不是“开一个开关”就结束的事情而是一条持续迭代的路。浏览器在更新网站的检测技术在更新你的配置也不可能一劳永逸。我通常每两周会花半小时做一次例行维护拉取最新版 Firefox 更新说明看看有没有影响现有配置的改动跑一次指纹检测对比各项指标检查扩展是否发布了可能导致行为变化的新版本。这套节奏坚持下来项目才能一直保持在可用状态。如果你也想跟着搭一套路径可以很简单先建独立 profile从开启privacy.resistFingerprinting和letterboxing开始跑一周看能不能接受遇到的兼容性问题再逐步加严。不用一开始就追求“最强隐身”先保证“不被广告平台一眼认出”就已经赢了一大半。