Когда HTTPS перестает работать, логи веб-сервера не всегда подскажут правду. Проблема может быть выше по стеку — в TCP, в самом рукопожатии TLS, в SNI/ALPN или в сетевых фильтрах. В таких случаях pcap-захват и последующий анализ в терминале или Wireshark позволяют увидеть реальную картину на проводе и быстро локализовать причину.
Короткий ликбез: TLS, SNI, ALPN, рукопожатие
TLS обеспечивает шифрование и целостность. До установки ключей часть метаданных идет открыто: ClientHello содержит версии, список шифров, расширения. Важнейшие расширения для диагностики веба:
- SNI (Server Name Indication) — имя виртуального хоста, которое клиент запрашивает еще до шифрования. В многодоменных конфигурациях сервер выбирает сертификат по этому имени.
- ALPN (Application-Layer Protocol Negotiation) — договоренность о прикладном протоколе поверх TLS: h2 (HTTP/2), http/1.1, иногда h3 (для QUIC — уже в UDP).
В TLS 1.2 рукопожатие длиннее и более «читаемое» для анализаторов: ClientHello → ServerHello → Certificate → ServerKeyExchange → ... → Finished. В TLS 1.3 схему упростили и ускорили (меньше проходов), часть параметров переносится в новые сообщения (EncryptedExtensions), многие детали шифруются раньше — зато Wireshark их корректно декодирует на этапе переговоров.
Важно: даже без расшифровки содержимого сеанса вы видите критичные для диагностики поля ClientHello/ServerHello: SNI, ALPN, версии, списки шифров и алерты TLS.
Снятие pcap с tcpdump: надежные пресеты
Чтобы анализировать, сначала корректно соберите pcap. Общие правила:
- Снимайте на интерфейсе, где реально идет трафик (например,
eth0илиloдля локального проксирования). - Используйте полный snaplen (
-s 0), чтобы не обрезать заголовки TLS. - Ограничивайте фильтрами: порты, адреса, хосты — pcap будет меньше и понятнее.
- Для длительных сборов — ротация файла или ограничение по размеру/времени.
# Захват TLS по TCP/443 с полного интерфейса, без обрезки
sudo tcpdump -i eth0 -nn -s 0 -w tls.pcap tcp port 443
# Если используется HTTP/3/QUIC, добавьте UDP/443
sudo tcpdump -i eth0 -nn -s 0 -w quic.pcap udp port 443
# Фильтр по конкретному IP сервера
sudo tcpdump -i eth0 -nn -s 0 -w tls-host.pcap host 203.0.113.10 and tcp port 443
# Ротация каждые 5 минут с именованием по времени
sudo tcpdump -i eth0 -nn -s 0 -G 300 -w 'tls-%Y%m%d-%H%M%S.pcap' tcp port 443
# Ограничение по размеру с кольцевой ротацией (100 MB на файл, 10 файлов)
sudo tcpdump -i eth0 -nn -s 0 -C 100 -W 10 -w tls-rot.pcap tcp port 443
Если веб-сервер и обратный прокси общаются по lo, снимайте и на loopback:
sudo tcpdump -i lo -nn -s 0 -w local-proxy.pcap tcp port 443
Нужны короткие «снимки» во время инцидента? Полезно держать заготовки и команды под рукой. Не забывайте по окончании инцидента выключать захват и безопасно хранить pcap.
Быстрый терминальный разбор: tcpdump и tshark
Для грубой оценки можно заглянуть в пэкап прямо в терминале. Увидим, есть ли ClientHello/ServerHello, идет ли ретрансмиссия/сбросы, приходят ли алерты.
# Посмотреть короткое резюме пакетов
tcpdump -nn -r tls.pcap | head -n 50
# Показать только TLS Handshake по TCP/443 (по текстовым указаниям протокола)
tcpdump -nn -r tls.pcap 'tcp port 443' | grep -i 'Client Hello\|Server Hello\|Alert'
Точнее и богаче по полям — tshark (консольный движок Wireshark). Он умеет извлекать SNI, ALPN и детали рукопожатия:
# Клиентские приветствия и SNI
tshark -r tls.pcap -Y 'tls.handshake.type == 1' -T fields -e frame.time -e ip.src -e tcp.srcport -e tls.handshake.extensions_server_name
# ALPN, согласованный протокол (в ServerHello)
tshark -r tls.pcap -Y 'tls.handshake.type == 2' -T fields -e frame.time -e ip.dst -e tcp.dstport -e tls.handshake.extensions_alpn_str
# Версии TLS, поддержанные клиентом (TLS 1.3: supported_versions)
tshark -r tls.pcap -Y 'tls.handshake.extensions_supported_version' -T fields -e ip.src -e tls.handshake.extensions_supported_version
# Алерты TLS (например, handshake_failure, bad_certificate)
tshark -r tls.pcap -Y 'tls.alert_message' -T fields -e frame.time -e ip.src -e ip.dst -e tls.alert_message
# Ошибки TCP: RST (часто при несогласии протоколов или сбое на уровне приложения)
tshark -r tls.pcap -Y 'tcp.flags.reset == 1' -T fields -e frame.time -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport
Если tshark не находит поля с префиксом tls., проверьте версию. В старых сборках использовался префикс ssl.. Аналогичные фильтры будут работать с заменой tls. на ssl..
Анализ в Wireshark: что смотреть в первую очередь
Wireshark визуально удобнее для последовательного разбора. Откройте pcap и идите по шагам:
- След TCP-потока (Follow TCP Stream) — быстро увидеть направление и наличие рукопожатия. Для QUIC используйте поток UDP.
- ClientHello — проверьте Server Name (SNI), список Supported Versions, Signature Algorithms, Groups, ALPN.
- ServerHello — смотрим выбранную версию, группу ключей, шифр, ALPN. В TLS 1.3 сразу обратите внимание на EncryptedExtensions.
- Certificate — правильная ли цепочка, CN/SAN соответствует SNI? Если нет, далее часто следует алерт certificate_unknown.
- Alerts — если рукопожатие обрывается, диалог часто заканчивается Alert от клиента или сервера; код подскажет тип поломки.
Если HTTP/2 не согласован, но HTTPS продолжился, Wireshark покажет ALPN: server accepted http/1.1. Это не авария, но симптом несоответствия настроек клиента/сервера.

