У HTTPS-запроса строгий порядок: имя разрешается в IP, клиент устанавливает TCP-соединение с портом 443, выполняет TLS-рукопожатие и только затем отправляет HTTP-запрос. За публичным адресом могут находиться CDN, балансировщик, Nginx и приложение. Эта инструкция проходит путь по слоям и фиксирует предел каждого вывода.
Снимите исходный симптом
Запишите домен, точный URL, время с часовым поясом и сеть клиента. Сохраните текст ошибки браузера и результат из другой внешней сети. Уточните масштаб: весь домен или один путь, www или адрес без него, IPv4 или IPv6, один регион или несколько.
Первый командный запрос показывает этап остановки:
curl -v --connect-timeout 10 --max-time 25 \
-o response.html https://example.com/problem-pathВ выводе найдите разрешённый IP, факт соединения, сообщения TLS и HTTP-статус. Не публикуйте cookie и заголовки авторизации в общем канале. Если в запросе были секреты, сделайте безопасную копию без них.
До сбора исходных данных не перезапускайте прокси и приложение. Рестарт может изменить состояние процесса, журналы и маршрут запросов. Если нужен краткий организационный протокол до глубокой диагностики, используйте руководство по реакции на инцидент.
Шаг 1. Разрешите имя через несколько DNS
Получите A и AAAA через системный и независимый публичный резолвер:
dig +short A example.com
dig +short AAAA example.com
dig @1.1.1.1 +short A example.com
dig @1.1.1.1 +short AAAA example.comПустой ответ, SERVFAIL, старый IP или расхождение указывают на зону, делегирование, DNSSEC, кэш или незавершившееся обновление. Различие само по себе может быть штатным для CDN; сравните адреса с ожидаемым пулом и регионом точки.
Если опубликованы оба типа записи, дальше тестируйте пути раздельно. Исправный A не компенсирует неисправную AAAA для клиента, который предпочитает IPv6. Команды curl -4 и curl -6 покажут, повторяется ли симптом на каждом протоколе.
TTL влияет на длительность расхождений, но не гарантирует точную минуту обновления всех кэшей. Подробности есть в статье о распространении DNS-записей.
Результат этого шага: список фактически полученных IP. Он ещё ничего не доказывает о доступности порта и сертификате.
Шаг 2. Проверьте TCP/443
Для каждого нужного пути установите соединение с портом 443:
nc -vz -w 5 example.com 443Connection refused обычно означает, что узел достижим, но порт не слушается или соединение активно отклоняется. Тайм-аут возможен при фильтрации, проблеме маршрута или недоступном сервере. Успешное подключение подтверждает TCP из этой точки; сертификат и приложение ещё не проверены.
Повторите из другой независимой сети. Сочетание «офис — timeout, мобильная сеть — success» направляет к корпоративному firewall, провайдеру или маршруту. Если ошибка следует за одним IP из DNS-пула, исследуйте конкретный edge или балансировщик.
Не переходите к журналам приложения, пока соединение до публичного 443 не устанавливается. Запрос не дошёл до HTTP-обработчика, поэтому внутренний stack trace для него отсутствует.
Шаг 3. Проверьте TLS-рукопожатие
После успешного TCP получите цепочку с правильным SNI и проверкой имени:
openssl s_client -connect example.com:443 \
-servername example.com -showcerts \
-verify_return_error -verify_hostname example.com </dev/nullПараметр -servername передаёт SNI и выбирает нужный виртуальный хост, а -verify_hostname отдельно сверяет имя с SAN сертификата. Сопоставьте срок действия, издателя, промежуточные сертификаты и итог проверки. Ошибка имени, истёкший сертификат и неполная цепочка требуют разных исправлений. Если сервер обрывает соединение до выдачи сертификата, оснований заменять файл сертификата пока нет: возможны WAF, TLS-терминатор, несовместимость протокола или маршрут.
Проверяйте узлы повторно, если ответы чередуются. Один сервер за балансировщиком может продолжать отдавать старую цепочку. Успешный вызов по IP без SNI попадёт в другой виртуальный хост и не подтвердит пользовательский домен.
Распространённые причины сообщений браузера перечислены в статье про ошибки SSL-сертификата.
Шаг 4. Получите HTTP-ответ через HTTPS
После TLS отправьте обычный GET и сохраните заголовки и тело:
curl -sS --connect-timeout 10 --max-time 25 \
-D headers.txt -o body.html \
-w '%{http_code} %{url_effective} %{time_total}\n' \
https://example.com/problem-pathGET выбран намеренно. Запрос HEAD, который делает curl -I, CDN, WAF или приложение могут обрабатывать по другому маршруту. Если прежний тест использовал HEAD, подтвердите его результат GET-запросом.
Код 5xx переносит исследование к edge, прокси, приложению или зависимости. 403 и 429 требуют проверки правил доступа и ограничения частоты. При 3xx пройдите цепочку с -L и запишите конечный домен. При 200 откройте body.html: аварийная заглушка тоже может иметь успешный статус.
Порт 80 проверяют отдельной боковой веткой:
curl -sS -D - -o /dev/null --max-time 15 http://example.com/Ожидаемый 301 на HTTPS подтверждает работу части незашифрованного пути, однако не определяет причину сбоя 443. Трафик двух портов может попадать на разные компоненты. Настройка перехода описана в руководстве по редиректу с HTTP на HTTPS.
Шаг 5. Определите публичный edge
Выясните, где завершается публичный TLS: CDN, облачный балансировщик, ingress или Nginx. Сравните сертификат снаружи с конфигурацией этого компонента, посмотрите его состояние и журналы за точное время ошибки. Новый файл на origin не влияет на цепочку, если сертификат клиенту выдаёт CDN.
Для Nginx сначала проверьте конфигурацию командой чтения, затем журнал ошибок и слушающие сокеты. Успешная проверка синтаксиса говорит о файле конфигурации; она не подтверждает, что работающий процесс загрузил эту версию. Сопоставьте PID, время загрузки и публичный ответ.
Edge способен успешно завершить TLS и вернуть 502 из-за недоступного origin. Обратная ситуация тоже возможна: приложение исправно локально, а публичный запрос блокируется WAF или маршрутом раньше него.
Шаг 6. Сравните edge с origin
Проверяйте origin только через разрешённый административный путь и без изменения состояния. Для локального HTTP-приложения сохраните правильный Host:
curl -sS -D - -o origin-body.html \
-H 'Host: example.com' http://127.0.0.1:3000/problem-pathДля прямого HTTPS к известному IP удобно сохранить имя и SNI через --resolve:
curl -sS -D - -o origin-body.html \
--resolve example.com:443:203.0.113.10 \
https://example.com/problem-pathНе отключайте проверку сертификата в доказательном тесте. Опция -k покажет, способен ли сервер отдать данные при игнорировании доверия, но не подтвердит исправность для пользователя.
Локальный 200 относится к одному узлу и одному виртуальному хосту. Для публичного восстановления нужно проверить путь через DNS, edge и TLS. Если балансировщик не достаёт origin, исследуйте allowlist адресов CDN, внутренний DNS, firewall и health check. Если ответы разных backend чередуются, сравните версии и конфигурацию каждого.
Сведите результаты в матрицу
Одна строка соответствует сети и IP. Заполняйте фактами, не словами «работает» и «не работает»:
| Точка | IP | TCP/443 | TLS | HTTP GET | Итог |
|---|---|---|---|---|---|
| Офис IPv4 | 203.0.113.10 | success | имя и цепочка верны | 502 | Ошибка после TLS |
| Мобильная IPv6 | 2001:db8::10 | timeout | — | — | Маршрут или фильтрация IPv6 |
| Origin | 10.0.0.8 | success | внутренний путь | 200 | Приложение отвечает на одном узле |
Временная мера должна соответствовать найденному слою: вывести неисправный backend, откатить конфигурацию TLS-терминатора, исправить подтверждённую запись DNS. Перед изменением сохраните журналы и способ возврата. После него повторите строки матрицы теми же командами.
Ежедневный контроль срока SSL помогает заранее заметить плановое истечение, но не локализует текущий отказ между CDN и origin. Для активного инцидента всё равно нужна заполненная матрица публичных и внутренних путей.
Условия закрытия
Проверьте исходный URL из нескольких независимых сетей, по IPv4 и IPv6 при наличии обеих записей, для нужных вариантов домена. TCP должен устанавливаться, TLS — проходить проверку имени и доверия, GET — завершаться ожидаемым статусом и содержимым.
В записи инцидента оставьте заполненную матрицу, подтверждённую причину, выполненное изменение и время нескольких успешных повторов. Непроверенный маршрут пометьте явно. Например: IPv4 подтверждён из двух сетей; IPv6 не проверен из-за отсутствия независимой точки. Такая формулировка задаёт конкретную оставшуюся задачу.