Иногда всё выглядит идеально: сертификат выписан, цепочка собрана, DNS указывает на нужный IP — а при заходе на сайт браузер показывает mismatched certificate (сертификат выдан на другой домен). В реальности это почти всегда означает одно: на этапе TLS handshake веб-сервер выбрал не тот виртуальный хост — сработал default server или «первый попавшийся» vhost, и клиенту отдали «чужой» сертификат.
Ниже разберём, как SNI влияет на выбор сертификата, почему порядок vhost критичен в Apache, как правильно задавать listen 443 default_server в Nginx и как диагностировать проблему через openssl s_client. В конце — короткий runbook, который можно держать под рукой.
Что такое SNI и где ломается выбор сертификата
SNI (Server Name Indication) — расширение TLS, которое позволяет клиенту (браузеру, curl, мониторингу) передать имя хоста во время TLS-рукопожатия. Это принципиально важно, потому что сертификат нужно выбрать до того, как сервер прочитает HTTP-запрос и заголовок Host.
Если SNI не передан или не совпал с конфигурацией, сервер видит только IP:порт. При нескольких HTTPS-сайтах на одном IP он вынужден выбрать «дефолтный» сертификат — отсюда и классическая симптоматика: один домен работает, а остальные внезапно показывают сертификат «соседа».
Ключевой момент: при HTTPS выбор сертификата происходит до обработки HTTP. Если SNI не передан или не матчится на vhost — будет выбран default server (или первый vhost), и вы увидите wrong vhost.
Типовые причины mismatched certificate
- Клиент не отправляет SNI (старые клиенты, некоторые библиотеки, специфические проверки).
- На 443 неправильно определён default vhost/server block и он перехватывает запросы.
- В Nginx неверные
server_name, нет блока под нужный домен или есть конфликт server blocks. - В Apache порядок vhost влияет на то, кто станет «первым» (а значит дефолтом при отсутствии совпадения).
- Проверяете не тот IP (особенно часто — из-за AAAA/IPv6).
- TLS терминирует внешний узел (балансировщик/прокси), и сертификат берётся уже там.
Как быстро подтвердить проблему: openssl s_client
Сначала нужно увидеть, какой сертификат реально выдаётся с конкретного IP и с указанным SNI. Самый быстрый инструмент — openssl s_client.
Проверка с SNI (правильный способ)
openssl s_client -connect 203.0.113.10:443 -servername example.com -showcerts
В выводе проверьте:
subject=иissuer=— какой сертификат отдали.- SAN (Subject Alternative Name): есть ли
DNS:example.com. - Если видите сертификат другого домена — это подтверждение wrong vhost/default server.
Проверка без SNI (чтобы увидеть дефолт)
openssl s_client -connect 203.0.113.10:443 -showcerts
Если без -servername вы получаете «левый» сертификат — это нормально для нескольких сайтов на одном IP: сервер отдаёт дефолтный. Важно, чтобы с SNI выдавался правильный.
Частая ловушка: проверка по домену, но попали не на тот IP
Когда вы делаете:
openssl s_client -connect example.com:443 -servername example.com
OpenSSL резолвит домен сам. Если у домена несколько A/AAAA или вы стоите за прокси/балансировщиком — легко проверить «не тот» узел. Для чистоты теста фиксируйте IP в -connect и отдельно задавайте имя в -servername.
Перед покупкой и установкой сертификата полезно заранее определить, какой vhost будет дефолтным на 443. Так вы избежите ситуации, когда на «неизвестные» домены и проверки без SNI отдаётся сертификат боевого сайта. Если нужен выпуск и продление в одном месте — посмотрите SSL-сертификаты (GlobalSign).

