hosts 文件中的一条记录和路由器过滤器以完全不同的原因屏蔽同一个站点,这就是为什么一个在 VPN 下继续工作,另一个却悄悄失效。hosts 文件在任何数据包离开本机之前就回答了名称。路由器过滤器检查经过它的流量。在这两点之间加一条隧道,后者就失去了视野,而前者毫无察觉。

名称在哪里解析决定了一切

每一次屏蔽都始于一个问题:谁把名称变成地址?在普通桌面上,答案是系统解析器,它按配置的顺序查找,通常先读 hosts 文件再查询 DNS。在受过滤的网络上,答案可能是路由器,只有当客户端不加保护地把查询发给它时它才看得到。改变路径,也就改变了谁有权回答。

VPN 在这里同时做两件事:它改变默认路由,也可能推送自己的 DNS 服务器。这两项改变中的任何一项,都足以让名称解析离开原本执行屏蔽的设备。

这就是那句熟悉的抱怨背后的机制:过滤器一直有效,直到 VPN 连上。

hosts 记录在隧道存在之前就给出答案

像 127.0.0.1 www.example.com 这样的一行由本地解析器读取,因此答案在本机生成,不涉及网络。连接隧道、更换 DNS 服务器、切换网络:这条记录仍然返回 loopback。所以 hosts 屏蔽是两者中唯一不受 VPN 终止位置影响的一种。

它的盲区同样是本地的。自带解析器、使用 DNS over HTTPS 或直接连接字面地址的应用从不会询问系统,因此这条记录不会被查询。运行中进程内部缓存的地址也有同样的效果,直到该进程重启。

与其相信浏览器标签页,不如在 Linux 上用 getent ahosts 或在 Windows 上用 Resolve-DnsName 确认答案。

路由器过滤器只看见经过它的流量

家用路由器上的内容或 URL 过滤器匹配以可读形式经过它的名称和请求。当客户端与别处的服务器建立加密隧道时,路由器只看到一条通往该服务器的流,看不到里面的内容。过滤器没有名称可匹配,于是放行流量,这看起来像过滤器失效,而不是被绕过。

有效的拓扑是另一种:路由器自己持有隧道,在端点解密并在那里应用过滤器。在这种设计里,过滤器位于明文出现的地方。

如果隧道终止在笔记本上,那么无论规则怎么写,路由器按定义都在受保护路径之外。

四个执行点以及各自遗漏什么

有四个地方可以执行屏蔽,每个地方的失败方式都不同。请把这份清单当作覆盖范围图,而不是排名。

  • hosts 文件或本地解析器:离线可用,在任何隧道下都有效,但会被自带解析器或写死的地址绕过。
  • VPN 网关上的 DNS 过滤:覆盖使用所推送解析器的客户端,漏掉自行覆盖 DNS 的客户端。
  • 网关按地址或 SNI 的出站规则:不依赖客户端 DNS,但对读不出的名称和尚未学到的地址是盲的。
  • 受管理的浏览器或设备策略:在受管硬件上很强,在个人设备上不存在。

以上没有一项能构成对未受管设备上坚定用户的安全边界。它们是策略控制,诚实的描述应当说明每一项实际覆盖了哪些流量。

选择与意图相符的层次:家庭便利属于设备,组织规则属于网关。

在宣布完成之前测试两种状态

在 VPN 连接和断开两种状态下运行同样的三条命令:用 getent ahosts 看解析器的答案,用 nslookup 看查询返回什么,用 curl -I 访问站点看连接是否仍然完成。如果第一条返回 loopback 而第三条连上了真实地址,说明有东西绕过了解析器,hosts 记录并不是你以为的那个控制点。

在路由器上,读取请求前后的过滤器计数器。完全不动计数器说明流量从未到达过滤器,这是路由层面的答案,不是规则层面的答案。

把结果连同拓扑一起记下来,因为下一次 VPN 变动又会改变路径。

相关文章