你发现一个名为 config.json 的文件,里面提到了某个 VPN 服务器,于是立刻冒出一个假设:这一定是 OpenVPN 的连接配置。多数情况下并不是。这个名字的 JSON 文件可能属于启动客户端的桌面前端,也可能属于保存自身设置的守护进程,还可能属于某个产品的导出格式,而每一种都有自己的 schema。

文件名是最没有用的线索。先找到读取该文件的进程,再确认它期望的格式到底是不是 JSON,最后才判断修改这个文件是不是受支持的改动方式。

从进程入手,而不是从文件名入手

看看实际运行的是什么。服务单元、启动脚本或托盘程序会指名它启动的二进制文件,通常还会给出它传入的配置路径。文件所在的目录是第二条线索:应用数据目录、服务配置目录和用户配置目录分别暗示不同的所有者。

然后去读拥有该组件的产品的文档。如果 JSON 属于某个包装层,那么它的键就是包装层的键;照着另一个产品的示例拼出来的、看起来合理的对象,只会被拒绝或被静默忽略。

不同目录下同名的两个文件是常见陷阱。一个可能是服务每次启动都会重写的生成状态,另一个可能是本应由人编辑的模板。改错了那个,得到的修复只能撑到下一次重启。

Community OpenVPN 的配置文件究竟是什么

Community OpenVPN 2.6 读取的是基于选项的文本格式。一个配置文件是一串指令:客户端模式行、设备行、远程端点,再加上身份、加密和路由选项,并且可以把证书和密钥材料内嵌在行内块里。

这种格式由客户端自己逐行解析。通过 config 选项交给它一份 JSON 文档,并不会启用 JSON 解析器;第一行就会被当作未知指令拒绝。把 JSON 文件改名成以 .ovpn 结尾也不会转换其内容;反过来,合法的选项文件也不会因为扩展名不常见而失效。

OpenVPN Connect 和 OpenVPN 3 Linux 有各自的配置导入与管理路径。这些产品可以接收配置文件,并存进自己的数据库或服务状态,这与一个碰巧描述服务器的 JSON 文件并不是一回事。

修改属于另一个组件的状态

如果 JSON 是生成出来的,修改它就是一场竞速。运行中的服务可能在关闭时、重连时或下一次设置变更时把它写回去,手改的结果会悄无声息地消失。优先使用产品自带的导入命令、管理 API 或设置界面,因为这些路径会更新文件所代表的内部状态。重启后回退的文件其实在告诉你哪条路径才是持久的。

如果你确实要改生成文件,先停掉服务、留好备份,并且只做尽可能小的改动。然后检查服务启动时是否会重写该文件,因为启动即回退说明真正的持久状态在别处,这次修改本来就不可能留下。

密码和内嵌私钥是另一个问题。JSON 和选项文件一样可以轻松携带完整密钥,所以任何导出都应视为机密,不要放在共享盘上,在把结构贴到论坛提问之前先遮盖具体值。

验证改动并保护文件

验证不是“JSON 能解析”。解析只能证明括号配对,并不能说明所有者是否认识这些键。要看产品自身的状态:活动配置文件列表、当前选中的连接,以及一次确实用上新值的重连。只出现在列表里却从未成为选中项的文件,仍然不是正在使用的那个。

要盯的是你改过的那个组件的日志,而不只是 VPN 客户端的日志。拒绝你文件的包装层通常会在自己的日志里报告;而根本没收到文件的客户端,看起来和一个收到错误设置的客户端一模一样。

保留可用文件的副本,并记录你测试所依据的产品版本。这些格式会随版本变化,去年能用的结构在升级后可能被拒绝,而错误信息里完全不会提到 schema。

流程小结:确定进程、读它的文档、确认文件到底是不是 JSON、使用受支持的修改路径,并通过产品自身的状态来验证。文件名从来没有回答过其中任何一个问题。

相关文章