4G 上的分支 VPN:IP 变化时保持身份稳定
移动分支会更换地址,却不会改变自己是谁。在中心端固定 IKE 身份,让分支作为发起方,然后测试一次真实的地址变更。
从分支自身开始,在 4G 路由器的 WAN 状态页面上。如果你看到的地址落在运营商的私有地址段而不是公网段,那么那台设备上任何端口转发都永远无法让中心端向内拨号,隧道只能从分支向外建立。仅凭这一项观察就能决定设计。剩下的工作是确保中心端用来识别分支的东西,比一个每隔几小时就变化的地址更可靠。
隧道必须从哪里开始
把这个地址和运营商用于自身 NAT 的共享地址空间 100.64.0.0/10 对照,也对照常见的私有网段。在移动上行链路上看到其中之一,通常意味着运营商级 NAT 位于分支与互联网之间,入站连接无论分支出什么价都拿不到。当 WAN 地址是公网但会变化时,你面对的是另一个更容易的问题。
动态 DNS 只在第二种情况下有用。它给一个会变化的公网地址一个稳定的拨号名称,却无法创造运营商从未提供的映射。对公网情形仍然值得配置,因为它省掉了重新编号时唯一需要手工完成的一步。它绝不能变成这样一种答案:用来解决运营商从一开始就没有使其可达的分支。
把拨号的地址与匹配的身份分开
中心端需要一个稳定的可被找到的对象,一条获批的固定地址,或一个有人维护的主机名。分支需要一个稳定的被识别方式,在 IKEv2 中那就是它在认证时出示的身份载荷,与它的数据包碰巧携带的源地址无关。像 @branch-a.vpn.example 这样的字符串即便移动地址每小时都变,也能充当那个身份。
这个字符串是与策略比对,而不是通过 DNS 解析,所以不要在建立隧道时指望发生查询。中心端的配置必须明确写出预期的身份,而在证书认证下,身份还必须与证书实际声明的内容一致。
因为源地址看起来合理就接受任意身份,正是要避免的失效模式。在响应方那一侧,这意味着用一个身份通配符和一个共享密钥接受任意对端,那认证的是一个字符串,而不是一台设备。
把中心端写成具名对端
用 strongSwan 的说法,响应方一侧是带 right=%any 的连接,它接受来自任意源地址的对端,再加上 [email protected],它钉住该对端必须声称自己是谁。为分支的各个 LAN 加上 rightsubnet=10.20.0.0/16,让连接在不被拨号的情况下加载用 auto=add,用 dpd_delay=30s 维持存活,用 mobike=yes 让地址变更被吸收,而不是被当作一个新对端。
其他厂商用不同的名称表达同样的对象,通常是带身份字段和受保护子网字段的动态或分支机构对端类型。两个字段都要填,而一个通用的动态勾选框不是兼容方案。
让分支保持为发起方
在分支上是镜像做法:用 left=%defaultroute 让本地移动地址照现状使用,用 [email protected] 出示身份,用 right=hub.example.com 指定稳定的中心端名称,用 auto=start 让隧道无需人工介入就能起来。当移动链路重新连接时,分支重新发起,中心端把同一个身份与同一个策略对象比对。
在两侧都放行 UDP 500 上的 IKE、UDP 4500 上的 NAT 穿越,以及随后的封装 ESP。然后让它们一直保持放行:一条只在办公时间开放的规则看起来就像一条时断时续的隧道。
测试地址变更,而不只是第一次握手
把隧道建立起来,确认它,然后用一分钟开关移动数据或飞行模式,迫使分支换到新地址。观察中心端上的安全关联列表,检查对端地址变了而身份没变。一条只能撑到运营商第一次重新分配地址的隧道,等于完全没有测试过。
然后单独检查受保护子网。一条已建立的 SA 只说明对端通过了认证,并不说明中心端有到分支 LAN 的路由,也不说明分支接受来自中心端一侧的流量。分别读取路由表和防火墙策略,然后从主机而不是从网关发起 ping,因为网关是任何网络中最不具代表性的设备。
稳定的身份把分支变成中心端可以点名的一个策略对象。它并不能让运营商 NAT 地址变得可达,也不会因此就把分支的访问权授予组织里的其他部分。