TLS 协商挂起

TLS 协商挂起

我有一个设置,过去几年运行良好,但几天前停止了工作。在我的客厅里,我有一台“裸机”,上面有几台虚拟机。其中一个虚拟机负责我的电子邮件(dovecot、postfix),另一个负责 HTTP/S 服务器(nginx)。这两个虚拟机中的每一个都与 Digital Ocean 上的 droplet 建立 OpenVPN 连接。droplet 具有防火墙规则(iptables),可将数据包转发到负责该数据包的 OpenVPN 客户端:如果它来自端口 80,则转发到具有 nginx 的内部 VM。如果是与电子邮件相关的数据包,则转发到电子邮件 VM。

从几天前开始,与 TLS 相关的一切都停止工作了(参见编辑)。SMTP 事务将在 STARTTLS 阶段挂起,HTTPS 连接将在 TLS 协商期间挂起。其他任何操作都可以正常工作:普通HTTP 连接已完成(见编辑)如果我在 postfix 上禁用 TLS,电子邮件就可以正常接收。

此外,如果我在同一个网络上,并且将主机名与虚拟机的内部 IP 一起添加/etc/hosts,HTTPS 和 STARTTLS 都可以正常工作。如果连接来自“外部”(即来自隧道),则不起作用。

如果我将互联网连接从“裸机”更改为使用手机的移动数据连接,它也能按预期工作。

总而言之,似乎对我来说我的路由器和/或我的 ISP 在这个等式中扮演着关键角色,但我就是无法接受,因为往返 VM 的流量是通过 OpenVPN(加密)传输的。如果我已经学到了一些东西,那就是最简单的解释通常是正确的,而我发现的唯一解释一点也不简单,所以,我对这个问题的其他可能原因很感兴趣。

到目前为止我已经尝试过:

  • 裸机上的另一台虚拟机,装有另一个操作系统:不起作用
  • 我的内部网络上的 Raspberry Pi 作为带有 nginx 的 OpenVPN 客户端:不起作用
  • 另一个 droplet 作为 OpenVPN 客户端与 nginx 配合使用:有效
  • 我笔记本电脑上的虚拟机作为 OpenVPN 客户端,使用 nginx:不起作用
  • 我的笔记本电脑通过手机的移动数据连接连接到互联网,再加上上面的场景:有效
  • 其他提供商的 OpenVPN 服务器(Amazon EC2):无法工作

可能有帮助的日志:

来自内部虚拟机的 TCP 转储

来自 OpenVPN 服务器 (Droplet) 的 TCP 转储

Droplet 上的防火墙规则

通过 Droplet 在端口 80 上成功从公共互联网连接到内部虚拟机

通过 Droplet 从公共互联网连接到内部虚拟机时在端口 443 上挂起的连接示例

从内部网络通过端口 443 成功连接

编辑:

VM 的 Wireshark 日志

OpenVPN 服务器的 Wireshark 日志

编辑2:

我做了一些测试,并在 nginx 上使用自签名证书创建了一个新的 vhost。看来 OpenVPN 服务器和 VM 之间的数据交换已经进行了进一步的,但尚未完成:

VM 的 Wireshark 日志

OpenVPN 服务器的 Wireshark 日志

编辑3:

最终看来,这根本与 TLS 无关。只要涉及 TLS,就会发生这种情况,这只是一个“巧合”,但我越来越确信这与数据包大小有关:删除 nginx 上将所有 HTTP 连接转发到 HTTPS 的“强制重定向”,我发现当有效负载大于几 KB 时,HTTP 连接也会发生此问题。

我还尝试将路由器/调制解调器与 ISP 的光纤连接断开,然后使用手机上的 USB 网络共享功能检查问题是否出在路由器/调制解调器上,结果成功了。因此,问题似乎已经解决了。

相关内容