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

Tar*_*rwn 5 powershell https curl jira

我已经在这个问题上浪费了几天时间,希望它能激发某人的想法。

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

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

代表 PoSH 命令:

Invoke-RestMethod -Method Get -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 "USERNAME:PASSWORD" -v -X GET

我在这方面做了很多挖掘,我很难过。我确实尝试使用 Wireshark 进行更深入的挖掘,但是我已经好几年没有使用数据包嗅探器了,而且我已经生疏了,不得不学习 UI。

故障排除:

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

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

在很短的时间内,我以为我已经让 cUrl 一直在工作。我使用 -3 -4 来强制使用 SSL3 和 ipv4 地址,它似乎可以正常工作,而我不必用网络浏览器建立连接。不幸的是,重新启动后这不再有效。

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

  • cUrl, cUrl with -3 -4
  • PoSH:Invoke-RestMethod、Invoke-WebRequest、WebClient、WebRequest/WebResponse,通过 ServicePointManager 将默认 SSL 设置为 SSL3,通过系统默认设置代理和代理凭据,以防万一(我不知道)
  • IE:作品
  • 铬:作品

卷曲输出

这是 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
Run Code Online (Sandbox Code Playgroud)

刷新浏览器后立即运行时的 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 ...
Run Code Online (Sandbox Code Playgroud)

更新

我在上面的问题中添加了 Wireshark 结果。

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

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

这绝对是与网络相关的事情,我将看看重新运行该命令是否最终会再次超时,或者是否以某种方式取消第一个调用让我尽可能长时间地继续进行后续调用(这可能是可能的,我认为 PoSH 在初始连接形成后正在利用保持活动状态)。

Tar*_*rwn 0

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

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

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