名称需要不会移动的地址,而 OpenVPN 的 pool 文件只是让地址变得黏着。一旦丢失那个文件,或以另一个通用名重新签发证书,返回的客户端就会落在 pool 中的别处,而它的 DNS 记录仍然指向旧地址。持久的答案是按客户端设置 override 来固定地址,再加一个更宽的隧道网段,让固定的地址位于动态范围之外。那次扩大背后的算术,正是大部分混乱所在之处。

OPNsense 把这些 override 保存在服务器的客户端专属设置中,以证书的通用名为键,这就使通用名成为地址规划的一部分。

黏着的租约不是静态地址

pool 文件写入地址到客户端的映射,并在已知客户端重新连接时把它们交还。这是便利而非契约:文件可以重新生成,客户端身份改变时映射就会消失,而共享同一个 pool 的两台服务器不会对此达成一致。按客户端设置的 override 则不同,因为地址来自配置而不是历史。只要 override 随其余配置一起备份,它也能在设备重启和重装之后保留下来。

动态的替代方案,即用 client-connect 脚本和动态更新把 VPN 接入 DNS,确实可行,但需要一个接受更新的解析器,外加每次连接都要执行的脚本。在专用设备上,你只能使用厂商提供的软件包,通常计划就停在那里。

没人喜欢的 /30 算术

在默认的 net30 拓扑下,每个客户端都有自己的 /30:第一个可用地址给服务器一侧,第二个给客户端。因此 override 必须位于服务器动态隧道网段之外,这意味着要先把该网段扩大。位于 10.8.0.0/24 的服务器可以改到 10.8.0.0/23,把旧网段的一半留给动态客户端,另一半留给 override。把原来的 /24 作为附加 IPv4 本地网段加入,好让通往两半的流量都进入隧道。

每个 override 地址都必须落在 /30 的边界上,所以最后一个八位组是四的倍数。10.8.1.0 上的 /30 给客户端 10.8.1.2,DNS 记录携带的正是这个地址。若改选 10.8.1.3,客户端能连上却无法转发流量,因为该地址属于拓扑从未分配给它的子网。

如果从扩大后网段的上端向下分配 override,方案就更容易维持,动态 pool 会向空白处扩张,而不是绕着固定的孤岛扩张。

本地网段与客户端查询的区域

客户端之间的流量需要自己的许可。服务器的 IPv4 本地网段列表必须包含网段的两半,动态和静态;否则服务器接受来自一个客户端的数据包,却没有允许它通过到另一个客户端的策略。症状看起来像 DNS 故障,因为名称能解析,连接却仍然失败。同时检查客户端之间的设置,因为仅有本地网段条目并不会启用对等端之间的转发。

把记录发布在远程客户端实际查询的区域。只由 LAN 解析器提供服务的区域里的记录,对推送解析器指向别处的客户端是不可见的,而往错误的区域添加更多记录永远修不好这一点。在添加任何东西之前,先确认 推送的 DNS 选项和搜索域。

新连接上要检查什么

重新连接客户端,并在测试其他任何东西之前确认分配的地址与其 override 一致。然后从第二个客户端解析名称并按名称连接服务,这会一并检验 DNS 记录、路由和防火墙。在服务器一侧确认回复路径,因为名称能解析而服务仍不可达,是路由或策略问题,而不是命名问题。把 override 表放在证书列表旁边,好让两者一起接受检查。

以另一个通用名重新签发的证书不再与其 override 匹配,并会把客户端送回动态 pool。任何身份变更之后都要预料到这一点。

相关文章