向管理接口问一次状态,它就开始看起来像个状态端口。但它并不是。客户端一旦被接纳,就能发出协议的控制命令,而运行该客户端的账号会继承这些命令对守护进程能做的一切。把它当成只读数据流,正是把监控集成变成未认证控制台的错误。

这种想法,以及它的代价

常见的想法是:管理监听器等同于指标端点——接上一个采集器,读读计数器,然后收工。实际发生的是,采集器打开的是一个带控制能力的会话,于是你对部署的其他所有假设,现在都取决于这个采集器是否守规矩。

接口里没有任何地方声明只读模式。没有可选的观察者角色,配置文件里的一个用户名也变不出这种角色。

被接纳的客户端实际持有的是什么

社区版守护进程同一时间只接受一个活动的管理客户端。这唯一的槽位意味着 GUI、脚本和监控代理无法同时接入;第一个占着会话时,第二个只能等待或失败。如果你的设计假定并发读取,那它已经错了。

在周期性快照就够用的场合,状态文件的输出能在没有实时会话的情况下给你同样的数字。按间隔写这个文件,再用普通文件权限去读,就能把采集器完全挡在控制平面之外,而这正是大多数监控真正需要的安排。

自己拥有的套接字,而不是敞开的

Unix 域套接字让控制路径不经过网络,从而把会变化的隧道地址从问题中移除。但它移不走权限问题。父目录必须对服务账号可写、对控制器的账号可达,而这是两项彼此独立的授权:

management /run/openvpn/office-management.sock unix /etc/openvpn/management.password
management-client-user vpn-observer
management-client-group vpn-observer

密码文件的第一行就是管理密钥。像保护任何其他凭据一样保护这个文件,别让它的内容出现在日志和工单里。用户和组限制是 Unix 套接字上的对端检查,不是文件系统权限,所以目标进程既需要文件访问权,也需要匹配的身份。

为了让权限报错消失就把套接字开放给全世界,是唯一必须避免的修法。它会把一条本地控制通道变成主机上任何进程都能驱动的东西。

通过 TCP 发布并不是同一种设计

把监听器搬到 TCP 端口并不会让它更安全或更方便。管理密码是明文发送的,所以 TCP 监听器会把凭据和会话一起暴露给任何能观察这条路径的人。要从另一台主机访问它,需要一条经过授权的管理通道,或者一个只暴露所需观测数据的小型本地代理。

明文传输上的密码是没有机密性的认证,这种组合比看上去更糟,因为它让人感觉受到了保护。

你并没有要求的启动依赖

有几个管理选项会改变守护进程的生命周期。在控制器连上之前一直压着启动,或者控制器一消失就终止,会把一个可选的观察者变成硬依赖。那样一来,监控代理一崩溃就会把隧道一起带走。

在启用套接字本身之外的任何东西之前,先审一遍这些选项。可选观测就该保持可选,重启策略也不该绑在一个为画图而加的采集器上。

进程失败后留下的套接字文件,并不能证明监听器还在。删除之前先确认这个路径归哪个实例所有,并用服务自带的恢复流程,而不是在运行中的守护进程底下删文件。

验收是什么样子

四项检查覆盖这个设计:预期的控制器身份能连上,没有该身份的进程被拒绝,控制器无预警断开后守护进程仍然存活,隧道在受控重启后仍能承载流量。管理连接成功只能证明控制平面。它说明不了私有应用流量是否正常,所以要单独测试。把这四项结果写在下一个运维人员找得到的地方。

管理接口文档描述了单客户端模型和协议的特权性质,把仪表盘指向它之前,值得先读的就是这一部分。

相关文章