DNS 泄露防护:保护你的浏览活动隐私
DNS 泄露如何暴露你的浏览活动和真实位置,以及如何通过代理路由 DNS 解析以实现完整的隐私保护。
简介
当你使用代理来保护你的浏览身份时,你期望所有流量都通过该代理路由。但 DNS 查询通常走的是不同的路径。在你的浏览器通过代理连接到网站之前,它需要将域名解析为 IP 地址。如果该 DNS 查询发送到你的 ISP 解析器而非通过代理,你的 ISP 就能看到你访问的每个域名。这就是 DNS 泄露,它是基于代理的隐私设置失败的最常见方式之一。
BotBrowser 通过 --bot-local-dns 标志在浏览器引擎级别解决 DNS 泄露问题,该标志启用一个内置的本地 DNS 解析器,使解析保持在你的控制之下。
隐私影响
DNS 泄露以多种方式破坏代理隐私。你的 ISP DNS 解析器会记录你解析的每个域名,即使所有 HTTP 和 HTTPS 流量都通过代理路由,这也会创建你浏览活动的完整记录。ISP 看到域名、请求时间和你的真实 IP 地址。
除了 ISP 可见性之外,DNS 查询还会暴露你的地理位置。DNS 解析器是区域性的。如果你使用德国的代理但你的 DNS 查询发送到弗吉尼亚的解析器,这种地理不匹配是明显的。关联 DNS 解析器位置与报告 IP 位置的追踪系统可以识别这种不一致。
DNS 泄露也可能通过不太明显的路径发生。DNS 预取(浏览器用来加速导航的功能)可能在你点击链接之前就解析域名。WebRTC 可以在代理路径之外触发 DNS 查询。一些代理配置处理 TCP 流量但让基于 UDP 的 DNS 查询不受保护。
BotBrowser 的引擎级 DNS 控制同时关闭了所有这些路径。
技术背景
浏览器中 DNS 解析的工作原理
当你导航到 https://example.com 时,浏览器必须在建立连接之前将 example.com 解析为 IP 地址。解析过程通常遵循以下路径:
- 浏览器检查其内部 DNS 缓存
- 如果未缓存,查询操作系统的 DNS 解析器
- 操作系统解析器检查自身缓存,然后将查询转发到配置的 DNS 服务器(通常是你的 ISP 的)
- DNS 服务器响应 IP 地址
当配置了代理时,理想行为取决于代理协议:
- SOCKS5H:浏览器直接将主机名发送到代理,由代理处理 DNS 解析。不发生本地 DNS 查询。
- SOCKS5:浏览器本地解析 DNS,然后将解析后的 IP 发送到代理。DNS 查询会泄露。
- HTTP CONNECT:浏览器在 CONNECT 请求中将主机名发送到代理。DNS 解析取决于实现方式。
DNS 预取和推测性解析
现代浏览器积极预取 DNS 记录以减少延迟。当页面包含链接时,浏览器可能在你点击之前就解析这些域名。这种预取发生在浏览器引擎级别,在所有配置中可能不会遵守代理设置。
类似地,浏览器在你输入时对地址栏中出现的域名执行推测性 DNS 解析。这些查询默认通过操作系统解析器,创建了仅靠代理设置难以控制的泄露路径。
代理提供商 DNS 的问题
即使 DNS 查询通过代理路由(如 SOCKS5H),代理提供商的 DNS 行为可能也不理想:
- 提供商可能使用与代理地理区域不匹配的 DNS 服务器
- DNS 响应可能被提供商缓存或重写
- 提供商的 DNS 策略可能阻止某些域名
- DNS-over-HTTPS 或 DNS-over-TLS 支持因提供商而异
常见方案及其局限性
使用 SOCKS5H 代替 SOCKS5
从 socks5:// 切换到 socks5h:// 指示浏览器将主机名发送到代理进行解析,而非本地解析。这是好的第一步,但有局限性:
- DNS 预取可能仍然使用本地解析器进行推测性查询
- 代理提供商的 DNS 行为不在你的控制范围内
- 并非所有代理协议都支持远程 DNS 解析
- 浏览器内部 DNS 缓存行为在不同实现之间有差异
系统级 DNS 配置
配置你的操作系统使用特定的 DNS 服务器(如 Cloudflare 的 1.1.1.1 或 Google 的 8.8.8.8)可以防止你的 ISP 看到 DNS 查询,但这些 DNS 服务器仍然能看到。这些 DNS 服务器通常位于与你的代理不同的地理区域,造成位置不一致。系统级 DNS 也无法解决浏览器内部的 DNS 预取行为。
DNS-over-HTTPS (DoH)
Chromium 支持 DNS-over-HTTPS,可以加密 DNS 查询。这可以防止你的 ISP 读取 DNS 流量,但 DoH 提供商仍然能看到查询和你的真实 IP 地址(因为在许多配置中 DoH 请求走代理路径之外)。DoH 解决了机密性问题但不解决泄露路径本身。
VPN 级 DNS 保护
VPN 通常将所有 DNS 查询通过 VPN 隧道路由。这对一般浏览有效,但增加了完整 VPN 隧道的开销。对于需要按浏览器或按上下文代理控制的用户,VPN 粒度太粗。
BotBrowser 的方案
--bot-local-dns 标志
BotBrowser 的 --bot-local-dns 标志(ENT Tier1)启用浏览器引擎内置的本地 DNS 解析器:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-local-dns
此标志在网络栈级别控制 DNS 行为,这意味着:
- 所有 DNS 查询在本地处理。 没有查询到达你的 ISP 解析器。
- DNS 预取遵守代理配置。 推测性查询不会泄露。
- WebRTC 和其他协议不能触发不受保护的 DNS 查询。 保护覆盖所有网络路径。
- 对网站不可见。 从页面的角度来看,DNS 行为没有可观察的差异。
何时使用 --bot-local-dns
--bot-local-dns 标志在以下情况下最有价值:
- 你的代理提供商阻止或重写 DNS 查询
- 你需要跨多次运行的一致 DNS 行为
- 你希望避免提供商端的 DNS 策略
- 你使用的是 SOCKS5(而非 SOCKS5H)代理,希望防止本地 DNS 解析泄露
与其他网络保护结合
对于全面的网络隐私,将 DNS 保护与代理和 WebRTC 设置结合:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-local-dns \
--bot-webrtc-ice="google"
此配置关闭了所有三个主要网络泄露路径:HTTP/HTTPS 流量通过代理,DNS 查询在本地解析,WebRTC ICE 候选受到控制。
配置和用法
基本 CLI 设置
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-local-dns
Headless 服务器部署
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-local-dns \
--headless=new
Playwright 集成
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy:1080',
'--bot-local-dns',
'--bot-webrtc-ice=google',
],
headless: true,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com');
// 验证 DNS 没有泄露
const ip = await page.evaluate(async () => {
const res = await fetch('https://httpbin.org/ip');
return res.json();
});
console.log('Detected IP:', ip.origin);
await browser.close();
})();
Puppeteer 集成
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--proxy-server=socks5://user:pass@proxy:1080',
'--bot-local-dns',
],
headless: true,
defaultViewport: null,
});
const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();
})();
验证
使用 --bot-local-dns 启动 BotBrowser 后:
- 导航到 DNS 泄露测试网站(如 dnsleaktest.com 或 browserleaks.com/dns)
- 运行扩展测试,它会执行多次查询以识别所有解析器
- 验证结果中没有属于你 ISP 的 DNS 服务器
- 确认所有 DNS 查询通过预期的服务器解析
- 检查 DNS 解析器位置是否与你的代理地理区域一致
自动化验证:
const page = await context.newPage();
await page.goto('https://httpbin.org/ip');
const ipResponse = await page.textContent('body');
console.log('HTTP IP:', ipResponse);
// HTTP 请求的 IP 应与代理 IP 匹配
// DNS 查询不应暴露不同的位置
最佳实践
-
始终将 --bot-local-dns 与代理一起使用。 DNS 泄露是代理设置中最常见的隐私缺口。此标志在引擎级别关闭了该缺口。
-
使用 SOCKS5H 提供额外保护。 将
socks5h://与--bot-local-dns结合使用提供了两层 DNS 泄露防护。 -
与 --bot-webrtc-ice 结合使用。 DNS 和 WebRTC 是两个最常见的网络级泄露路径。同时关闭两者以实现全面保护。
-
使用扩展 DNS 泄露测试进行测试。 快速测试可能无法捕获所有泄露路径。执行多次查询的扩展测试更加彻底。
-
在 CI/CD 中监控 DNS 行为。 如果你运行自动化管线,将 DNS 泄露验证作为测试步骤以尽早捕获配置错误。
-
不要将系统 DNS 工具与 BotBrowser 混合使用。 如果你在
--bot-local-dns旁边配置系统级 DNS 设置,交互可能产生意外结果。让 BotBrowser 处理 DNS 解析。
常见问题
--bot-local-dns 在没有代理的情况下能工作吗? 可以,该标志无论代理配置如何都启用本地 DNS 解析。然而,没有代理时你的真实 IP 在 HTTP 请求中可见,因此仅 DNS 隐私提供的收益有限。
--bot-local-dns 是否影响页面加载速度? 本地 DNS 解析器增加的开销极小。在某些情况下,它可能比通过 DNS 服务器慢或地理距离远的代理提供商路由 DNS 查询更快。
我可以将 --bot-local-dns 与 HTTP 代理一起使用吗? 可以。该标志与所有代理协议配合使用:SOCKS5、SOCKS5H、HTTP 和 HTTPS。
--bot-local-dns 使用什么 DNS 服务器? 本地解析器在浏览器引擎内部处理 DNS 解析,避免操作系统级 DNS 查询。具体的解析策略在内部管理以保持一致性。
--bot-local-dns 是否防止 DNS 预取? 是的。所有 DNS 解析,包括预取和推测性解析,都通过本地解析器。没有 DNS 查询通过预取路径泄露。
我可以将 --bot-local-dns 与浏览器级 DoH 结合吗?
不建议。--bot-local-dns 标志提供全面的 DNS 控制。在其上添加 DoH 可能创建冲突的解析路径。
使用 SOCKS5H 时还需要 --bot-local-dns 吗?
SOCKS5H 已经通过代理路由主机名解析。然而,--bot-local-dns 对 DNS 预取和 SOCKS5H 可能无法覆盖的其他推测性解析路径提供额外保护。
总结
DNS 泄露是一个常见且严重的隐私缺口,即使所有 HTTP 流量都通过代理路由也会发生。BotBrowser 的 --bot-local-dns 标志在浏览器引擎级别关闭了这个缺口,确保没有 DNS 查询到达你的 ISP 或你控制之外的任何解析器。结合代理配置和 WebRTC 保护,它提供了全面的网络隐私。
完整的网络保护请将 DNS 泄露防护与代理配置和WebRTC 泄露防护配对。管理具有完全网络隔离的多个身份请参阅多账户浏览器隔离。