OpenVPN 启动失败,错误信息指向一行看起来没问题的配置:Unrecognized option or missing or extra parameter(s) in office.ovpn:42: ca。证书没有变,文件在编辑器里能打开,路径看上去也没错。解析器并不是在指责选项名,而是在指责随它一起到达的参数个数。四项检查几乎能解决所有这类情况,值得按成本从低到高依次进行。

解析器为什么怪到选项头上

每一行配置在任何选项读到它之前,就先按空白和引号切分。因此含空格的值如果没有被引号包住,就会以多个参数的形式到达,而拥有该行的选项随即报出不匹配。在 Windows 上,默认安装目录让这件事必然发生,因为 C:\Program Files 从结构上就位于路径中间。这种失败下证书根本不会被打开,所以检查文件是否存在证明不了任何有用的东西。

报出的行号通常是对的,报出的选项正是消耗掉该行的那一个。当被点名的选项你确定从没写过时,请读它上面那一行,因为前面某个块里丢了一个引号会整体错位解析。证书块最终背上参数个数的黑锅,就是这么来的。

ca C:\Program Files\OpenVPN\config\office-ca.crt

给每个含空格的路径加上引号

在值两边加一对双引号就是全部修复,而 Windows 接受正斜杠,所以转义永远不必成为问题的一部分。在同一轮里把每个路径选项都改好,因为解析器停在第一个错误上,下一个只是在等下一次重启。这组选项通常包括 ca、cert、key、tls-auth 和 auth-user-pass。

ca "C:/Program Files/OpenVPN/config/office-ca.crt"
cert "C:/Program Files/OpenVPN/config/office.crt"
key "C:/Program Files/OpenVPN/config/office.key"

按目录名搜索比读文件更快找全每一处。动手改之前先跑一遍,让清单完整:

Select-String -Path .\office.ovpn -Pattern 'Program Files'

把配置文件搬到没有空格的路径上也是可行的替代方案,但前提是每个路径都跟着搬。只搬了一半的配置会用另一个文件名重现同样的错误,而且更难发现,因为报错现在指向你刚创建的路径。选一种做法并做到底。

先恢复模式声明,再处理证书

第二种常见原因给出的错误信息不同,浪费的却还是同一个下午。客户端配置必须在靠前的位置声明自己的模式,而当只把证书块粘贴进新文件时,这个声明很容易丢失。没有它,OpenVPN 会以另一套默认值读取文件,问题要很久以后才以选项冲突或登录失败的形式出现。少掉的那一行,检查起来很便宜,忘掉却很贵。

client
dev tun
proto udp
remote vpn.example.net 1194

既然在那儿,就保持一行一条指令。被合并的行会产生和第一节一模一样的参数个数错误,而报出的行看上去很合理,因为合并发生在编辑器折行的位置。要读原始行,而不是渲染后的行。

编码损坏看起来像选项名

以 UTF-16 连字节序标记一起保存的文件会把第一个选项藏起来,让解析器看不到,而游离的字节可能粘到报错里的选项名上。把文件另存为不带字节序标记的 UTF-8,然后重新打开,确认第一个字符是正常字母。编辑器、PowerShell 重定向和从聊天窗口粘贴的文本,都会在无人过问的情况下改变编码。

Format-Hex .\office.ovpn | Select-Object -First 1

字节序标记会以开头的标记字节形式出现在任何文本之前,而手工删掉这些字符是必输的一招,因为编辑器下次保存时会再写回去。改用明确的编码重新保存文件。换行更宽容一些,但结尾没有换行的文件在一次编辑之后,仍可能把最后一条指令并进上一条。

先查哪一项,为什么

从编码开始,因为它只花一条命令,却能让其他所有读法失效。然后是引号,再然后是模式声明和其他必需指令,最后才轮到证书、密钥和凭据。按这个顺序做,每一步都可回退,因为为修引号问题而换掉的证书,会让一套能用的安装多出一个新故障,距离原样只差两次编辑。顺序比单项检查更重要。

保留一份运维方交付时的原始副本。如果后来的编辑把它弄坏,和那份副本做差异比较就能看出是引号、换行还是标记字节动了,这比重新读错误更快。每条指令的选项说明都在已安装版本的 OpenVPN 手册 里。

相关文章