从 VPN 服务器上的地址池字段开始,而不是表格。你在那里输入的内容会成为之后每个连接客户端的内网地址空间,并且必须与这些客户端要访问的 LAN、其背后的路由站点以及客户端在家庭网络中已有的地址共存。地址池一保存就连接一个客户端,因为第一次连接才能说明这个取值在实践中是否可行。从那里开始,整个流程向外展开:客户端实际拿到的地址、响应返回的路径,以及你留下的记录。

在任何客户端连接之前,先从地址池字段开始

不同产品的暴露方式不同,所以要找到真正分配地址的对象。OpenVPN 有服务器端的地址池指令,负责发放下一个空闲地址;IKEv2 网关有绑定到对端配置的地址池段落;WireGuard 两者都没有,因为每个对端都在自己的配置文件里携带地址。地址池指令与按对端的地址不能互换,改错对象会让后面的流程全部作废。

拿到字段后,先列出已经存在的网段:办公 LAN、每个路由站点、云上 VPC,以及其他仍在服役的地址池。重叠由前缀运算决定,而不是主机号看起来是否熟悉,所以要把聚合结果与每个网段逐一比对。两个都像 10.x 的网段,聚合不相交就无碍,相交就是一次支持事故。

然后决定地址是谁连接的函数,还是何时连接的函数。动态分配发放空闲地址,而按身份分配把固定地址绑定到凭证。把这个选择写下来,因为它决定以后重连应该是什么样子。

读取客户端实际拿到的地址

连接一个客户端,读隧道报告的结果,而不是地址池承诺的内容。客户端会在连接状态里显示内网地址,在 Linux 上接口则直接承载它。

把这个地址与你保存的网段比对。如果落在网段之外,说明你看到的分配路径不是刚才改的那条。还要检查前缀长度,因为持有 /32 的客户端没有链路上对端,所有目的都走默认路由。

ip -4 addr show tun0
ip route get 192.168.50.20

从使用同一网段的家庭路由器连上来的客户端能连上,却几乎什么都访问不到。客户端会为该前缀保留本地路由,隧道地址与背后的网络冲突,流量从错误的接口出去。这种情况在服务器端无法修复,书面办法是给家庭网络重新编号,或者选一个足够远的地址池网段,让冲突保持罕见。把故障和办法都记下来,因为服务台还会再遇到。

重新连接同一个客户端并观察地址。动态池可能返回相同或不同的值,两者都正确;而按身份的池若地址发生变化,就是没有遵守绑定。这一步只需几秒,却能确认第一节记录的分配方式是否真的在生效。

跟踪服务返回的响应路径

只有响应能回到地址池,地址池才算真正可用。LAN 上的服务回应内网地址,因此它的网关需要一条到地址池的路由,或者在服务前面做转换。当请求经隧道进入、响应却从另一条路离开时,状态防火墙或反向路径检查会把它丢弃,客户端看到的就是连上之后卡住。把地址池作为一个可汇总的整块写进路由设计,而不是逐主机加路由。

转换会改变系统其余部分看到的东西。源地址被改写后,主机防火墙和应用日志里的都是转换后的地址,于是针对地址池地址写的规则一条也匹配不上,日志行也无法追溯到具体客户端。strongSwan 的转发文档覆盖了 IKEv2 网关这条路径的服务器端一半。DNS 也受同一约束,解析到客户端不可达地址的名字会在稍后、在别处失败。

两个客户端,然后一次吊销

同时连接两个客户端并读取两个地址。它们必须互不相同、可用且落在地址池内,各自还要能访问自己该访问的服务。发放重复地址的池通常在这里暴露,而不是在第一次单客户端测试里。

在另一个客户端保持连接的情况下吊销一个凭证,然后从存活的那个客户端试服务。影响另一条会话的吊销指向共享状态,最常见的是一个凭证或一个地址被多台设备复用。重新连接被吊销的客户端,确认它被拒绝,而不是拿到刚释放的地址。

用一个本应被拒绝的目的收尾。能访问一切的客户端只是连上了,并没有被测试过。

把四个取值写在下次变更找得到的地方

记录要短:地址池网段与前缀、分配方式、回程路径或所用转换,以及为这些目的作答的 DNS 范围。把它放在服务器配置旁边而不是工单里,并标注日期。今后改动其中任何一项的人,都需要另外三项摆在眼前,因为池子扩缩会破坏路由,路由变更会破坏 DNS 应答。

同时保留归属说明:隧道网段属于 VPN 服务器,而 在 LAN 的 DHCP 作用域里做的保留不会为隧道内客户端保留任何东西。这一行能挡住最常见的返工——有人加了保留,就以为隧道地址会跟着走。

相关文章