HTTPS через прокси: как найти участок, на котором ломается запрос

После подключения HTTPS браузер показывает ошибку, а приложение отвечает на localhost. Перезапускать приложение наугад неудобно: клиентский запрос проходит ещё через DNS, установку защищённого соединения и выбор сайта в прокси. Ошибка на каждом участке выглядит по-разному и требует своего исправления.

Возьмём понятную схему: публичное имя api.example.org указывает на сервер с Nginx, он принимает HTTPS на 443 и передаёт HTTP-запрос приложению на 127.0.0.1:8000. Если у вас CDN или отдельный балансировщик, добавьте его в рисунок маршрута. Для проверки важно знать, где заканчивается TLS и где начинается следующий сетевой вызов.

Сначала сохраните точный симптом

Выполните запрос с машины, на которой возникла проблема. Сохраните время, запрошенное имя, код завершения curl и текст ошибки. Используйте безопасный endpoint без токенов в URL. Подробный вывод может содержать заголовки, поэтому не копируйте его целиком в публичное обсуждение.

curl --verbose --connect-timeout 5 --max-time 15 https://api.example.org/health

Ошибка разрешения имени возникает до подключения к серверу. Отказ в соединении означает, что соединение с выбранным адресом не установлено; он ещё ничего не говорит о сертификате. Ошибка проверки сертификата означает, что клиент дошёл до TLS, но не подтвердил доверие, срок или соответствие имени. HTTP-статус появляется уже после этих этапов.

Поэтому сначала установите адрес, выбранный клиентом, и сравните его с нужным узлом. У домена могут быть A и AAAA записи, а IPv4 и IPv6 ведут на разные конфигурации. Сравнение curl -4 и curl -6 полезно именно при наличии соответствующих записей и маршрутов; отсутствие IPv6 у клиента само по себе не доказывает ошибку сайта.

Отделите DNS от конфигурации HTTPS

Для запроса к определённому серверу оставьте обычное имя в URL и задайте адрес через --resolve. Пример ниже содержит адрес для документации. После подстановки своего адреса вы получите проверку выбранного узла с правильным именем TLS и HTTP Host, даже если публичный DNS пока указывает в другое место.

curl --verbose --resolve api.example.org:443:192.0.2.20 https://api.example.org/health

Прямой запрос https://192.0.2.20 проверяет другое имя и может выбрать другой виртуальный сервер. Добавление только заголовка Host не исправляет имя, используемое на этапе TLS. Поэтому --resolve подходит для репетиции нового сертификата и нового узла лучше, чем комбинация IP-адреса и отключённой проверки доверия.

Если проверка сертификата падает, выясните, какой сертификат реально выдан для этого имени. Проверьте срок действия, список имён и полноту цепочки промежуточных сертификатов на стороне прокси. Если сервер использует внутренний центр сертификации, клиенту нужен соответствующий доверенный корень. Параметр -k убирает проверку и скрывает именно то свойство, которое нужно подтвердить перед открытием доступа пользователям.

Когда TLS прошёл, переходите к HTTP

Ответ 404 может прийти от приложения либо от другого виртуального сервера Nginx. Сопоставьте точное время с access log прокси и запросом в журнале приложения. Если записи приложения нет, проверьте server_name, выбранный location и адрес proxy_pass. Конфигурацию Nginx сначала проверяют командой nginx -t, а уже затем применяют обычной процедурой проекта.

Ответ 502 направляет поиск к соединению прокси с upstream. На сервере выполните тот же запрос прямо к приложению. В нашем примере оно слушает HTTP; обращение к нему по HTTPS создало бы отдельную ошибку протокола. Если приложение работает внутри контейнера, адрес 127.0.0.1 зависит от того, где запущен сам прокси.

curl --fail --show-error http://127.0.0.1:8000/health

Прямой запрос работает, а прокси получает отказ? Проверьте именно адрес и порт из активного proxy_pass, ограничения доступа и error log. Запрос проходит, но вход в аккаунт уходит по кругу? Теперь нужно смотреть передаваемую схему и настройки доверия к прокси в приложении: оно может строить перенаправление на HTTP, не учитывая внешний HTTPS. Это уже следующий этап, после подтверждённого сетевого пути.

Меняйте один участок за раз и повторяйте одинаковый запрос. Одновременная замена DNS, сертификата и адреса upstream затрудняет сравнение: исчезнувший симптом ещё не показывает, какое действие помогло. Для записи диагностики достаточно времени, адреса проверенного узла, исходного статуса и результата следующего запроса. Так повторную проверку сможет выполнить другой участник команды.

Проверьте пользовательский маршрут целиком

После исправления повторите исходный запрос с клиентской машины. Затем выполните обычное безопасное действие: авторизацию тестовой учётной записью или чтение известного объекта. Сохраните адрес узла, статус и время. Так вы проверите именно маршрут посетителя, включая DNS и прокси, а не только локальный процесс.

Если имя upstream ведёт в контейнер, продолжите разбором localhost в Compose. Для обратной ситуации, когда сам контейнер вызывает чужой HTTPS API, пригодится проверка доверенных сертификатов внутри образа.

Когда прокси и приложение работают в Docker, следующий полезный навык — понимать адреса между контейнерами, порты хоста и конфигурацию запуска. В курсе Docker и Docker Compose вы соберёте HTTP-сервис с PostgreSQL, настроите связь сервисов и потренируетесь искать причины недоступности по логам и состоянию контейнера. Откройте программу курса и соберите окружение, в котором сетевой путь можно объяснить по шагам.

Продолжить на практике

  • Docker и Docker Compose: контейнеризация приложений ↗

    Упакуйте приложение в Docker и запустите его с PostgreSQL через Compose. Образы, сети, тома, диагностика поломок, обновление версий и восстановление данных — с практикой и итоговым проектом.