PiVPN 会写一份服务器配置和一份客户端配置,然后退出;它从来不会变成承载你流量的那个进程。因此,握手失败、客户端连到错误端点,或者重启后服务返回异常,都无法从安装脚本的菜单里解释。这些症状属于当下正在运行的那个 OpenVPN 守护进程、它真正加载的配置,以及被指向的那份日志。四条只读命令通常就能定论,而且没有一条会改动你的证书或密钥。

辅助脚本和守护进程是两个不同的对象

困惑很容易解释:同一个目录里放着辅助脚本生成的文件、守护进程读取的文件,有时还有两者的陈旧副本。辅助脚本是一段准备脚本。它装包、写单元文件、打印客户端配置,做完就结束。留下来的是一条服务管理器记录和一行命令。

在 systemd 主机上,从活动单元入手,而不是目录列表。名字取决于打包方式:Debian 和 Raspberry Pi OS 镜像通常提供模板实例,例如 openvpn-server@server;而更早的安装使用 openvpn@server。直接问管理器哪个在跑,不要凭文件名猜。

systemctl list-units --type=service --all | grep -i openvpn
systemctl cat openvpn-server@server

读这段输出里的 ExecStart= 行。它会指出实际被启动的可执行文件和选项,包括任何 --config 路径;旁边放着、却没有任何命令引用的配置文件,并不属于正在运行的隧道。

沿着守护进程解析出的配置链往下走

OpenVPN 不会扫描目录来找设置。它读取通过 --config 传入的文件,跟随其中任何 config 指令,然后应用命令行选项。手册 2.6 描述了这个顺序;当两份文件在端口、设备或加密算法上不一致时,这个顺序很关键。

先把实际调用打印出来,再看决定身份与可达性的那些指令。两条命令都是只读的,在运行中的服务器上安全,只不过第二条会打印你可能不想放进公开工单的路径。

systemctl show -p ExecStart --value openvpn-server@server
grep -E '^(config|dev|proto|port|local|log|log-append|status|ca|cert|key|tls-auth|tls-crypt)' /etc/openvpn/server/server.conf

主目录里的 .ovpn 文件属于客户端产物。服务端守护进程从不读它,所以改这个文件去修服务端握手失败,什么也做不到。

include 是另一个陷阱。一行 config 会把第二个文件拉进来,其中的选项就在那一处被处理,因此后面出现的一条单值指令可能覆盖主文件看起来写的内容。如果看得见的文件没问题、守护进程却仍然表现不同,先读被包含的文件,再动任何东西。

把日志对到进程上,而不是对到你记得的那个报错

日志有两个常见去处,只有一个是 journal。设置了 log-append 时,守护进程写进那个文件,journal 里除了启动行几乎不剩什么。没有它时,journalctl 就是事件来源。

journalctl -u openvpn-server@server -n 80 --no-pager

把一次连接尝试对应到一个时间窗口。记下客户端端点,然后读同一秒的服务端事件。一个从没走到证书交换的 TLS 握手指向可达性或协议不匹配;而认证被拒则发生在隧道参数已经谈好之后。

旧日志条目证明不了你五分钟前下载的配置。重新生成客户端文件,连一次,只读那次尝试期间出现的行。

记下第一个具体失败,而不是最后那个笼统失败。绑定错误、没有回应的外层交换、证书被拒和账号被拒各把你带向不同层次,而末尾的超时常常把上面那条有用的事件盖住。

重建隧道不是诊断步骤

诱人的捷径是再架一条更简单的隧道:静态密钥、不要证书、不加认证。它往往能连上,也只证明两台主机之间能过 UDP 或 TCP。它说不清为什么证书认证的部署失败,还悄悄换掉了要求你保留的安全模型。

关掉 tls-auth 或 tls-crypt、放宽 verify-x509-name、或者为了绿色状态而丢掉第二因素,也是一回事。因为验证被拿掉才连上的隧道是另一套系统,不是修好的系统。

在日志点名的层次做一处有边界的改动,重启同一个单元,再重复那一次连接尝试。这样比较才诚实,也留下一个可以回退的改动。

该把什么交给下一个人

趁手上还有,写下四件事:来自 openvpn --version 的 OpenVPN 版本、正在活动的单元、带 include 的配置链,以及覆盖一次尝试的日志窗口。这四样能把含糊的抱怨变成可复现的案例。

分享前先脱敏。私钥、auth-user-pass 文件、静态密钥材料和完整客户端包都不该进工单;选项名和链的形状通常已够第二双眼睛看。

如果配置链完好、日志仍指向网络,下一步是客户端与服务器之间的路径,而不是再装一遍。这才是辅助脚本从来不曾掌握的那部分故事。

相关文章