除非之前已从浏览器访问,否则 HTTPS 地址/域的 cUrl 会超时

除非之前已从浏览器访问,否则 HTTPS 地址/域的 cUrl 会超时

我已经花了几天时间来解决这个问题,希望它能引发一些人的思考。

我正在使用 Powershell 脚本将多个系统集成在一起。我连接到的两个服务之一(托管 JIRA)可以从我的本地系统正常访问,但从我的一个虚拟机运行时脚本会失败。我偶然发现,如果我在服务器上打开/刷新浏览器以获取该主机的 HTTPS URL,那么脚本将能够在之后的大约 20-30 秒内通过 HTTPS 访问 API。

当我远程访问服务器并从 powershell 控制台尝试此操作时,我收到超时错误。然后我验证了 cUrl 也发生了相同的行为(下面包含详细输出)。使用该域刷新浏览器,然后允许两者在短时间内访问 HTTPS URL。它似乎在 SSL 协商之前的初始连接上超时。

PoSH 指挥代表:

调用-RestMethod-方法获取-Uri”https://MYDOMAIN.atlassian.net/rest/api/2/issue/PLPT-1?fields=key,id,status“-Headers @{“Authorization” = “Basic”+ [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('USERNAME:PASSWORD'))}

代表性的cUrl命令:

curl.exe“https://MYDOMAIN.atlassian.net/rest/api/2/issue/PLPT-1?fields=key,id,status“-u”用户名:密码“-v-X获取

我对此进行了大量研究,但仍然一头雾水。我确实尝试使用 Wireshark 进行深入研究,但我已经多年没有使用数据包嗅探器了,而且我已经生疏了,不得不学习 UI。

故障排除:

以下是我在尝试隔离问题时想到的问题/答案:

  • 它是 powershell 吗?
    • 使用 cUrl 也会超时
  • 都是HTTPS吗?
    • https://google.com/工作正常,无超时
    • https://localhost/...工作正常,无超时
  • 有没有通过浏览器访问过JIRA的系统?
    • 我验证了我的家用台式机可以通过 PoSH 连接,尽管从未访问过 JIRA
  • 它是主机、DC 还是操作系统?
    • 这是 Azure 中的 2008 R2 VM,我验证了 PoSH 和 cUrl 命令在运行 2008 R2 的第二个 Azure VM 中运行正常
  • 防火墙、防病毒软件?
    • 禁用防病毒和防火墙,cUrl + PoSH 仍然超时
  • 用户代理?
    • 包含用户代理对问题系统或工作系统没有影响
  • Fiddler 说了什么?
    • 使用 SSL 解密的 Fiddler 导致网关发生错误而不是超时,我还没有深入研究
  • 这可能是 Atlassian 的网络问题?连接不稳定?
    • 我不断收到来自我的服务器的错误,而我尝试过的其他地方都一直正常工作
    • 我在服务器和本地连续执行了 10 次调用,从 10 次本地调用中获得了完美的返回值,从服务器获得了完美的超时。在服务器上执行浏览器刷新技巧后,我连续获得了 10 次完美的响应。
  • 它在 Wireshark 中是什么样子的?
    • 使用 cUrl:Wireshark 显示初始 TCP 调用已发出,但尚未确认,因此您会看到两次 TCP 重传尝试
    • 在浏览器启动后使用 cUrl:Wireshark 显示第一个 TCP 调用已确认,然后一切正常

有那么一小段时间,我以为 cUrl 已经稳定地工作了。我使用 -3 -4 来强制使用 SSL3 和 ipv4 地址,它似乎可以正常工作,而我无需使用 Web 浏览器启动连接。不幸的是,重启后它不再起作用。

我在服务器上尝试过的方法:

  • cUrl,cUrl 与 -3 -4
  • PoSH:Invoke-RestMethod、Invoke-WebRequest、WebClient、WebRequest/WebResponse、通过 ServicePointManager 将默认 SSL 设置为 SSL3、通过系统默认值设置代理和代理凭据(如果有)(据我所知)
  • IE:有效
  • Chrome:有效

cUrl 输出

以下是 cUrl 的一些示例输出。我已经打开了浏览器https://MYDOMAIN.atlassian.net(它位于登录屏幕上),但我让它闲置了一段时间,因此连接可能已失效。

刷新浏览器之前 cUrl 输出:

* Hostname was NOT found in DNS cache
*   Trying 165.254.226.145...
* connect to 165.254.226.145 port 443 failed: Timed out
* Failed to connect to MYDOMAIN.atlassian.net port 443: Timed out
* Closing connection 0

刷新浏览器后立即运行时 cUrl 输出:

* Hostname was NOT found in DNS cache
*   Trying 165.254.226.145...
* Connected to MYDOMAIN.atlassian.net (165.254.226.145) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: C:\Users\Administrator\AppData\Local\Apps\cURL\bin\curl-ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
... rest of handshake and HTML for a 401 error page because I didn't force pre-authentication ...

更新

我将 Wireshark 结果添加到上述问题中。

我现在还发现,如果我运行 cUrl 命令并在它超时之前取消它并立即再次运行它,它就会成功。如果我让 cUrl 命令超时然后立即再次运行它,它会再次超时。

如果我运行 PoSH 命令并在超时之前取消它并立即再次运行它,我实际上可以连续成功运行它 5 次以上。

这绝对与网络有关,我将看看重新运行该命令是否最终会到达再次超时的点,或者取消第一次调用是否可以让我尽可能长时间地继续进行后续调用(这可能是可能的,我认为 PoSH 在初始连接形成后利用了保持活动的优势)。

答案1

我的临时“解决方案”是在初始调用时使用较短的超时时间,如果失败则立即重试。超时时间足够短,以至于在此服务器上失败,然后以足够快的速度重试以开始成功通信(就像我手动运行它,取消它,然后再次运行一样)。

到目前为止,看起来一次超时和重试足以保持连接正常工作,从而使其余的自动化脚本能够无问题运行。

这是一个解决方法,我仍在寻找根本原因和更好的答案。

答案2

对于非常相似的症状(失败时 curl 详细输出,而通过时则不然),但对于间歇性故障,我们只使用 CL 中的 curl出现发现这个 curl 的附加选项可以有效解决这个问题:

--connect-timeout 30

相关内容