TLS 1.2 vs TLS 1.3: что видно в pcap
Разница для диагностики:
- TLS 1.2: больше сообщений в открытом виде до шифрования. Удобно видеть детали, но рукопожатие медленнее.
- TLS 1.3: меньше раундов, часть расширений переносится, а после ServerHello большинство сообщений зашифровано. Тем не менее SNI/ALPN и поддержанные версии в ClientHello всегда доступны.
Для быстрой идентификации используйте фильтры:
# Пакеты с ClientHello (type 1)
tshark -r tls.pcap -Y 'tls.handshake.type == 1' -T fields -e frame.number -e tls.handshake.version
# Попытки TLS 1.0/1.1 (частая причина отказа, если они запрещены)
tshark -r tls.pcap -Y 'tls.record.version == 0x0301 || tls.record.version == 0x0302' -T fields -e frame.time -e ip.src -e tls.record.version
Диагностика SNI
Если сервер отдает «не тот» сертификат или соединение сразу рвется, проверьте, пришел ли корректный SNI.
# Извлечь SNI, IP источника и порт
tshark -r tls.pcap -Y 'tls.handshake.extensions_server_name' -T fields -e ip.src -e tcp.srcport -e tls.handshake.extensions_server_name | sort | uniq -c
Типичные случаи:
- Клиент без SNI: старые клиенты не отправляют SNI. Сервер выбирает дефолтный сертификат — браузер увидит несоответствие имени.
- Опечатка в домене: в SNI пришел другой домен, чем ожидалось. Часто заметно по статистике выше.
- Прокси/балансировщик меняет маршрут: SNI верный, но цепочка виртуальных хостов на бэкенде не соответствует.
Диагностика ALPN (HTTP/2, HTTP/1.1, HTTP/3)
Несогласование ALPN не рвет TLS, но влияет на производительность и функционал. Диагностируем так:
# Что предлагал клиент
tshark -r tls.pcap -Y 'tls.handshake.extensions_alpn_str' -T fields -e ip.src -e tls.handshake.extensions_alpn_str
# Что выбрал сервер (ServerHello)
tshark -r tls.pcap -Y 'tls.handshake.type == 2' -T fields -e ip.dst -e tls.handshake.extensions_alpn_str
Кейсы:
- Клиент предлагает h2,http/1.1, сервер выбирает http/1.1 — на стороне сервера отключен HTTP/2, либо выбранный шифр/настройка не совместимы.
- Клиент не предлагает h2 — библиотека/версия клиента устарела, либо промежуточный прокси удаляет расширение.
- HTTP/3: для QUIC смотрите потоки UDP/443; ALPN обычно «h3». Если UDP блокируется/теряется, падение будет заметно по повторам Initial и отсутствию подтверждений. Подробно про практику терминации см. статью «Терминация HTTP/3/QUIC в HAProxy» (как настраивать и диагностировать QUIC).

