返回知识中心
网络

浏览器端口扫描防护:保护本机 localhost 服务

网页如何探测 localhost 端口来推断你运行了哪些本地服务,常见做法为何不够,以及如何验证回环端口的行为是否一致。

BotBrowser Team

文档中心

想直接看维护中的产品文档?

这篇文章对应的主题已经有文档中心页面。需要规范流程、当前参数和长期参考时,优先看 docs。

网页可以让浏览器向你自己这台机器上的某个地址发起连接,而浏览器通常会照做。如果该端口上有服务在监听,连接会成功,或者收到协议层面的回应;如果没有任何服务在监听,连接会被拒绝。网页对一批常见端口重复这一尝试,就能得到一份端口开闭的分布,而这份分布能反映你在运行什么软件。

下面的内容先说明如何从一次连接尝试推断出稳定的本地环境信号,再比较常见的应对办法各自留下的缺口,然后介绍 BotBrowser 的端口保护如何让响应变得一致。最后给出一个可在你自己机器上执行的验证步骤,并如实说明该功能不覆盖的范围。

两种情况的对比:未启用端口保护时,网页对开放和关闭的回环端口看到不同的结果;启用端口保护后,网页对两者看到相同的结果

要点回顾

要点: BotBrowser 端口保护会让网页对文档列出的回环端口得到一致的结果,同时保留本地工具的直接连接。它不覆盖所有端口或私有网络地址,因此启用前要核对确切的地址形式和端口范围。

目录

网页如何摸清你的本地服务

每台机器都有回环接口,它的作用是让同一主机上的程序互相通信而不必离开本机。RFC 1122 为此保留了整个 127.0.0.0/8 地址块,RFC 4291 则把 ::1 定义为 IPv6 回环地址。主机名 localhost 通常解析到其中一个或两个。只供本地用户使用的服务,例如开发服务器、数据库引擎、远程桌面辅助程序和容器工具,往往就监听在这里,因为其他机器无法访问回环接口。

不过浏览器运行在同一台机器上,所以网页代码也能访问这些端点。网页无需安装或获得任何批准,只要发起一次普通的连接尝试,例如通过 WebSocket、图片加载或 fetch 调用,然后观察这次尝试如何收场。不同的结果会告诉网页不同的信息:

  • 接受连接并以可识别方式应答的服务,说明该端口上运行着某一类特定的软件。
  • 接受连接但返回网页无法理解内容的服务,仍然说明该端口是开放的。
  • 被拒绝的连接说明没有任何服务在监听,而且拒绝到达的方式可能与被接受连接的结束方式不同。

这一切都不会读取本地服务的任何数据。网页只是得知某个端口表现出某种行为,但端口足够多时,这就是对一台机器相当详细的描述。检查几十个常见端口的网页,往往就能判断访问者运行的是网站开发环境、数据库、远程访问工具还是容器平台。

这一点的意义不止于跟踪,因为许多本地服务在编写时就假定只有同一机器上的程序才能访问它们。它们常常不要求登录,监听在知名端口上,并提供简单的 HTTP 接口。网页一旦得知这类服务存在,就已经获得了信息;如果它还能向该服务发送请求,可能获得更多。多年来浏览器收紧了跨源规则,但知道某个端口开放,比读取响应要容易得多。所以真正值得保护的,正是端口开闭的分布本身。

WICG 的 Local Network Access 提案描述了这类请求,即从公共站点提供的网页访问本地和回环地址,并建议浏览器对此类请求设置权限确认。它是社区规范,不同浏览器和版本的支持情况各异,因此不要假定你当前的浏览器会提示或拦截。依赖它之前,请先确认你自己使用的版本实际会怎么做。

为什么这种特征会跟着你跨会话出现

在同一浏览器配置文件中比较 127.0.0.1:3000 与 127.0.0.1:5432;开闭结果取决于主机进程集合,而不是 Cookie 状态。

Cookie、本地存储和 IP 地址都是你可以清除或更换的东西。你电脑上运行的服务集合则不同,因为它描述的是你如何工作,而不是你从哪里连接。每天使用同一编辑器集成、同一数据库和同一容器运行时的开发者,周一和周五呈现的是同一种分布。

正是这种稳定性让该信号可用于跟踪。看看人们重新开始时常用的几种办法:

  • 清除 Cookie 和站点数据会移除站点存放在浏览器里的状态,但不会改变哪些端口是开放的。
  • 换一个 IP 地址,例如通过代理,会改变站点看到的网络位置,但回环端口的分布属于这台机器,会一直跟着它。
  • 打开隐私窗口或第二个浏览器配置文件会重置浏览器状态,但同一台机器的应答方式不变。

这一信号也很容易与其他信号结合。端口开闭的分布只是又一个属性,可以与 canvas 输出、可用字体以及指纹脚本收集的其余内容合并。单个属性只能反映局部,合在一起却可能把一台机器区分出来,所以即使是一个较弱的信号,也值得堵上。 关于为什么无痕窗口不会改变这些信号,请参阅为什么无痕模式无法防御指纹追踪,其中逐步对比了普通会话和无痕会话。

