大多数 Pi VPN 搭建都从服务器教程开始,最后以一台连不上网的手机收场。顺序反了。手机客户端实现的是某一种特定协议和特定的认证交换,服务器必须去匹配这套交换,而不是反过来。先定下应用,就能把一个下午的调试缩短成一份简短的检查清单。

能省下一次重装的顺序

在 Pi 上安装任何东西之前,先写下手机的操作系统和确切的 VPN 应用。这两个要素决定了哪些协议是可行的。客户端应用不会因为某个配置文件里恰好出现一个熟悉的字段,就变成另一种客户端。

配置文件里的共享密钥,或者一个看起来很眼熟的端口号,都不能把一种协议变成另一种协议。认证交换要么与应用实现的相符,要么就会在某个几乎给不出线索的阶段失败。没有任何诊断信息会用大白话告诉你「协议不对」。你得到的只是超时、证书错误或静默重试循环,而这三者看起来都像服务器的问题。

应用一旦定下来,服务器的选择范围就收窄了,后面的搭建也就有了目标。

手机应用实际实现了什么

一份公开发布的客户端列表介绍的是一个应用,而不是一项服务。Android 版 OpenVPN Connect 应用需要一台 OpenVPN 服务器;它本身并不提供服务器端。当配置文件看起来相似时,它也不会因此变成 IPsec 或 L2TP 客户端。

这一点在看旧教程时最要紧。为某个协议写的教程,即使当前应用已经不再支持该协议,仍然能在 Pi 上顺利装好,也仍然会在手机上失败——这读起来像配置错误,而不是协议不匹配。

在选定服务器软件包之前,先查一下应用当前的文档,看它支持导入哪些配置文件格式。读五分钟胜过重装一遍。

四部分约定

记下四件事并把它们放在一起:手机的操作系统与应用版本、Pi 上的服务器实现、认证与信任策略,以及对外的接入点。这四项中的任何一项都可能让另外三项失效。

一次应用升级、一次服务器软件包更换,或者一个新的证书颁发机构,都会打破这个约定,而每次都从手机上看起来一模一样。把这四项写下来,才能让你判断是哪一项变了。

凭据各有各的职责

决定配置文件用的是客户端证书、用户名加密码,还是受支持的组合,并让两端保持一致。服务器的身份和受信任的 CA 材料也必须与客户端愿意接受的内容相符。

CA 的公开证书和它的签名私钥是两个不同的对象。只有公开部分才属于手机配置文件。把签名私钥放到手机上,等于交出了签发身份的能力,这与 CA 存在的目的正好相反。把那个文件当作整个搭建过程中最敏感的对象来对待。

使用服务所支持的导出与导入流程,而不是手工拼装配置文件。手工拼出来的配置文件往往带着只适用于桌面端的指令,手机应用会忽略或拒绝这些指令。

最重要的是,不要为了让一个旧示例连上,就用「接受任何服务器」取代证书校验。那会把一个兼容性问题变成一次认证绕过,而且因为它确实能用,通常会一路活到生产环境。

可达性是另一份契约

手机必须通过真实的上游安排才能到达服务器的对外接入点。家庭路由器的地址转换、过滤以及运营商的 NAT 都夹在两者之间。一个动态 DNS 名称只给接入点一个稳定的名字;它并不创建入站路径。

然后定义客户端连上之后可以到达什么:私有前缀还是完整的互联网出口、它们的转发与回程路径、DNS 行为,以及 IPv6 是否在范围内。一次成功登录并不能证明其中任何一项。

直接验收目标手机和配置文件,包括检查未获授权的资源仍然不可达、以及吊销确实移除了访问权限。用桌面客户端成功,验证的是那台桌面客户端,而不是你手里的手机。OpenVPN Connect 的商店页面就是一个具体的例子:它是一款期待配套服务的客户端应用。

相关文章