cUrl для HTTPS-адреса / домена истекает, если ранее не был получен доступ из браузера

Я потерял пару дней из-за этой проблемы и надеюсь, что у кого-то возникла мысль.

Я объединяю несколько систем, используя скрипты Powershell. Один из двух сервисов, к которым я подключаюсь (размещенный JIRA), может быть легко доступен из моей локальной системы, но сценарий завершится ошибкой при запуске с одной из моих виртуальных машин. Я случайно обнаружил, что если я открою / обновлю браузер на сервере для URL-адреса HTTPS для этого хоста, то сценарий сможет получить доступ к API через HTTPS в течение 20-30 секунд после этого.

Я получаю сообщение об ошибке тайм-аута при удалении на сервер и пробую это с консоли powershell. Затем я убедился, что такое же поведение происходит с помощью cUrl (подробный вывод приведен ниже). Обновление браузера с этим доменом затем позволяет обоим обращаться к HTTPS-URL-адресам в течение короткого периода времени. Похоже, что истекает время на исходное соединение до согласования SSL.

Представитель PoSH Command:

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 ('ИМЯ ПОЛЬЗОВАТЕЛЯ: ПАРОЛЬ'))}

Представительная команда cUrl:

curl.exe " https://mydomain.atlassian.net/rest/api/2/issue/PLPT-1?fields=key,id,status" -u "ИМЯ ПОЛЬЗОВАТЕЛЯ: ПАРОЛЬ" -v -X GET

Я много копался в этом, и я довольно озадачен. Я пытался использовать Wireshark, чтобы копать глубже, но прошло много лет с тех пор, как я использовал анализатор пакетов, и я устал и должен изучать пользовательский интерфейс.

Поиск проблемы:

Вот вопросы / ответы, которые я мог придумать, пытаясь выделить проблему:

  • Это PowerShell?
    • Использование cUrl также истекло
  • Это все HTTPS?
    • https://google.com/ работает нормально без таймаута
    • https://localhost/... работает нормально без таймаута
  • Это система, которая когда-либо обращалась к JIRA через браузер?
    • Я подтвердил, что мой домашний компьютер может подключаться через PoSH, несмотря на то, что я никогда не обращался к JIRA
  • Это хост, DC или ОС?
    • Это виртуальная машина 2008 R2 в Azure. Я проверил, что команды PoSH и cUrl работают нормально на 2-й виртуальной машине Azure с 2008 R2
  • Брандмауэр, антивирус?
    • Антивирус и брандмауэр отключены, время ожидания cUrl + PoSH еще не истекло
  • Пользовательский агент?
    • Включение пользовательского агента не имеет значения для проблемной системы или рабочих систем
  • Что говорит Фидлер?
    • Fiddler с расшифровкой SSL вызвал ошибки шлюза вместо тайм-аутов, я не копался глубже
  • Может быть, это проблема сети для Atlassian? Прерывистая связь?
    • Я постоянно получаю ошибки от своего сервера, и он постоянно работает везде, где я пробовал
    • Я выполнил 10 вызовов подряд на сервере и локально и получил идеальные результаты от 10 локальных и совершенных таймаутов с сервера. Сделав трюк с обновлением браузера на сервере, я получил 10 подряд ответов.
  • Как это выглядит в Wireshark?
    • С помощью cUrl: Wireshark показывает, что первоначальный вызов TCP завершен, но он не подтвержден, поэтому вы видите две попытки повторной передачи TCP
    • С помощью cUrl после инициализации браузера: Wireshark показывает, что первый вызов TCP ACKed, а затем все работает, как ожидалось

В течение короткого времени я думал, что у меня CUrl работает последовательно. Я использовал -3 -4 для принудительной адресации SSL3 и ipv4, и, похоже, он работал без необходимости инициализации соединения через веб-браузер. К сожалению, после перезагрузки это больше не работает.

Методы, которые я попробовал на сервере:

  • cUrl, cUrl с -3 -4
  • PoSH: Invoke-RestMethod, Invoke-WebRequest, WebClient, WebRequest / WebResponse, установка SSL по умолчанию для SSL3 через ServicePointManager, установка прокси и учетных данных прокси через системные значения по умолчанию, если таковые имеются (не мне известно)
  • IE: работает
  • Хром: работает

выход 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 пользуется возможностью сохранить жизнь после того, как будет установлено первоначальное соединение).

2 ответа

Для очень похожих симптомов (вывод многословного скручивания при сбое по сравнению с прохождением), но для периодических сбоев с использованием только скручивания из CL, мы обнаружили, что эта дополнительная опция скручивания эффективно решает эту проблему:

--connect-timeout 30

Мое временное "решение" - использовать короткий тайм-аут при начальных вызовах и немедленно повторить попытку, если они потерпели неудачу. Тайм-аут достаточно короткий, чтобы на этом сервере произошел сбой, а затем снова достаточно быстро, чтобы начать успешную связь (как когда я запускал его вручную, отменил, а затем снова запустил).

До сих пор похоже, что наличие одного таймаута и повторных попыток достаточно для поддержания работоспособности соединения, чтобы оставшаяся часть сценария автоматизации работала без проблем.

Это обходной путь, я все еще ищу основную причину и лучший ответ.

Другие вопросы по тегам