并非所有机器的暴露程度都相同。只用来收发邮件和处理文档的笔记本,可能几乎没有开放端口,其分布与许多其他机器接近。运行十几个服务的工作站或服务器则要有辨识度得多。从处理这一信号中获益最多的是开发者、无界面服务器的运维人员,以及使用远程访问工具的人,因为这些环境监听的端口比典型的消费级机器多。

为什么常见的应对办法不够

即使把 touch-action 设为 none,也只会影响触摸手势,不会改变网页对 127.0.0.1:3000 的连接结果。

立即返回 ERR_BLOCKED_BY_CLIENT 本身就是可测结果,应先与浏览器正常连接超时的表现比较,再选择规则。

测试页面可以使用 fetch() 搭配 AbortSignal.timeout(1000) 请求 http://127.0.0.1:3000/;网页能观察到的是耗时和错误类别。

有几种办法看起来合理,但每一种都留有缺口。

直接阻止回环连接。 如果浏览器拒绝一切访问 localhost 的尝试,网页就无法得知运行着什么服务。但这种拒绝本身会成为可观察的行为。被阻止的尝试可能与正常的拒绝看起来不同,而每个端口都立刻以相同方式失败,与正常浏览器表现出的差异相比也显得反常。阻止还会破坏你可能依赖的功能:与网页通信的桌面配套应用、带实时重载的开发服务器,以及会重定向回本地监听器的登录流程。

浏览器扩展。 请求过滤器可以阻止对本地地址的连接,但它们工作在浏览器的扩展层,覆盖范围取决于请求类型。能处理 fetch 调用的规则,未必覆盖网页打开连接的所有其他方式。扩展本身也可能留下网页能观察到的痕迹,于是这种保护反而成了另一个可区分的属性。

防火墙规则。 操作系统防火墙决定哪些程序可以接受入站连接或访问网络。由网页发起的、指向 localhost 的连接是浏览器发出的本地连接,因此针对来自互联网流量调好的规则处理不了它。若规则阻止浏览器访问回环地址,又会破坏你想保留的本地工具,并重新带来拒绝方式独特的问题。

网络命名空间和容器。 在拥有独立网络命名空间的容器里运行浏览器,可以使它看不到宿主机的服务,这确实把两者隔开了。代价体现在运维上:你要多维护一层,难以访问你确实需要的宿主机服务,而且容器自身也会暴露一组网页可以探测的监听服务。对某些部署来说,这是合理的隔离手段,但对这个具体问题而言过于笨重。

VPN 路由。 VPN 改变的是出站互联网流量的去向。回环流量从不离开本机,所以路由的改变不会影响浏览器对 127.0.0.1 连接尝试的应答方式。你多加了一跳网络和一些开销,而实际行为原封不动。 关于网络路由与页面运行环境应如何描述同一套配置,请参阅面向隐私保护的网络层浏览器一致性,其中介绍了可重复的一致性验证方法。

这些办法的共同点是,没有一种能让响应变得一致。它们要么直接去掉响应,这很显眼而且会造成干扰,要么工作在看不到这条连接的层面。真正对应这个问题的目标要窄得多:当网页尝试连接一个常被探测的回环端口时,结果不应取决于是否有服务在监听。 域名解析是这些办法都没有处理的另一个独立层面;请参阅DNS 泄露防护:解析路径、代理与泄露测试,其中介绍了解析路径以及如何进行泄露测试。

开启端口保护

BotBrowser 的文档将端口保护列为 PRO 功能。它默认关闭,你可以用启动参数或配置文件设置来开启。命令行形式是在常规启动命令后加一个参数:

chrome --bot-profile="path/to/profile.enc" --bot-port-protection

同样的开关也可以写在配置文件的 JSON 里,适合那些应当始终开启保护、不该忘记加参数的配置文件:

{
  "configs": {
    "portProtection": true
  }
}

设置写在配置文件里时,配置文件一加载就会生效,不需要额外参数。如果你通过自动化框架启动,就像添加其他 BotBrowser 参数一样,把同一个参数加入启动参数即可。端口保护文档展示了在 Playwright 启动以及与代理组合配置中使用同一参数的方式。

文档描述的行为是:网页对常被探测端口发起的连接尝试,在各回环地址上表现一致。CLI 参数参考给出的覆盖范围是 30 个常被探测的端口,涉及三种地址形式:IPv4 回环地址块 127.0.0.0/8、IPv6 回环地址 ::1,以及主机名 localhost。端口保护指南描述了相同的行为,但没有给出数量。

只想在单次启动时获得保护,例如测试期间,就选择参数。希望某个配置文件始终带有保护,就选择配置文件设置。把启动脚本纳入版本控制的团队通常更喜欢配置文件设置,因为无论由哪个脚本启动,受保护的配置文件都仍然受保护,审阅配置文件也能看出意图。请记住该功能默认关闭,所以没有该设置的配置文件和没有该参数的启动,都是在无保护状态下运行。

