重新连接 OpenVPN 客户端:三种控制,三种范围
断开一个会话、通知所有 UDP 客户端和重启守护进程是不同的操作。先确定范围,再验证新会话。
有人要求重新连接 VPN 客户端,而这个请求可能意味着三件不同的事。它可能指断开一个已认证的会话,通知每个客户端某个 UDP 服务器即将下线,或者重启守护进程本身。每种做法的影响半径不同,选错会把针对单个用户的修复变成一次服务中断。范围就是决策,命令随之而来。
在追问用哪种控制之前,先问清楚应该影响谁。
单个实例:管理接口
配置好的管理接口可以列出已连接的实例,并精确断开其中一个。每个会话都有一个客户端标识符,而 client-kill CID 针对的是该标识符,而不是通用名称。要从当前状态输出中读取仍然有效的标识符,因为从旧日志里复制的值指向的会话已经不存在了。断开该实例只会结束那一个连接,不涉及别的。
它并不保证会有新连接。客户端是否回来取决于它的重试设置、剩余的远程条目、认证要求,以及监控应用是否仍在运行。重新回来的客户端会得到新的标识符,所以说,比较标识符是区分新旧会话唯一可靠的方法。
UDP 退出通知不是针对单个客户端的命令
explicit-exit-notify 是一条关于退出和重启事件的配置指令。在 UDP 客户端上,它告诉对端会话正在结束,数字参数控制通知重复的次数。当服务器通过 UDP 运行时,它会向已连接的客户端发送重启控制消息,而文档中给出的取值区分了重新连接同一台服务器与切换到另一个远程条目。这是一个受众广泛的生命周期信号。
其中没有任何东西会在任意时刻选中任意客户端。把它当成重连按钮,会同时触及所有已连接的会话。
信号作用于进程,而不是会话
SIGUSR1 要求正在运行的进程在不重新读取配置的情况下重启连接,而 持久化选项决定这次重启能保住什么。SIGHUP 走得更远:它会重新读取配置文件并重新打开资源。SIGTERM 和 SIGINT 请求有序关闭。这些是进程级操作:在多客户端服务器上,它们影响该进程承载的每一个会话,而不是工单里点名的那个。
当进程由服务管理器托管时,使用管理器自身的控制方式,而不是向进程列表里找到的 PID 发信号。请阅读 unit,看清管理器发送的是哪个信号,因为重启和重载对同一个守护进程做的事情并不相同。
先确定范围,再选择控制方式
三个问题就能定下来。应该影响谁:一个用户、一台服务器的所有客户端,还是守护进程及其承载的一切。要保留什么:配置、隧道状态,还是都不要。谁有权操作:管理集成、服务所有者,还是控制退出通知的网络运维。回答了这些,只有一种控制方式合适。
为了得到一个重连按钮而增加未经认证的控制监听器,等于把远远多于那个按钮的东西交给任何能访问该端口的人。
验证新会话,而不是断连
断连事件只能证明旧会话结束了。它完全不能说明新会话是否完成认证、是否拿到地址、是否装好路由、是否到达用户需要的资源。请依次检查新标识符、隧道状态,以及一个真实资源。这三步就是重连和真正可用的连接之间的差别。
把范围写进变更记录。当客户端只是共享服务器上四十个中的一个时,我重连了客户端算不上描述。