为什么 OpenVPN 的 /24 比你预想的更早耗尽客户端
在 net30 下每个客户端占用一个 /30,因此 /24 大约在 64 个客户端处到顶。数清分配数量,找出真正的拒绝原因,再从地址规划出发重新确定池的大小。
建立在 /24 上、到六十来个客户端就不再接受连接的池,是按设计在运行,并没有撞上许可上限。在 net30 下,每个客户端都会被分配到一条两端各有地址的虚拟点对点链路,它消耗四个地址,所以 256 个地址的子网只能支撑前缀所暗示的大约四分之一。真正要看的数字是分配数,而不是地址数。把前缀读成客户端数量,正是让人去寻找隐藏用户上限的那个错误。
两种拓扑、两种算术模型,而只有一种与人们默认的前缀相符。
net30 为每个客户端花费四个地址
net30 为每个客户端分配一个 /30 块,因为每个会话都被建模为两端各有一个地址的点对点链路。那个块里放进四个地址,其中两个可用,所以有效客户端数是子网的四分之一。在 /24 上,扣掉服务器自己那一块和任何固定分配之后,只剩 64 块。报告的 63 左右的上限是算术暴露出来的结果,而不是配置的最大值。
服务器也需要自己的分配,而静态客户端条目无论这些客户端是否连接都要占用块。两者都会在不改变你最初那个前缀的前提下压缩动态范围。
池的边界比前缀更重要
服务器指令可能定义一个比它所声明的子网更窄的池,辅助脚本还可能展开成你打开的那份配置里看不见的额外设置。来自 client-config 目录的固定地址就落在那个范围里,不能发放两次。前缀只描述可能的最大空间;正在运行的配置实际提供的才是有效池。
在对容量下任何结论之前先把两者比一比,因为更小的已配置范围同样能解释这个上限。
找出真正拒绝客户端的那条限制
先读拓扑和有效池,再把固定分配和保留地址算进去。在怪罪地址空间之前,检查 max-clients 以及 OpenVPN 之外的任何准入控制。最后,把服务器在拒绝那一刻自己给出的消息与这些候选限制对照。消息会点名约束,数量只是缩小范围。
带并发错误的拒绝和带分配错误的拒绝修法不同,在两者之间猜测只会浪费一个维护窗口。
切换拓扑会改变地址规划
切换到子网拓扑让每个客户端得到的是一个地址而不是一个块,当前缀确实太小时这是正确的一步。它还会改变客户端地址参数的含义,所以每一条钉死的分配和每一个客户端专用文件都必须重新推导,而不是手工重新编号。规划新范围、迁移静态条目,并更新引用它们的路由。
这次切换不是旧配置的同义词。把它当作一次带有自身评审的地址规划变更,并预期至少有一个客户端仍保留上一套方案中的地址。
从规划而不是从掩码确定池的大小
按并发客户端数量加上重连与测试的余量来选择大小,然后在所选拓扑下选取能覆盖它的最小前缀。为了解决六十个客户端的上限而扩到 /16,是用路由和重叠问题换掉容量问题,因为更大的私有范围更容易与客户端已经能访问到的东西冲突。
把拓扑、池、固定分配以及由此得到的客户端上限一起记录下来。这样下一个容量问题就成了算术,而不是一次排查。