用户双击 OpenVPN 的图形界面,确认 UAC 提示,并在下次重新连接时重复同样的流程。这个提示并非打包失误:客户端要创建虚拟适配器并修改路由表,两者都属于需要特权的改动。真正值得问的是,用户到底需要其中哪些权限。用服务加一项范围很窄的委派,就能覆盖连接,而不必发放管理员成员身份。

哪些操作才真正需要提权

隧道终止在一个虚拟网络接口上,而安装这个接口是一次性需要管理员权限的驱动操作。适配器存在之后,每次连接仍会写入路由,并视配置档案修改 DNS 设置。触发普通账户提权的正是这两步。身份验证和加密本身都不需要管理员权限,这也正是可以把这项特权拆分出来的原因。

在选择授权之前,请把安装阶段和连接阶段区分开。两者的负责人不同,生命周期也不同。

把服务当作持权的组件

受支持的方案 是运行一个持有所需权限的 Windows 服务,由图形界面请该服务去连接。这样特权代码就永远不会在用户会话中运行。

sc query OpenVPNService
sc qc OpenVPNService

要确认的第一件事,是有一个正在运行、且其二进制路径指向已安装客户端的服务,然后再谈委派。适配器和路由都由该服务持有,用户只负责启动和停止连接。共享机器上应当采用这种形态,因为点击连接的那个账户不具备常驻特权。请先用 sc sdshow 读一遍描述符再修改,并保留一份已知可用的输出副本。

用内置组委派路由变更

对于必须交互运行的客户端,可委派的内置组是 Network Configuration Operators。它涵盖网络设置和路由变更,但不包含软件安装和一般管理工作。

net localgroup "Network Configuration Operators" alice /add
sc sdshow OpenVPNService

添加账户并不是无声的:默认策略仍会每个会话弹一次提示,所以这项授权只是缩小了提权能做的事,而不是取消提权。请把成员关系记录下来,因为它会悄悄积累,几乎无人复核。在服务方案中,可以用 sc sdset 修改描述符,把启动和停止委派给某个组;不过描述符里的一处笔误就可能让所有账户失去启动权限,而要撤销它又需要管理员。任何描述符改动都应先在实验机上验证,再推向生产主机。

从用户账户验证

在管理员会话里做的配置,并不能证明之后使用它的账户会怎样。请以该用户身份登录、连接,并对比前后的机器状态。

route print -4
Get-DnsClientServerAddress

路由表应当新增隧道路由,连接期间解析器应当指向 VPN 提供的服务器。断开之后,两份输出都应与事先抓取的副本一致,这正是要先抓取的原因。驱动程序更新可能让管理员要求重新出现,所以请把客户端版本记在结果旁边。配置档案和密钥文件应只让使用它们的账户可读,而不是为了共享安装去放宽权限。

写下谁能启动隧道、哪个组授予该权限、以及还有哪些事需要管理员。有了这份记录,下次客户端更新就会变成有计划的活,而不是一个下午的猜测。

相关文章