Get-запрос к защищенному rest api
Задача сосотоит в том, что у меня есть необходимость отправить get запрос на REST API. Сложность состоит в том, что на первом этапе проводится проверка SSL сертификата на сервере, допустим https://134.44.100.60. Со стороны сервера имеется собственный СА от которого я и получил сертификат. Также, у меня настроен VPN туннель с данным сервером. С валидацией сертификата проблем не стало, т.е. я отправляю запрос на сервер и получаю вменяемый ответ. После этого мне необходимо направить запрос к REST API (например, /api/v1/Accountant/service?toDate=2020-10-08) на получение информации, но я получаю ответ, что данных URL-ов на сервере не существует. Что является довольно странным поведением, поскольку к данным URL ежедневно подключаются другие пользователи и успешно ими пользуются. Операционная система с которой работаю Windows server 2012R2
Что я использовал для отправки запроса:
- PowerShell 5.1. Invoke-WebRequest и Invoke-RestMethod (пробовал оба, но различие увидел только в представлении возвращаемых ответов, но могу ошибаться). Пример:
$response = Invoke-WebRequest -Uri https://134.44.100.60 -Certificate $cert -SessionVariable 'ses'
Здесь все хорошо и я получаю 200 ответ от сервера и никаких ошибок, предупреждений и прочего
Далее пробую обратиться к REST API:
$rest = Invoke-WebRequest -Uri https://134.44.100.60/api/v1/Accountant/service?toDate=2020-10-08 -H $headers -WebSession $ses
И, вот, тут я и получаю URL not found. headers содержит базовую аутентификацию
- Python requests. Здесь долго мудрил с сертификатами, но так и не получил нормального результата. Т.е. я конвертировал в .pem файл и пробовал вот так
import requests
url = 'https://134.44.100.60/api/v1/Accountant/service?toDate=2020-10-08'
response = requests.get(url=url, headers=headers, verify=(cert.pem))
ошибка выглядит примерно так [SSL] PEM lib [._4303]
Так, вот в чем вопрос: куда дальше? Документация по API говорит, что ссылки вот такие и точка. Пробовал, конечно, с ними поиграться, но это как слепой котенок тыкаешься и не понимаешь, что делаешь. Точно знаю, что у API ip адрес отличается от адреса хоста, примерно такой: 134.44.101.100, но ping на него не проходит
Ответы (1 шт):
Решение такое, если кто будет также копаться как и я. Сначала перепроверил сертификаты от CA. С помощью openssl верифицировал и собрал цепочки. Следом, начал работать под Linux с curl, что немного более гибко, чем Windows Server 2012.
- Обратился к серверу
curl --verbose https://134.44.100.60
- Посмотрел, где может затыкаться запрос и нашел вот такие строчки
subjectAltName does not match 134.44.100.60
SSL: no alternative certificate subject name matches target host name '134.44.100.60'
это могло означать, что серверный сертификат не содержит ip-адрес как имя хоста
- Смотрим какие имена распологаются в поле subjectAltname
openssl s_client -connect 134.44.100.60:443 </dev/null 2>/dev/null | openssl x509 -inform pem -text | grep -A1 "Subject Alternative Name"
Вывод был достаточно большим и содержал примерно 20 имен
Заглянул в документацию к API и нашел необходимое имя для моего запроса (accounting.local)
И воспользовался
curl --connect-to, чтобы перенаправить свой запрос
curl -H "Authorization:Basic <base64user_pass>" --connect-to accounting.local:443:134.44.100.60 https://accounting.local/api/v1/Accountant/service?toDate=2020-10-01
- И тут все заиграло яркими красками.
Ну, и разобравшись написал скрипт на python с таким поведением.
Осталось понять, насколько все это можно легко перенести в производственную конфигурацию.