VPN 连接后邮件提交失败:找出出错的阶段
超时、TLS 错误和 5xx 响应发生在不同阶段。先归类故障,再确认端口的 TLS 模式,然后比较路径,而不是密码。
整个上午都能用的邮件,在隧道建立的那一刻就停了,第一反应是重新输入密码。这个反应跳过了更有用的问题:客户端到底有没有连上服务器,有没有走到可以提交凭据的那一步?超时、证书错误和拒绝回复是三种不同的失败,只有第三种与账户有关。按顺序走过各个阶段,VPN 就从事先认定的嫌疑人变成一个可以测试的变量。
步骤 1:在动凭据之前先给故障分类
读应用实际产生的错误,然后把它放进三类之一。超时或连接重置,说明 TCP 路径失败;TLS 或证书错误,说明路径通了而握手没通;带代码的 SMTP 回复,说明邮件服务器已经应答并作出决定。每一类指向不同的责任方。
分开这三类是有价值的,因为修法互相矛盾。服务器拒收发件人时,延长超时毫无用处;路由被黑洞时,改密码也不起作用。回复代码是清单里最有价值的证据,因为它证明整条传输链路都通了,问题出在策略或身份上。重试之前,先把原始文本保存下来,包括任何增强状态码。
如果无法在 VPN 之外复现,就停在这里。只在一台机器、一个应用里出现的问题,还不是网络问题。
步骤 2:确认端点和 TLS 模式
邮件提交是独立的服务,与服务器之间的中继不是一回事。按服务商关于提交的文档确认主机名、端口和 TLS 模式,因为从别的邮件配置里借来的熟悉端口不是证据。587 端口期待明文问候后再 STARTTLS,而 465 端口从第一个字节起就是 TLS。
openssl s_client -connect smtp.example.com:465 -servername smtp.example.com -quiet
openssl s_client -starttls smtp -connect smtp.example.com:587 -servername smtp.example.com -quiet
nc -vz smtp.example.com 587跑错其中一个探测,正是客户端配置成另一种模式时会犯的错误。如果隐式 TLS 探测在 587 上挂住,或 STARTTLS 探测在 465 上失败,端口和模式就对不上。应当在客户端里改正模式,而不是关闭证书验证,那会把配置错误变成未经校验的连接。这种区分早已标准化:465 端口上的隐式 TLS 就是 RFC 8314 描述的布置。
这里的证书错误是信息而不是障碍。它说明了服务器出示的身份和客户端预期的身份,两者都能在不削弱连接的前提下修正。
步骤 3:不改账户,只比较路径
让端点、账户和客户端设置保持不变,只改变路径。关掉隧道发一次,打开隧道再发一次,记录路由和服务器会看到的源地址。如果故障跟着路径走,就已经隔离;如果跟着机器走,就还没有。
ip route get smtp.example.com
curl -v --ssl-reqd --url smtp://smtp.example.com:587 --user "$SMTP_USER" \
--mail-from [email protected] --mail-rcpt [email protected] --upload-file msg.txt全隧道会改变服务商看到的源地址,有些服务商对陌生来源比对陌生密码更严格。那是他们那边的策略决定,可能是灰名单、限速或封锁。不要从一个服务商推广到所有服务商,也不要以为缺少一条 NAT 规则就能解释所有失败。curl 的记录能看出哪一步失败,即使应用自己的日志看不出来。
如果隧道要承载互联网流量,它的路由和出口策略都必须放行这个目的地。只承载私有路由的隧道会把邮件连接留在本地路径上,那是另一种比较。
步骤 4:发一封无害的邮件并记录回复
修好失败的阶段,然后用同一个应用而不是网页邮箱发一封无害的邮件。要测的是应用自己的发送路径,包括它保存的设置和 TLS 模式。网页邮箱会话证明不了这些。
记录回复、端口、TLS 模式和所用的路径,让下一个人能复现结果。浏览器能用、VPN 图标是绿的,这些是对别的事的观察。邮件到达之后,剩下的工作是把这套配置做成每台用该账户发信机器的默认值。
当你能够说出失败的阶段、客户端使用的端口和 TLS 模式、邮件经过的路径以及服务器返回的回复时,清单就完整了。这四个事实把一个含糊的发件箱问题变成别人可以审查的改动。