DNS 解析器日志和 VPN 连接日志都是网络记录,都有用,而且不能互相替代。解析器接收的是被要求应答的域名。VPN 端点处理隧道连接,并记录其实现选择记录的内容。它们可能位于同一栋楼、由同一团队运营、被同一份隐私声明覆盖,但仍然描述着标识不同、留存期限不同的不同事件。把其中一个当作另一个来读,正是调查跑偏的原因。

两份日志,两种事件

解析器条目回答的是命名问题:这个客户端在此刻请求了这个域名,答案就是这个。VPN 条目回答的是连通性问题:这个对端建立或失去了隧道,被分配了这个地址,并在离开前传输了大约这么多数据。两者都不是用户在 HTTPS 会话内部做了什么的记录,也互不替代。

这一区别对承诺有实际后果。说某 VPN 服务商不记录隧道活动,对它分发的解析器只字未提;而解析器的留存策略,对谁连接了隧道也只字未提。每项声明都属于各自的运营方和各自的系统。

读任何一份日志之前,先追踪查询走了哪条路

只有当路径确实向解析器发问时,查询才会到达解析器。应用可以使用操作系统的解析器、运行自带的加密 DNS 客户端,或者读取缓存中的答案而什么都不发。因此,一份什么都没显示的解析器日志并不是某个域名从未被使用的证据,而是这个解析器没被问过的证据。

resolvectl status
dig @127.0.0.53 build.corp.example +qr
journalctl -u systemd-resolved -n 20 --no-pager

最后那条命令读的是本地解析器自己的日志,与上游服务器的日志并不相同。如果你的查询经 DNS over HTTPS 发往某个服务商,本地存根可能什么都不显示,而服务商那边有完整记录,并且服务商是另一家政策不同的运营方。

每份记录能显示什么、不能显示什么

RecordTypically showsDoes not show
Resolver logQueried name, client address, time, responseWhich page was fetched, or what the tunnel did
VPN connection logPeer identity, assigned address, connect and disconnect times, volumeWhich name the application asked for
Application or proxy logRequests, status codes, sometimes full URLsResolved addresses for every dependency

真正的功夫在于把两者关联起来,而关联并不总是可行。记录客户端地址的解析器,可以与从已知地址池分配地址的 VPN 做比对,这种比对会在被查询的域名与某条隧道之间建立看似合理的联系,但那仍然是两份记录之间的联系,而不是关于某个人的记录。

加密 DNS 改变的是传输方式,不是端点处的可见性。解析器仍然会收到它所回答的问题,正如 RFC 8484 明确指出的那样,而该解析器是否留存,是政策决定而非协议属性。

分割 DNS 与缓存如何把故事搅乱

多个解析器是常态。分割 DNS 的设计把内部域名送往内部服务器,其余送往公共服务器,于是一次调查可能牵涉两份从未打算合并的日志,以及两套从未打算对比的留存设置。两边都能看到查询,说明设计在工作,而不是泄漏的证据。

缓存则朝相反方向起作用。热门域名可能连续数小时由缓存应答,于是解析器记录只显示第一次查询,之后什么都没有,而用户的应用程序仍在愉快地解析同一个域名。某段时间之后没有条目,并不意味着那之后没人用过这个域名。

背景流量是第三种失真。开机时解析遥测域名的手机、解析搜索建议域名的浏览器、每小时报到一次的更新程序,都会出现在解析器日志里,就挨着你真正关心的那个域名。那份日志里的数量不是注意力,数查询次数也不是数访问次数。解析器日志是问题的记录,而问题是廉价产生的。

把留存问题分开来问

对每个系统问三个问题:谁收集、收集什么,以及保留多久。然后再问谁能读、按什么流程读。RFC 8484 关于 DNS over HTTPS 的讨论很好地提醒我们:加密传输并没有取消端点,而运营方自己的文档,才是关于该端点保留什么唯一可靠的说明。

当有人就隐私对「VPN」作出声明时,先把它拆成几部分再接受:隧道运营方、隧道分发的解析器、这些查询抵达的任何上游解析器,以及设备上的应用程序。每一部分都有自己的答案,而只对其中一部分成立的说法,常常被当作覆盖了全部四个来重复。

排障时也用同样的拆分。先问是哪个应用发起了查询、哪个解析器给出了答案,然后去看真正拥有该事件的那份日志。从另一份日志去猜,省下一分钟,却赔上一个下午。

相关文章