公共 VPN 配置突然失效?先读失败卡在哪一步
下载来的配置文件只描述某一时刻的一台主机。先看是哪条断言断了,再核对对端出示的证书,永远不要关闭验证。
周二还能用的配置,周五客户端转了三十秒就放弃。你的机器上什么都没变。问题恰恰在这里:下载来的配置只描述某一时刻的一台主机,而另一端的运营方没有义务让这个描述一直成立。诱惑是先去改安全设置,直到隧道重新连上。正是这个本能,让很多人最后跑着一份关闭了证书验证的配置,那比干脆没有隧道更糟。
文件描述的是一个时刻,不是一份合同
配置文件是一组断言:这个主机名在这个端口上用这个协议监听,出示与这个名字匹配的证书,并接受这组凭据。其中任何一条不再成立,文件就过期了,修复属于边界另一侧的运营方,而不在你的设置里。
公共节点列表 的性质本身就说明了这一点。节点由志愿者运行,出现又消失,地址被回收,端口被它所处的网络封锁。列表是不断重新生成的快照,而你磁盘上的副本只是更早那份快照的照片。
商业服务变化更慢,但并非不变。证书颁发机构会轮换,监听地址从共享地址搬到独立地址,旧协议被退役,新的加密套件清单上线。这些变化在你客户端尝试连接、并得到与文件预期不同的回答之前,都是看不见的。
动设置之前,先读失败停在哪一步
错误信息会告诉你是哪条断言断了,而每条断言的修法完全不同。主机名都解析不出来时去改加密套件,只会浪费一个下午,谁也教不会。
| What happens | The assertion that broke | Supported response |
|---|---|---|
| Name never resolves | The host still exists under that name | Get a current endpoint from the operator |
| TCP connect times out | The listener is on that port and reachable | Check the current published port, then the local network |
| TLS or key exchange fails | The peer presents the expected identity | Compare the certificate, not the cipher list |
| Authentication rejected | The account is still valid | Get credentials reissued or stop using the service |
dig +short vpn.example.net
curl -sS -o /dev/null -w 'connect=%{time_connect} tls=%{time_appconnect}\n' --max-time 8 https://vpn.example.net:443/
openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -brief </dev/null中间那一行区分被封锁的路径和握手失败,第三行显示实际出示的证书的签发者与有效期。如果签发者不是配置文件里固定的那个,证书就变了,客户端侧任何选项都无法让旧的固定重新正确。
证书与身份的变化是最安静的那种
大多数故障会自己喊出来。身份变化不会,因为固定了证书名的客户端会拒绝一张完全正常的新证书,而它给出的信息常被读成程序出错。隧道没问题,是固定过期了。
下结论之前,先找身份相关的选项:
grep -nE '^(remote|proto|auth|verify-x509-name|tls-crypt|key-direction|ca) ' profile.ovpn
openssl x509 -in profile-ca.crt -noout -subject -dates如果配置里带着内嵌的 CA,而运营方已经换到新的机构,旧文件无法验证新服务器。用运营方公布的新 CA 块替换旧块是正当修复。删掉验证指令不是,那几下按键一模一样,结果却完全不同。
客户端升级也可能在运营方毫无改动的情况下产生同样的症状。以前被默默容忍的选项现在被拒绝,或者某个已弃用的协议被移除。这是你软件里的兼容性上限,在怪服务器之前,值得用同一个客户端试第二份配置。
只有运营方能发布有效的替代
节点消失时,替代必须来自发布原件的同一个来源。有人发来一份配置、理由是「用的是同一个服务器名」,那只是来自陌生一方的未经验证的配置,导入它就等于把路由的控制权交给对方。
检查很便宜。从公布的位置取回当前文件,把端点和协议与列表对照,并确认 CA 材料的指纹,而不是相信文件名:
curl -sS -o current.ovpn https://example.org/nodes/current.ovpn
sha256sum current.ovpn profile.ovpn
grep -nE '^(remote|proto) ' current.ovpn两个哈希只在空白上不同,那是格式变化。在端点上不同,说明运营方动过东西,公布的文件才是权威。如果公布的文件比手里的旧,你多半看到的是缓存,过期的答案会把你带向错误的方向。
让旧条目退役,并把发生了什么记下来
确认替代可用之后,删掉旧配置,而不是留作后备。半连不上的旧条目是个陷阱:它会在故障时被选中,会慢慢失败,排查的人前十分钟都花在错误的文件上。
在配置之外留一条简短记录:日期、旧端点、失败阶段,以及被什么替代。公共节点换得快,六周之后同样的问题会由另一个人提出来。笔记文件里的一行就能在几秒内回答它。
如果从某个网络每个节点都以同样方式失败,而从另一个网络一个都不失败,那就别再改配置,去看本地链路。强制门户、被过滤的端口段或者做拦截的代理,会在互不相关的服务商身上产生一模一样的错误,而这个模式正是唯一说明问题从来不在文件的信号。