在 SSL 中,事情是这样的:客户端在 DNS 中查找服务器名称;然后它连接到 DNS 提供的 IP 地址;然后发生 SSL 握手,在此期间服务器发送其证书。请注意,此时实际 URL 尚未发送到任何地方,只有服务器名称;所以我们可以忽略诊断的 URL。
由于该问题影响了具有不同操作系统和浏览器的多台机器,我们可能可以排除浏览器和操作系统错误。
Google、Barnes and Noble、Facebook……是人类创造的,因此不完美,偶尔会失败;但它们同时失败是不太可能的。
如果您是中间人攻击的目标,那么攻击者就是无能的。这也太不可能了。
总而言之,问题可能出在路由器和 ISP 之间。您观察到的症状与来自浏览器的 TCP 连接(以前针对www.google.com)最终在 Apple 的iCloud服务器上的假设一致。第一种可能的情况如下:
您的路由器是 DNS 中继。通过 DHCP,它实际上将您的家庭计算机配置为使用路由器作为 DNS 服务器,并且该路由器将提供您配置的外部 DNS 服务器(Google 的 DNS 服务器)。在这种情况下,如果路由器混合了它的内部表(由于软件错误或 RAM 损坏),那么它可能会为您的机器提供错误的 IP 地址。
在这种情况下,问题不仅限于 SSL。事实上,当浏览器想要连接到任何服务器时,它会询问服务器名称,而不是端口或协议。因此,如果该假设是正确的,那么非 SSL 的纯 HTTP 连接也应该偶尔会失败。例如,如果您的连接www.facebook.com被重定向到 的 IP 地址www.google.com,您将得到 Google 的答案(实际上是重定向到 Google 的主页),而不会像 Facebook 那样。
如果只是您的 SSL 连接有问题,那么这不是 DNS 问题。这将指向第二种可能的情况:
您的 ISP 的动态路由存在问题。它尝试以最佳方式路由流量,在多个目的地之间移动数据包。这些路由决策可以是特定于端口的,从而解释了为什么问题只发生在 SSL 上。出于某种原因(可能又是坏 RAM,在 ISP 路由器之一中),数据包可能会被误导。
我知道一个旧的 Cisco 路由器(RAM 不好),它的行为有点像这样。当路由器处理 IP 数据包时,它必须复制并部分修改包头(至少要修改 TTL),因此路由器中的错误可能导致目标地址被破坏。
这种情况有一个变体,其中您的路由器有坏的 RAM(再次......)并且在执行NAT时会自行跳闸。
要进一步诊断问题:
当问题发生时,在同一台机器上执行一个nslookup www.google.com(如果您想联系 Google 但被重定向到其他地方)然后openssl s_client -connect www.google.com:443(使用OpenSSL命令行工具 -- 如果您使用 Linux 或 MacOS X,那么您已经拥有它)。这将告诉您 DNS 返回什么 IP 地址,以及据称在该地址回答的服务器返回什么证书。
如果问题是间歇性的(即浏览器连接失败,但立即重试),请尝试运行网络捕获工具,如Wireshark或网络监视器,以准确观察问题发生时发生的情况。您将看到从您的机器上看到的 IP 地址。
更换家用路由器。例如,从朋友那里借一个旧路由器,或购买一个新路由器(这些成本 40 美元)。如果问题出在您的 ISP 上,那么 ISP 支持人员可能会首先声称您的路由器有问题,因此无论如何这一步都无法避免。如果更换路由器可以解决问题,那么您将再次知道 RAM 中风不良。