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
Мое временное "решение" - использовать короткий тайм-аут при начальных вызовах и немедленно повторить попытку, если они потерпели неудачу. Тайм-аут достаточно короткий, чтобы на этом сервере произошел сбой, а затем снова достаточно быстро, чтобы начать успешную связь (как когда я запускал его вручную, отменил, а затем снова запустил).
До сих пор похоже, что наличие одного таймаута и повторных попыток достаточно для поддержания работоспособности соединения, чтобы оставшаяся часть сценария автоматизации работала без проблем.
Это обходной путь, я все еще ищу основную причину и лучший ответ.