有人问 VPN 上有多少台机器,于是状态文件被当作证据摆出来。它回答的是一个更窄的问题:这份快照里有多少个会话,以及服务器路由了哪些虚拟地址。这两个问题之间的落差,正是大多数报告错误的藏身之处,而弥合落差要从读文件自身的表头开始。

快照里究竟有什么

当为该服务器实例配置了状态输出时,文件会按固定间隔写入,所以它是一张周期性画面,而不是实时流。它的各个段落分别列出会话和内部路由状态,格式版本决定列的布局。

status /run/openvpn/office.status 30
status-version 3

版本 3 写入以制表符分隔的字段,并带一行表头;更早的格式与此不同,更晚的版本还可能增加字段。应当读表头,而不是把列号写死,因为按位置假设的脚本会在下一次升级时悄悄出错。

RecordWhat it describesWhat it cannot tell you
Client listA session in this snapshotHow many people or machines that session represents
Real addressThe outer peer address and portWhich device is behind it
Routing rowsVirtual addresses and route ownershipWhich downstream hosts are alive

统计会话,而不是人数或机器数

一条站点连接可以承载其背后多台已授权机器的流量。一个人也可能同时从笔记本和手机持有不止一个会话。这两种情况都不会体现在计数里,所以只有先定义单位,“已连接用户”才有意义。在任何人开始计数之前,先问清报告需要的是哪种单位。

如果这个数字对许可或容量有意义,就把单位定义在与报告相同的文档里。一份没有说明统计的是会话、身份还是设备的报告,会被读成读者原本以为的那种单位。

外部地址不是标识

真实地址字段是服务器所看到的对端地址和端口。多个客户端位于同一个经过转换的公网地址之后,会共享该地址,因此按它分组会把互不相关的会话并在一起。端口也会在连接之间变化,使这个组合无法作为稳定键。这样分组的报告看起来很精确,却是错的。

分组应使用有效的客户端身份,而把地址当作传输层的细节。当两行共享同一身份时,通常意味着并发会话,而不是重复记录。

路由行不是主机清单

一条路由项可以指向某个对端负责的子网,而子网并不是其主机清单。服务器知道应当把该网段发往某个特定会话,却完全不知道那些机器中哪台开着、哪台通过了应用认证、哪台对人有用。路由表描述的是可达性,不是占用情况。正是这一差别,决定了 VPN 无法回答资产清单式的问题。

多行也可能指向同一个对端,因为一个站点可以通告不止一个网段。把行数当作设备数,会用任意倍数高估部署规模。

如果需求确实是资产清单,就使用拥有该网络的那套清单流程。VPN 能识别哪条路由由哪个对端承载,这与背后存在哪些主机是两件不同的事实。

时间、权限与实时视图

每次回答都要附上文件的修改时间。几小时前就停下的服务器会把最后一份快照留在原处,而把过期文件当作当前状态来呈现,比没有报告更糟。

目录必须存在,并且服务实际运行所用的账户要能写入,这一点在加固之后很容易被忘记。文件通常包含名称和地址,所以要放在管理位置,而不是 Web 服务器能对外提供的任何地方。权限要从服务账户去检查,而不是从你自己的 shell 检查。悄悄停止更新的快照,看起来和一张安静的网络一模一样。

对事件驱动的需求,应使用受支持的管理接口,而不是加快轮询。把那个接口当作控制面而不是指标,也绝不要仅仅为了统计会话就把它暴露到互联网上。

相关文章