Nginx: как выбирается default server и почему важен listen
В Nginx выбор server block на 443 идёт по логике: адрес:порт, затем SNI (по server_name), и если подходящего имени нет — используется default server для этого listen.
Практическое правило: для каждого listen на 443 (и для IPv4, и для IPv6) должен быть либо корректный набор server_name, либо аккуратный дефолтный сервер с нейтральным сертификатом и понятным поведением. Иначе «чужой» сертификат будет всплывать в самых неожиданных местах: у части пользователей, по IPv6, в мониторинге, в API-клиентах.
Симптомы неправильного default server в Nginx
- Добавили новый сайт, но Nginx продолжает отдавать сертификат «старого» сайта.
- Один домен работает, второй получает сертификат первого домена.
- При наличии IPv6 проблема проявляется только по AAAA.
Правильный дефолтный сервер на 443: «глушилка»
Практичный подход — отдельный дефолтный server block, который явно помечен default_server, использует нейтральный сертификат и возвращает короткий ответ. Часто используют return 444; (Nginx закроет соединение), либо 400/421 по вашей политике.
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_certificate /etc/ssl/certs/default/fullchain.pem;
ssl_certificate_key /etc/ssl/private/default/privkey.pem;
return 444;
}
А каждый реальный сайт должен иметь свой server block с корректным server_name и своим сертификатом:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/private/example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
Где чаще всего ошибаются с nginx server_name
- Опечатка в домене или лишняя точка.
- Забыли
www(или наоборот), а сертификат выписан на оба имени. - Слишком общий wildcard в одном месте перекрывает ожидания в другом.
- Дубликаты
server_nameв разных include-файлах: Nginx выберет один (обычно первый), а второй будет «жить своей жизнью».
Проверка, какой сервер Nginx считает default и какие имена видит
nginx -T
Команда печатает итоговую конфигурацию со всеми include. Ищите блоки listen 443, отметки default_server и соответствие server_name доменам и сертификатам.
Если размещаете много сайтов и хотите предсказуемо контролировать IPv4/IPv6, порядок include и TLS-настройки без сюрпризов, удобнее делать это на отдельном сервере: на VDS проще держать конфигурацию Nginx/Apache «под себя».
Apache: порядок vhost, выбор сертификата и «первый» виртуальный хост
В Apache ситуация исторически сложнее из-за разных поколений конфигурации, но принцип тот же: для HTTPS сертификат выбирается до обработки HTTP-заголовков. С SNI Apache способен отдать правильный сертификат для нужного имени. Без SNI (или при несовпадении) он отдаст сертификат из дефолтного vhost — обычно это первый объявленный виртуальный хост на этом адресе:порту.
Почему «первый» становится дефолтом
Если у вас несколько vhost вида <VirtualHost *:443>, Apache пытается сматчить имя по SNI и ServerName/ServerAlias. Но если матч не найден, в игру вступает «первый». Поэтому не стоит держать «боевой» домен первым, если сервер обслуживает много сайтов.
Что делать с NameVirtualHost
NameVirtualHost — директива из старых версий Apache (в 2.4 обычно не требуется). В смешанных конфигурациях она иногда встречается, и администраторы пытаются «лечить» ею HTTPS-проблемы.
На практике лечится это не NameVirtualHost, а корректной структурой vhost на 443, отсутствием дублей и предсказуемым дефолтом. Если вы видите NameVirtualHost *:443, проверьте версию Apache и не дублируются ли определения: дубли могут приводить к неожиданному wrong vhost.
Пример «дефолтного» Apache vhost на 443
<VirtualHost *:443>
ServerName default.invalid
SSLEngine on
SSLCertificateFile /etc/ssl/certs/default/fullchain.pem
SSLCertificateKeyFile /etc/ssl/private/default/privkey.pem
<Location />
Require all denied
</Location>
</VirtualHost>
Затем — реальные сайты отдельными vhost, где имя и сертификат совпадают:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com/fullchain.pem
SSLCertificateKeyFile /etc/ssl/private/example.com/privkey.pem
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
Если хотите освежить в памяти различия подходов и типовые грабли при миграциях конфигов, держите ссылку: сравнение Nginx и Apache для админов: синтаксис, vhost и практические отличия.

Сценарии из практики: почему всё «вдруг сломалось»
1) Добавили IPv6 и забыли про него
Очень частый кейс: по IPv4 всё правильно, а по IPv6 браузер видит другой сертификат. Причина — на [::]:443 работает другой default server, либо вообще другой server block/vhost, либо Nginx/Apache слушает IPv6 иначе, чем IPv4.
Диагностика: отдельно проверяйте IPv6-адрес в openssl s_client -connect и убедитесь, что конфиг содержит явный listen [::]:443 там, где нужно.
2) Два server block в Nginx делят одно имя
Когда в разных include-файлах случайно встречается одинаковый server_name example.com, Nginx не «объединяет» их. Он выберет один (обычно первый по порядку загрузки конфигов), а второй будет работать непредсказуемо. Это легко приводит к mismatched certificate: сертификат лежит в одном блоке, а запрос попадает в другой.
3) Клиент без SNI (мониторинг, старый Java, устройство)
Даже если ваш браузер всегда шлёт SNI, какие-то внешние системы могут не слать. Тогда они всегда увидят сертификат default server. Это не всегда «баг», но важно, чтобы дефолтный сертификат не «светил» ваши домены и не пугал пользователей или заказчиков отчётов.
Пошаговый план исправления (runbook)
Зафиксируйте, на каком IP проявляется проблема (IPv4 и IPv6 отдельно). Снимите вывод
openssl s_clientс-servernameи без него.Убедитесь, что нужный vhost/server block существует и содержит корректный
server_name(Nginx) илиServerName/ServerAlias(Apache).Проверьте дефолт на 443: Nginx — явный
listen 443 ssl default_server(и для IPv6 тоже); Apache — отдельный нейтральный vhost первым в порядке загрузки.Проверьте дубли и порядок: Nginx — через
nginx -T; Apache — через вывод загруженной конфигурации вашего дистрибутива (важно увидеть реальный порядок подключений).Сделайте reload конфигурации и сразу повторите
openssl s_clientна IP (IPv4/IPv6).Если проблема осталась — ищите внешний TLS-терминатор: балансировщик, прокси, панель управления, отдельный сервис на 443.
Если конфигов становится много (несколько сайтов, IPv6, разные окружения), проще вынести их на отдельный сервер и держать порядок: на VDS удобно разруливать default vhost, SNI и сертификаты без ограничений виртуального хостинга.
Мини-чеклист: как сделать так, чтобы wrong vhost больше не возвращался
- Держите отдельный дефолтный HTTPS-виртуальный хост (не «боевой» сайт).
- Явно задавайте default для IPv4 и IPv6.
- Не допускайте дублей
server_name/ServerNameв разных файлах. - Проверяйте реальный сертификат на выдаче через
openssl s_clientпри любых изменениях TLS/виртуальных хостов. - Документируйте, какой vhost является default и зачем.
Если параллельно настраиваете «внешнюю» безопасность сайта, проверьте и заголовки: неправильный vhost иногда тянет за собой чужие политики HSTS/CSP. По теме: настройка security headers в Nginx/Apache.


