动态客户端连接和路由都正常,但唯一一个使用固定地址的客户端完全无法访问服务器。防火墙没有任何改动,CCD 那一行看起来也合理。常见原因是第二个参数是按与服务器不同的 TUN 拓扑写的。故障很安静:客户端拿到了地址,服务器也接受了连接,但流量就是不通过。

在 net30 下,该字段是对端地址;在 subnet 下,它是子网掩码。两种形式是二选一,绝不是先后关系。

两种形式并排对比

在传统的 net30 部署中,每个客户端拥有一个 /30 网段:一个网络地址、两个可用地址和一个广播地址。ifconfig-push 接收客户端地址和对端地址,对端就是同一网段中另一个可用地址,由点到点链路的服务器一侧使用。

# net30: client address and its peer
ifconfig-push 10.99.0.6 10.99.0.5
# topology subnet: client address and the pool netmask
ifconfig-push 10.99.0.20 255.255.255.0

在 topology subnet 下,客户端与服务器共享一个子网,同一条指令接收地址和子网掩码。服务器自己的地址来自 server 指令,而不是第二个字段。混用两种形式会让客户端以为自己在点到点链路上,而服务器却把它当作子网主机来路由,或者反过来。这就是子网掩码绝不能与 net30 搭配的原因。

这段配置里的两行都是 CCD 文件中的独立行。一个客户端只会得到其中一行。

读取服务器实际运行的拓扑

要读正在运行的配置,而不是软件包默认值,因为拓扑可能是多年前设定并被一路复制下来的。查看有没有 topology subnet,再检查 server 行如何分配地址。从未提及拓扑的配置,与设置 subnet 的配置并不相同。

然后读取客户端实际收到的设置。它报告的地址、掩码和对端,会告诉你服务器采用了哪种解释。

让固定地址留在动态地址池之外

固定地址必须位于动态地址池之外,否则两个客户端可能拿到同一个地址。在 subnet 拓扑下,nopool 会关闭 server 行上的自动地址池,而显式的 ifconfig-pool 范围决定动态客户端能拿到什么。

dev tun
topology subnet
server 10.99.0.0 255.255.255.0 nopool
ifconfig-pool 10.99.0.100 10.99.0.210 255.255.255.0
client-config-dir /etc/openvpn/ccd

服务器自己占用 10.99.0.1,固定客户端地址位于地址池范围之外。CCD 文件以实际生效的客户端身份命名,而不是配置文件文件名,并且不带额外扩展名。如果启用了 username-as-common-name,通过认证的用户名就是要匹配的身份。两台设备共享同一身份,也会共享这个固定地址,这属于策略问题,而不是路由问题。

核实客户端实际拿到的分配

重新连接目标客户端,并在检查其他任何内容之前确认选中的是哪个 CCD 文件。然后核实地址、掩码或对端,以及返回服务器的路由。在 subnet 部署中显示对端地址的客户端,仍然用错了形式。

更改拓扑会影响每个客户端和每个覆盖项,所以要把它当作迁移,而不是修一个客户端。把静态行改成与现有拓扑一致,通常是更小的改动。server-options 参考文档 记录了辅助指令和针对单个客户端的覆盖项。

相关文章