无界面服务器和共享构建机器值得单独说明。托管着数据库、监控代理和容器工具的服务器上的浏览器,身边有许多本地监听器,它访问的网页能看到与工作站相同类型的分布。如果这个浏览器属于一组应当行为一致的机器,某台服务器独特的监听器集合就是我们不希望出现的差异。把该选项设在这些任务所用的配置文件里,就能在不依赖每个启动脚本的情况下保持行为一致。

规划时有两点要注意。第一,保护针对的是网页发起的尝试。文档说明直接连接的本地工具不受影响,所以你的终端、数据库客户端和编辑器仍像以前一样工作。第二,覆盖范围是一份固定的常被探测端口列表,而不是机器上的所有端口。如果你需要覆盖列表之外的端口,文档建议联系支持团队,不要假定它已包含在内。

用本地测试服务验证结果是否一致

验证应当说明两件事:启用保护后,网页发起的结果是一致的,以及你自己的工具仍能正常工作。你可以在自己拥有的机器上用一个临时服务检查这两点。只针对你自己的机器进行。对你无法控制的主机做测试不属于验证步骤,本文也不涉及。

在一个你可以占用的端口上,启动一个绑定在回环地址上的无害服务:

python3 -m http.server 8080 --bind 127.0.0.1

然后按顺序完成这些检查:

  1. 在未启用端口保护的情况下做一次基线测试。使用一个你自己控制、在浏览器中加载的小型测试页面,让页面代码向你的临时服务和同一地址上一个未使用的端口各发起一次连接,并记录每次尝试如何收场。
  2. 用 --bot-port-protection 或 configs.portProtection 重新启动,并重复同一页面。启用保护后,对网页而言,开放端口和未使用端口的结果应当无法区分。
  3. 对文档中列出的各种地址形式重复尝试:IPv4 回环地址、IPv6 地址 ::1 和主机名 localhost。每一种形式的结果都应当一致,而不只是其中一种。
  4. 在终端中直接连接临时服务,例如用 curl http://127.0.0.1:8080/。它应当正常应答,因为工具的直接连接不受影响。
  5. 如果你依赖网页与本地配套应用通信,请在启用保护的情况下测试这一集成。文档描述的是网页对常被探测端口发起尝试时的一致行为,所以任何在这些端口上进行的网页到本地应用的流程,在推广该设置之前都值得单独检查。
  6. 记录启动参数、所用配置文件和结果,并在配置文件、浏览器版本或启动脚本变更后重复测试。

有用的记录很简短:地址形式、端口、是临时服务还是未使用端口,以及网页观察到的结果。只记录你自己的测试端口。记录只包含你自己开启的端口的结果,就足以证明一致性,也不会在共享文档里留下你真实服务的清单。

如果基线测试本身就显得一致,这一对比的价值就不大,因为即使没有保护,你的测试页面也分辨不出两个端口。如果启用保护后,在你预期被覆盖的端口上仍能看到差异,请检查参数或配置文件设置是否已传到浏览器,并对照文档确认该端口。覆盖范围之外的端口行为与以前相同。这是应向支持团队提出的覆盖范围问题,不一定是故障。

BotBrowser 支持什么,哪些不在范围内

BotBrowser PRO 通过 --bot-port-protection 参数或配置文件中的 configs.portProtection 支持端口保护,使网页对常被探测的回环端口(涉及 127.0.0.0/8、::1 和 localhost 的 30 个端口)发起的连接尝试表现一致,这样网页就无法摸清你运行了哪些本地服务。BotBrowser 无法保证覆盖文档所列 30 个之外的端口,也无法保证覆盖 192.168.x.x 这类本地网络地址段,不能改变本地工具直接发起的连接,也不能取代代理、DNS、WebRTC 或其他指纹方面的保护。

范围有意保持得很窄。文档中提到的地址都是回环地址。网络中其他设备使用的地址段,例如 192.168.x.x、10.x.x.x 和 172.16.x.x,不在文档所述的覆盖范围内,所以不要把它们说成已受保护。该功能也只是多层防护中的一层:你的 IP 地址、DNS 查询和 WebRTC 候选地址是各自独立的面,需要单独处理,canvas、字体和类似信号也是如此。

与这一层相邻的网络层,请参阅 DNS 泄漏防护、WebRTC 泄漏防护以及代理、DNS 与 WebRTC 的一致性。在你自己的笔记里修改覆盖范围、端口数量、授权等级或默认状态之前,请重新核对端口保护文档和 CLI 参数参考,因为这些细节最有可能在版本之间发生变化。

来源

实践结论

当网页可见的回环行为必须与本地监听器无关时,启用 --bot-port-protection 或 configs.portProtection。核对文档列出的 30 个端口,并分别检查 127.0.0.1、::1 和 localhost;浏览器结果一致,并不意味着私有网络地址或未列出的端口也受到保护。

#Port#Scanning#保护#网络#隐私

本文属于指南: 代理配置总览:浏览器网络决策图

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。