域名前置不是 VPN:两个名字,一个请求
一个 HTTPS 请求里的两个名字并不是隧道。前置取决于服务商的路由规则;VPN 选择哪些数据包通行。请把两者分开画。
这两种技术被归在同一类,是因为二者都涉及中间方,而且听起来都像在隐藏。但它们作用的对象不同。域名前置关心的是一个 HTTPS 请求中哪个名字出现在哪一层。VPN 关心的是哪些数据包走特定路径到达对端。把前置称作一种 VPN,会导致无法工作的设计,也会让评审问到错误的问题。
两个名字,两层
一条 TLS 连接可以在握手中携带服务器名。连接建立之后,HTTP 请求会指明它想要的权威,通常写在 Host 头里。这是两个字段,由两个不同的软件在不同时刻分别读取。
| Layer | What carries the name | Who reads it |
|---|---|---|
| TLS handshake | Server name indication | The TLS terminator in front of the service |
| HTTP request | Authority or Host header | The routing layer that picks a backend |
| Network path | Destination address and port | Routers, and the VPN peer if one is in use |
域名前置利用前两者之间的差异,让前置服务接受连接,然后把请求改投别处。它只在该服务愿意改投的地方才成立,这属于服务商的策略问题,而不是协议花招。
前置取决于服务商,而不是技术本身
作为一个有边界的例子, Azure 的 Front Door 常见问题 记录了域名前置的防护措施。它说明:同一订阅内以及已配置路由内的域名存在被允许的不一致;当不一致防护拦下请求时,会返回 421 Misdirected Request。
这一条有据可查的策略同时推翻了两个口号。并非每一对不同的名字都能用,也并非每一处不一致都被禁止。其他服务各有各的检查、各有各的部署要求和错误码。
它也不是绕开另一个网络限制的操作指南。读服务商的路由规则、弄清它允许什么,属于架构工作;把那些规则当作绕过配方,是另一类活动,后果也不同。写文档时请把这两件事分开。在评审中被否掉的,正是第二件事。
VPN 究竟选中了什么
在网络型 VPN 中,路由与平台策略会为通往对端的隧道挑选内部流量。视部署而定,它可能覆盖若干应用或某个界定过的子集,也可以承载完全没有 HTTP 请求的协议。
前置这些都不做。借前置服务安排一个 HTTPS 请求,不会装上专用网络路由,不会承载任意 UDP 应用,也不会让设备上每个程序都走该服务。如果需要那种覆盖面,你需要的是代理或隧道,而不是命名花招。
这就是两者在评审中被混淆的原因:二者都被描述成中间方,又都出现在讲访问的文档里。它们提供的接口完全不同,而且只有一个是网络路径。
可见性不是二元的
比较也不只是隐藏与可见。DNS 查询、目的地址、握手特征、数据包大小和时序,对处于相应位置的人来说都仍然可观测,而观察者能学到什么,取决于他站在哪里。
应用数据在终止它的端点上同样可见。转发你请求的前置服务就是这样一个端点,VPN 对端则是另一个。两种安排都不会让内容对必须读取它才能为你服务的一方变得不透明。
画三个方框
做架构评审时,把 TLS 端点、HTTP 路由服务和最终应用画成三个彼此独立的方框,再把任何 VPN 对端画到别处。选择网页目的地的位置和承载专网数据包的位置不必是同一个系统,通常也不是。
方框分开之后,问题就答得上来:这家服务商接受哪些名字,哪些协议需要承载,哪一方能看到什么。把三者揉在一张图里,得到的是一份没人能实现的设计,以及一场围绕词汇争论的评审。