Алерты TLS и быстрые признаки обрыва
Когда рукопожатие срывается, часто прилетает alert — его стоит поймать первым делом:
# Все алерты и стороны
tshark -r tls.pcap -Y 'tls.alert_message' -T fields -e frame.time -e ip.src -e ip.dst -e tls.alert_message | sort | uniq -c
# Handshake failure
tshark -r tls.pcap -Y 'tls.alert_message == "handshake_failure"' -T fields -e frame.time -e ip.src -e ip.dst
# Bad certificate / unknown ca
tshark -r tls.pcap -Y 'tls.alert_message matches "certificate"' -T fields -e frame.time -e ip.src -e ip.dst -e tls.alert_message
Если алертов нет, но соединение обрывается RST — проверьте логи приложений и таймауты:
tshark -r tls.pcap -Y 'tcp.flags.reset == 1' -T fields -e frame.time -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport
Разбор типичных сбоев по pcap
1) Клиент не может договориться о версии TLS
Сервер разрешает только TLS 1.2+ или только 1.3, а клиент предлагает 1.0/1.1. В ленте видно ClientHello со старыми версиями, затем alert protocol_version или handshake_failure. Решение — обновление клиента или смягчение минимальной версии на периметре (если политика безопасности допускает).
2) Неверный сертификат из-за отсутствия SNI
В ClientHello отсутствует server_name, сервер отдает сертификат по умолчанию. Браузер жалуется на имя. Проверяем статистику SNI, оцениваем долю таких клиентов и при необходимости добавляем отдельный виртуальный хост по умолчанию с редиректом или информационной страницей.
3) ALPN не согласован, HTTP/2 не включается
Клиент предлагает h2, сервер возвращает http/1.1. Часто это настройки TLS: неподдерживаемая группа эллиптических кривых, шифры без ALPN, модуль HTTP/2 отключен на фронте. Решение — включить HTTP/2 на фронтенде и проверить список поддерживаемых шифров.
4) Обрыв на Certificate: unknown_ca или неполная цепочка
Сервер отправляет неполную цепочку (нет промежуточного CA). Клиент присылает alert unknown_ca/bad_certificate. В Wireshark в сообщении Certificate видна неполная цепочка. Решение — добавить промежуточные сертификаты в конфигурацию сервера. При замене или продлении проверьте свои SSL-сертификаты и валидность полной цепочки.
5) Сброс TCP при старте приложения
Рукопожатие не доходит до Application Data, вместо этого в сторону клиента летит RST — частая причина: приложение завернуло соединение после ранней проверки имени/хедера или упало. В pcap виден RST без TLS alert. Решение — совместная проверка системных журналов и pcap по времени.
6) QUIC/HTTP/3 не работает из-за сетевых фильтров
По UDP/443 видны повторы Initial, нет ответов сервера — фильтрация или асимметричная маршрутизация. Проверьте устройство между клиентом и сервером, временно отключите фильтр для проверки гипотезы, измерьте потери пакетов. Если балансируете L4, пригодится обзор «Nginx Stream: TCP/UDP‑балансировщик» (о конфигурации и диагностике потоков).
Мини-сниппеты для рутины
Выжимка полезных команд, которые экономят время:
# Частота доменов по SNI
tshark -r tls.pcap -Y 'tls.handshake.extensions_server_name' -T fields -e tls.handshake.extensions_server_name | sort | uniq -c | sort -nr | head
# Какая версия TLS выбрана чаще
tshark -r tls.pcap -Y 'tls.handshake.type == 2' -T fields -e tls.handshake.version | sort | uniq -c | sort -nr
# Статистика ALPN
tshark -r tls.pcap -Y 'tls.handshake.extensions_alpn_str' -T fields -e tls.handshake.extensions_alpn_str | sort | uniq -c | sort -nr
# Длина рукопожатия по времени (первые и последние кадры TCP-потока)
tshark -r tls.pcap -q -z conv,tcp
Где снимать трафик и как не потерять контекст
Снимайте как можно ближе к «истине»:
- На фронтенде — видно клиентский SNI/ALPN и реальное рукопожатие.
- Между фронтом и бэкендом — если есть TLS-терминация и повторное шифрование, снимите оба плеча. Это выявит рассогласование протоколов.
- На loopback — когда трафик проходит через локальный прокси или сервис-меш в пределах узла.
Если у вас балансировка по нескольким нодам, пометьте файлы pcap именем хоста и временем, чтобы в дальнейшем совместить с метриками и логами.
Этика и конфиденциальность
pcap может содержать чувствительные данные. Минимизируйте сбор:
- Фильтруйте по адресам/портам/времени.
- Не храните pcap дольше необходимого.
- Ограничьте доступ, пересылайте только по защищенным каналам.
- Для локальной отладки с расшифровкой используйте SSL key log в тестовой среде (переменную окружения для клиента), а не в бою.
Чек-лист диагностики TLS в pcap
- Есть ли ClientHello? Если нет — ищите сетевую проблему до TLS (маршрутизация, firewall, MTU).
- SNI корректный? Сверьте домен и ожидаемый виртуальный хост.
- Версии TLS и шифры согласованы? Проверьте supported_versions и выбранную версию в ServerHello.
- ALPN согласован? h2/http/1.1 ожидаемы? Для HTTP/3 — отдельный разбор UDP/443.
- Цепочка сертификатов полная? Нет ли unknown_ca/bad_certificate.
- Алерты или RST? Зафиксируйте точный код алерта или факт RST и сопоставьте с логами.
- Время рукопожатия не аномально? Сравните задержки по сегментам сети.
Итог
Сочетание tcpdump для аккуратного снятия pcap и Wireshark/tshark для детального разбора позволяет прозрачно увидеть SNI, ALPN, версии TLS и конкретные причины ошибок. Это сокращает время поиска неисправностей: от «не работает HTTPS» до точного «клиент без SNI, сервер вернул дефолтный сертификат», «ALPN не согласован — откат на HTTP/1.1», «цепочка неполная — alert unknown_ca». Держите шаблоны захвата и фильтров под рукой, и диагностика TLS перестанет быть черной магией.


