按顺序做完这些检查,遇到第一个不通过的就停下,因为每个答案都会改变下一步的含义。真正的问题很窄:ZeroTier 网络里的明文 HTTP 会以明文穿过互联网吗?在两个 ZeroTier 对等节点之间通常不会,因为 overlay 加密了那一跳。但这只是关于两个端点的说法,并不覆盖一个请求经过的每一段路径。路由器、网桥或反向代理会移动端点,在它另一侧,明文又重新开始。

检查 1:找出浏览器拨号的地址

把 URL 和机器实际持有的东西对一遍。ip -brief addr show 会列出 zt 接口和网络控制器分配的 overlay 地址;如果 URL 用的就是这个地址,浏览器的套接字就进入了 overlay。

如果名字反而解析成 LAN 地址,那么无论客户端的状态指示灯怎么说,overlay 可能根本没参与。ip route get 10.147.20.5 会打印内核会选择的接口和源地址,所以那里出现 zt 接口就说明数据包进入了 overlay,而出现你物理网卡的名字就说明没有。名字还会再加一层:指向 overlay 地址的记录和指向 LAN 地址的记录行为不同,搜索后缀或 hosts 文件里的一条记录就可能悄悄决定你拿到哪一个。

检查 2:确认两端都是对等节点,而不是负责解密的转发

ZeroTier 在对等节点之间加密,没有直连路径时数据包会经由一个根节点转发,且转发时仍保持加密。zerotier-cli peers 会把每个对等节点的路径标成 DIRECT 或 RELAY,并附一个延迟数字。被转发的路径多花的是往返,不是机密性。

真正改变答案的,是那种其实不算端点的成员。当远端是一个把流量路由或桥接进物理 LAN 的 ZeroTier 成员时,overlay 就在那个成员处结束,下一跳是普通以太网。

检查 3:看请求在哪里变成可读的

在你认为提供该页面的主机上,重新加载时抓 overlay 接口:sudo tcpdump -i ztxxxxxxx -A -c 5 'tcp port 80'。输出里出现可读的请求行,就证明流量到达该主机时已被解密,而这正是你要找的边界。

然后抓面向 LAN 其余部分的那个接口。如果同一个请求在那里以明文出现,说明它在到达应用之前就离开了 overlay,那段网络上的任何设备都能读到。如果 LAN 一侧什么都没出现,页面却仍然能加载,说明应用就终结在这台 ZeroTier 主机上。

前面有反向代理时,抓 loopback 也很重要,因为接受 HTTPS 再转发 HTTP 的代理会把边界挪到它自己的后端。

检查 4:把路由器或网桥后面的每一跳都算进去

配置成在 overlay 和 LAN 之间路由的成员是常见设计,也正是这些假设最容易破裂的地方。overlay 保护的是浏览器到路由器这一段,之后什么都没有。网桥用另一种机制讲同一个故事:overlay 和物理段变成同一个广播域,所以来自桥接笔记本的请求走的是普通以太网,哪怕那台笔记本就在 ZeroTier 网络上。

与其假设,不如追踪。从客户端到服务地址跑 traceroute,再加上网关成员上的路由表,就能看出最后一跳是 zt 还是 eth。

ZeroTier 还提供 trusted-path 模式,可以为了性能在指定的本地路径上放弃传输层安全。使用它的网络并不继承通常的“路径已加密”假设,所以在引用之前先读网络配置。协议文档既描述了对等节点加密,也描述了那个例外。

检查 5:决定应用还该做什么

overlay 成员身份只把设备认证到网络,并不说明另一端的服务就是你想访问的那个。HTTPS 通过把主机名绑定到密钥,回答的是另一个问题,所以这两种保护相互重叠,却并不互相取代。被授权的对等节点仍可能是错误的服务,而被攻陷的端点既能在加密前读请求,也能在解密后读。这两种机制都不审计应用记录了什么。

凡是带可复用会话或密码的东西,都在应用上或你控制的代理上终结 TLS,并保持证书校验开启。如果某个遗留服务必须留在明文 HTTP 上,就写清它被允许使用的主机到主机路径、谁能访问、哪一段始终没有保护;未来的评审者需要的正是这份记录。

"VPN 已连接"不是对以上任何一项的评估。诚实的说法会点明两个端点、它们之间的路径,以及第一个没有被覆盖的跳。

把抓包输出和对等节点列表放在服务文档旁边,这样任何改路由或加网桥的人都能看到自己即将打破哪个假设。

相关文章