现场设备向某个服务发起连接时,设计问题往往被表述成在 VPN 和 TLS 之间二选一。这种框定是错的,因为两者做的是不同的工作。TLS 验证应用端点并保护会话内容;而 VPN 控制可达性并保护对等方之间的数据包。沿着连接从设备向外逐层查看,每一层都有自己的答案。

如果你说不清 TLS 在哪里终止,也就说不清应用实际信任的到底是什么。

找到 TLS 真正的终止点

从设备上的应用出发,沿连接一路追到完成握手的那个进程。如果代理在主机前端终止了 TLS,那么受保护的路径就止于这个代理。剩下的那一跳需要有自己的、成文的保护措施。

仅凭假设称其为端到端,正是设计评审放过缺口的方式。把终止点和信任锚画在同一张图上。

TLS 在两个方向上承载请求与响应,因此双向通信的应用本身并不一定需要 VPN 来替代 TLS。反过来也成立:同一台设备上的其他协议可能仍然需要 VPN。

确定设备必须验证哪些身份

配置服务器身份校验以及预期的信任根。如果每台设备都必须证明自己的身份,就选择一个受支持的客户端认证模型,并为每台设备登记各自独立的凭证。共享凭证会让一台设备失窃演变成整个设备群的问题。

在出厂前规划好密钥保护、续期、吊销和恢复。现场设备若在一次续期失败后再也无法重新登记,就会变成一次上门服务,而这项成本对设计的塑造比握手更大。

使用受支持的库和当前指南。现代 TLS 部署指南禁止协商 TLS 1.0 和 1.1,旧设计笔记里出现 TLSv1 并不构成要求。

握手失败时要失败关闭

握手失败或身份校验失败时,绝不能悄悄回退到原来的明文协议。这种回退正是 TLS 工作本要消除的漏洞。要让设备操作员和服务端都能看到这次失败,并对敏感操作强制使用受保护通道。然后由应用层的授权来决定已通过认证的设备可以做什么。

把连接生命周期、分帧、超时和重试行为都定义在契约之内。加密并不能让重复执行的命令变得安全,而在前一次操作结果不明之后重试,需要一个应用层面的答案。

把回退规则写下来。"握手失败就在没有 TLS 的情况下重连"是一项设计决策,它应当是明确写出的决策。

只把 VPN 能做的那件事交给它

VPN 可以限制可达性,并保护发往其对等方的数据包。TLS 保护的是应用与所选端点之间的关系。两者的终止点可能不同,而两者都不保护端点存储的数据,也不保护其管理访问。

在真实设备上测量握手开销、稳定状态下的消息收发和重连,而不要假设某种机制更快。然后测试四个关键场景:预期的交互、错误的服务器身份、未获授权的设备,以及一次结果不明的操作之后的重连。记录每个场景的结果,包括设备显示的错误信息。

相关文章