- Опубликовано: 26 июл 2026
- 18
HTTPS включён, а браузер всё равно ругается: SSL без паники
Часть 6 из 14 · Серия «Хостинг без магии»
В панели хостинга рядом с доменом появилась отметка:
SSL-сертификат установлен
Автоматическое перенаправление на HTTPS включено. В адресной строке используется:
https://example.com
Но браузер продолжает показывать предупреждение:
Подключение не защищено
или:
NET::ERR_CERT_COMMON_NAME_INVALID
или:
Срок действия сертификата истёк
Иногда главная страница открывается нормально, а форма оплаты — нет. Иногда работает example.com, но не работает www.example.com. Иногда значок замка есть, однако изображения и JavaScript блокируются. После подключения CDN сайт может попасть в бесконечный цикл перенаправлений:
ERR_TOO_MANY_REDIRECTS
Пользователь начинает перевыпускать сертификат, удалять .htaccess, переключать режимы SSL в панели CDN и очищать кэш браузера.
После нескольких изменений проблема может исчезнуть. Но никто уже не понимает, что именно было исправлено и не вернётся ли ошибка при следующем автоматическом продлении.
Как и DNS, HTTPS перестаёт быть мистикой, если разделить его на уровни.
Нужно по очереди проверить:
- ведёт ли домен на правильный сервер;
- отвечает ли сервер на порту 443;
- какой сертификат он фактически показывает;
- входит ли открываемое имя в сертификат;
- действителен ли срок сертификата;
- может ли браузер построить цепочку доверия;
- не загружает ли страница ресурсы по HTTP;
- не спорят ли между собой несколько перенаправлений;
- не находится ли между пользователем и сайтом CDN или другой прокси-сервер.
SSL или TLS: как правильно
В панелях хостинга и обычной речи по-прежнему говорят «SSL-сертификат».
Технически современные HTTPS-соединения используют TLS — Transport Layer Security. SSL был более старым предшественником TLS и давно не является актуальным протоколом для современных браузеров. Однако выражения «SSL-сертификат», «подключить SSL» и «ошибка SSL» сохранились как привычные названия.
В этой статье будем использовать оба слова:
- TLS — когда говорим о протоколе;
- SSL-сертификат — как привычное название услуги в панели.
Что на самом деле делает HTTPS
Обычный HTTP передаёт запросы и ответы без защиты транспортного канала.
HTTPS добавляет TLS между браузером и сервером.
Упрощённо:
Браузер
│
│ зашифрованное TLS-соединение
▼
Веб-сервер
│
▼
PHP, приложение, база данных
TLS решает две основные задачи:
- шифрует данные при передаче;
- позволяет клиенту проверить, с каким сервером установлено соединение.
Для подтверждения личности сервер показывает цифровой сертификат, выданный центром сертификации. Браузер проверяет сертификат, имя сайта и цепочку до доверенного корневого центра.
HTTPS не гарантирует, что:
- сайт не содержит уязвимостей;
- владелец сайта добросовестен;
- сервер не заражён;
- база надёжно защищена;
- пароль пользователя невозможно украсть через ошибку приложения;
- резервные копии существуют.
HTTPS защищает канал связи и подтверждает идентичность узла, но не заменяет безопасность самого приложения.
В каком порядке устанавливается соединение
Когда пользователь открывает:
https://example.com/catalog
происходит несколько отдельных этапов:
1. DNS
example.com → IP-адрес
2. Сеть
подключение к IP на порту 443
3. TLS
сервер показывает сертификат
4. Проверка
имя, срок, издатель и цепочка доверия
5. HTTP
браузер отправляет запрос /catalog
6. Приложение
сервер формирует страницу
7. Ресурсы
браузер загружает CSS, JS, изображения и шрифты
Ошибка на каждом уровне выглядит по-разному.
Если домен ведёт не на тот сервер, браузер увидит чужой сертификат.
Если сертификат правильный, но приложение возвращает 500, проблема находится уже после TLS.
Если HTML загружается по HTTPS, а JavaScript — по HTTP, соединение с основной страницей исправно, но возникает mixed content.
Сначала определите точный тип ошибки
Фраза «браузер ругается на SSL» слишком общая.
Зафиксируйте:
Домен:
example.com
Проблемный адрес:
https://www.example.com/checkout
Текст ошибки:
NET::ERR_CERT_COMMON_NAME_INVALID
Дата и время:
22 июля 2026, 11:30
Работает ли:
https://example.com — да
https://www.example.com — нет
Последние изменения:
подключён новый хостинг и выпущен сертификат
Разные сообщения требуют разных проверок.
| Сообщение или симптом | Где искать |
|---|---|
| Имя сертификата не совпадает | Состав сертификата, DNS или виртуальный хост |
| Сертификат истёк | Автопродление, установка нового файла |
| Сертификат ещё не действует | Время сервера или компьютера, неверный сертификат |
| Неизвестный издатель | Самоподписанный сертификат или неполная цепочка |
| Соединение отклонено | Порт 443 или веб-сервер |
| Бесконечный редирект | Правила HTTP→HTTPS, CDN или приложение |
| Страница без замка | Mixed content или небезопасная форма |
| Ресурсы заблокированы | HTTP-ссылки внутри HTTPS-страницы |
| Ошибка только на части устройств | Цепочка, старые клиенты, кэш или время устройства |
| Открывается чужой сертификат | DNS ведёт на другой сервер либо неверная SNI-конфигурация |
Не перевыпускайте сертификат до того, как определили класс ошибки.
Шаг 1. Ещё раз проверьте DNS
Сертификат устанавливается на сервере, но браузер приходит к нему по адресу из DNS.
Проверяем IPv4:
dig +short example.com A
IPv6:
dig +short example.com AAAA
Отдельно www:
dig +short www.example.com A
dig +short www.example.com AAAA
dig +short www.example.com CNAME
Если A-запись ведёт на новый сервер, а AAAA — на старый, часть посетителей будет получать сертификат старого хостинга.
Если example.com и www.example.com указывают на разные серверы, каждый должен быть настроен и иметь подходящий сертификат.
Проверить публичные резолверы:
dig +short @1.1.1.1 example.com A
dig +short @8.8.8.8 example.com A
Если DNS неправильный, перевыпуск сертификата на новом сервере не изменит сертификат, который показывает старый.
Шаг 2. Проверьте, отвечает ли порт 443
Простой тест:
curl -Iv https://example.com/
Возможные результаты.
Домен не разрешается
Could not resolve host
Проблема находится в DNS.
Соединение отклонено
Connection refused
IP найден, но на порту 443 никто не принимает соединение.
Возможные причины:
- HTTPS не включён на веб-сервере;
- порт закрыт;
- сервер выключен;
- firewall блокирует соединение;
- DNS ведёт не на тот IP.
Соединение зависает
Connection timed out
Адрес найден, но сетевое соединение не устанавливается. Проверяйте firewall, маршрутизацию и доступность сервера.
Сертификат отклонён
SSL certificate problem
Соединение дошло до TLS, но проверка сертификата не прошла.
Получен HTTP-ответ
HTTP/2 200
или:
HTTP/2 301
TLS-соединение установилось. Дальше проверяем сертификат, редиректы и содержимое страницы.
Шаг 3. Посмотрите сертификат, который сервер показывает фактически
Панель может утверждать, что новый сертификат установлен. Но важно увидеть, что получает внешний клиент.
Команда:
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null
Параметр:
-servername example.com
передаёт серверу имя сайта. Это важно, потому что на одном IP может находиться много HTTPS-сайтов.
Получить краткую информацию:
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null |
openssl x509 \
-noout \
-subject \
-issuer \
-dates \
-ext subjectAltName
Пример:
subject=CN = example.com
issuer=C = US, O = Let's Encrypt, CN = ...
notBefore=Jul 20 09:00:00 2026 GMT
notAfter=Oct 18 08:59:59 2026 GMT
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com
Здесь видны:
- имя владельца сертификата;
- центр сертификации;
- начало срока действия;
- окончание срока;
- список доменных имён.
Почему имя в сертификате должно совпадать с доменом
Браузер проверяет не просто наличие любого сертификата, а соответствие сертификата имени, которое пользователь открыл.
Сертификат для:
example.com
не должен автоматически считаться сертификатом для:
shop.example.com
Проверка имени выполняется по DNS-именам, указанным в сертификате, прежде всего в расширении Subject Alternative Name. Современные рекомендации требуют сопоставлять имя сервиса с идентификаторами, представленными серверным сертификатом.
Проверить имя через OpenSSL:
openssl s_client \
-connect example.com:443 \
-servername example.com \
-verify_hostname example.com \
</dev/null
В конце успешной проверки:
Verify return code: 0 (ok)
example.com и www.example.com требуют отдельного покрытия
Это два разных DNS-имени:
example.com
www.example.com
Сертификат может включать оба:
DNS:example.com
DNS:www.example.com
Но если в сертификате указано только:
DNS:example.com
адрес:
https://www.example.com
может вызвать ошибку несовпадения имени.
Проверяйте оба варианта:
curl -Iv https://example.com/
curl -Iv https://www.example.com/
И отдельно сертификаты:
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null |
openssl x509 -noout -ext subjectAltName
openssl s_client \
-connect www.example.com:443 \
-servername www.example.com \
</dev/null 2>/dev/null |
openssl x509 -noout -ext subjectAltName
Даже если оба имени ведут на один IP, веб-сервер должен выбирать для каждого подходящий сертификат.
Wildcard-сертификат не означает «вообще все адреса»
Wildcard выглядит так:
*.example.com
Он предназначен для поддоменов одного уровня, например:
www.example.com
shop.example.com
api.example.com
Но корневое имя:
example.com
следует включать в сертификат отдельно.
Также обычный wildcard первого уровня не следует считать сертификатом для более глубокого имени:
admin.shop.example.com
При выпуске wildcard-сертификатов через Let’s Encrypt используется DNS-проверка владения доменом.
Практический набор имён часто выглядит так:
example.com
*.example.com
Но wildcard нужен далеко не каждому сайту. Для example.com и www.example.com проще выпустить обычный сертификат на два имени.
Шаг 4. Проверьте срок действия
Команда:
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null |
openssl x509 -noout -dates
Результат:
notBefore=Jul 20 09:00:00 2026 GMT
notAfter=Oct 18 08:59:59 2026 GMT
Проверяем два значения.
notBefore
Сертификат нельзя использовать раньше указанного момента.
Ошибка может появиться, если:
- на компьютере пользователя неверная дата;
- сертификат выпущен с будущим временем;
- сервер показывает не тот сертификат;
- часы системы серьёзно расходятся.
notAfter
После этого момента сертификат считается просроченным.
Если панель уже выпустила новый сертификат, но браузер видит старый, возможно:
- веб-сервер не перезагрузил конфигурацию;
- новый сертификат установлен не на тот сайт;
- CDN продолжает показывать собственный старый сертификат;
- часть узлов балансировщика не обновилась;
- DNS ведёт на старый сервер;
- IPv6 указывает на другой хост.
Само наличие нового файла сертификата не означает, что сервер начал его отдавать.
Неверная дата на компьютере тоже вызывает предупреждение
Сертификат проверяется относительно текущего времени клиента.
Если компьютер считает, что сейчас 2023 или 2030 год, корректный сертификат может выглядеть:
- ещё не вступившим в силу;
- уже просроченным.
Если проблема существует только на одном устройстве, проверьте:
- дату;
- время;
- часовой пояс;
- автоматическую синхронизацию часов.
Особенно часто такая проблема появляется на:
- старом компьютере;
- устройстве после полной разрядки;
- виртуальной машине;
- смартфоне без синхронизации времени.
Шаг 5. Проверьте издателя и цепочку доверия
Браузер обычно доверяет не каждому сертификату напрямую.
Цепочка выглядит так:
Сертификат сайта
↓ подписан
Промежуточным центром
↓ подписан
Корневым центром
↓ уже доверен браузеру или ОС
Промежуточные сертификаты позволяют центру сертификации не использовать корневой закрытый ключ для повседневной выдачи. Клиент строит цепочку от сертификата сайта через промежуточные сертификаты до известного доверенного корня.
Посмотреть все сертификаты, переданные сервером:
openssl s_client \
-connect example.com:443 \
-servername example.com \
-showcerts \
</dev/null
Проверить итог:
Verify return code: 0 (ok)
Если вместо этого появляется ошибка наподобие:
unable to get local issuer certificate
возможна неполная цепочка.
Сертификат сайта и fullchain — не одно и то же
При ручной настройке серверу часто требуется не только сертификат домена, но и файл полной цепочки.
Условно:
cert.pem → только сертификат сайта
chain.pem → промежуточные сертификаты
fullchain.pem → сертификат сайта + промежуточные
privkey.pem → закрытый ключ
Если веб-серверу передали только сертификат сайта, современный настольный браузер иногда сумеет достроить цепочку самостоятельно, а другой клиент — нет.
Симптомы:
- сайт работает в одном браузере;
- мобильное приложение отклоняет сертификат;
curlсообщает об ошибке;- старое устройство не доверяет цепочке;
- внешний API не может подключиться.
Для веб-сервера следует использовать конфигурацию, рекомендованную центром сертификации или панелью хостинга, а не случайный PEM-файл.
Самоподписанный сертификат
Самоподписанный сертификат создан и подписан самим владельцем, а не общедоверенным центром сертификации.
Шифрование при этом возможно, но браузер не имеет основания доверять личности сервера.
Такой сертификат подходит для:
- закрытой локальной среды;
- тестового стенда;
- внутреннего сервиса;
- инфраструктуры, где собственный корневой сертификат установлен на все устройства.
Для публичного сайта посетители увидят предупреждение.
Не советуйте пользователям нажимать «Продолжить» на рабочем интернет-магазине. Установите сертификат от доверенного центра.
Шаг 6. Убедитесь, что сервер показывает сертификат нужного сайта
На одном IP может работать много HTTPS-сайтов:
203.0.113.25
├── example.com
├── shop.example.net
└── blog.example.org
Клиент передаёт имя через SNI, а веб-сервер выбирает соответствующую конфигурацию и сертификат.
Если сайт настроен неправильно, сервер может показать сертификат другого домена или стандартной заглушки.
Проверка с правильным именем:
openssl s_client \
-connect 203.0.113.25:443 \
-servername example.com \
</dev/null 2>/dev/null |
openssl x509 \
-noout \
-subject \
-ext subjectAltName
Проверка другого имени на том же IP:
openssl s_client \
-connect 203.0.113.25:443 \
-servername shop.example.net \
</dev/null 2>/dev/null |
openssl x509 \
-noout \
-subject \
-ext subjectAltName
Если example.com получает чужой сертификат, возможные причины:
- домен не добавлен как HTTPS-имя;
- сертификат привязан к другому сайту;
- конфигурация веб-сервера не применена;
- используется неправильный IP;
- балансировщик не знает домен;
- часть серверов кластера не обновлена.
Как проверить новый сервер без изменения DNS
Используйте:
curl \
--resolve example.com:443:203.0.113.25 \
-Iv \
https://example.com/
Команда:
- подключится к указанному IP;
- передаст имя
example.com; - использует его для SNI;
- проверит сертификат именно для
example.com.
Это удобнее открытия IP в браузере.
Запрос:
https://203.0.113.25
проверяет сертификат для IP-адреса, а не для домена, и может попасть в стандартный виртуальный хост.
Шаг 7. Разберитесь, почему сертификат не выпускается
Автоматический выпуск обычно требует подтверждения контроля над доменом.
При HTTP-01-проверке центр сертификации запрашивает специальный файл:
http://example.com/.well-known/acme-challenge/TOKEN
ACME-клиент должен разместить токен на веб-сервере, доступном по домену. Let’s Encrypt описывает HTTP-01 именно как получение файла по этому пути; для такого метода нужен доступ к HTTP на порту 80.
Выпуск может завершиться ошибкой, если:
- домен ещё ведёт на старый сервер;
- неверна AAAA-запись;
- порт 80 закрыт;
- запрос блокирует firewall;
/.well-known/закрыт паролем;- rewrite отправляет запрос в приложение;
- CDN отвечает не с того origin;
- домен добавлен не в тот аккаунт;
- существует бесконечный HTTP-редирект;
- сервер отдаёт 403 или 404 для challenge-файла.
Проверить путь вручную:
mkdir -p public/.well-known/acme-challenge
echo "acme-test" \
> public/.well-known/acme-challenge/test.txt
Затем:
curl \
http://example.com/.well-known/acme-challenge/test.txt
Ожидаемый ответ:
acme-test
После проверки тестовый файл удаляется.
DNS-01-проверка
При DNS-01 создаётся TXT-запись:
_acme-challenge.example.com
Этот способ полезен:
- для wildcard-сертификатов;
- когда сервер не доступен напрямую по HTTP;
- при централизованном выпуске;
- для внутренних origin-серверов.
Let’s Encrypt подтверждает, что DNS-01 позволяет выпускать wildcard-сертификаты и может делегироваться через CNAME или NS для специальной зоны проверки.
Но ручное обновление TXT-записи неудобно для регулярного автоматического продления. Безопаснее использовать DNS API с ограниченными правами, если провайдер это поддерживает.
Не закрывайте порт 80 только потому, что сайт работает по HTTPS
Обычная схема:
http://example.com
↓ 301
https://example.com
Открытый порт 80 позволяет:
- перенаправить пользователя на HTTPS;
- выполнить HTTP-01-проверку;
- корректно обслужить старые ссылки;
- избежать неясного сетевого тайм-аута.
Let’s Encrypt рекомендует сохранять порт 80 доступным для обычных веб-сайтов и перенаправлять HTTP-запросы на HTTPS. Если это невозможно, применяются DNS-01 или TLS-ALPN-01.
Шаг 8. Проверьте перенаправление HTTP → HTTPS
Команда:
curl -I http://example.com/
Ожидаемо:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
Затем:
curl -I https://example.com/
Ожидаемо:
HTTP/2 200
Посмотреть всю цепочку:
curl \
-IL \
--max-redirs 10 \
http://example.com/
Хорошая цепочка:
http://example.com
↓ 301
https://example.com
↓ 200
Допустимая, но более длинная:
http://www.example.com
↓ 301
https://www.example.com
↓ 301
https://example.com
↓ 200
Лучше избегать лишних шагов, если можно сразу перенаправить на окончательный адрес.
Бесконечный цикл перенаправлений
Типичный цикл:
HTTP → HTTPS → HTTP → HTTPS → ...
Браузер показывает:
ERR_TOO_MANY_REDIRECTS
Это не ошибка сертификата. TLS может работать правильно, но правила HTTP спорят друг с другом.
Причина №1. Редирект настроен в нескольких местах
HTTPS одновременно принудительно включают:
- панель хостинга;
.htaccess;- nginx;
- CMS;
- плагин;
- CDN;
- приложение.
Одно правило направляет на www, другое — без www.
Получается:
https://example.com
↓
https://www.example.com
↓
https://example.com
Выберите один канонический адрес:
https://example.com
или:
https://www.example.com
И согласуйте все правила.
Причина №2. Приложение находится за прокси
Пользователь подключается по HTTPS к CDN:
Пользователь
│ HTTPS
▼
CDN
│ HTTP
▼
Origin-сервер
Origin видит HTTP и отвечает:
Перейдите на HTTPS
CDN снова запрашивает origin по HTTP. Цикл повторяется.
Приложение должно доверять корректно настроенному прокси и учитывать переданный исходный протокол, обычно через информацию наподобие:
X-Forwarded-Proto: https
Доверять таким заголовкам от произвольного клиента нельзя: список доверенных прокси должен быть ограничен инфраструктурой проекта.
Причина №3. Неверный адрес приложения
В конфигурации осталось:
APP_URL=http://example.com
Приложение генерирует HTTP-ссылки или перенаправления, а веб-сервер возвращает их на HTTPS.
После изменения конфигурации может потребоваться очистка кэша.
Для Laravel:
php artisan optimize:clear
php artisan optimize
Для CMS проверьте основной URL сайта в настройках и базе.
Шаг 9. Mixed content: HTTPS есть, но страница всё равно небезопасна
Главный HTML загружается по HTTPS:
https://example.com/
Но внутри него остаются ресурсы:
<script src="http://example.com/app.js"></script>
<img src="http://example.com/photo.jpg">
<link rel="stylesheet" href="http://example.com/style.css">
Это называется mixed content: защищённая страница пытается загрузить часть содержимого по незащищённому HTTP. Браузеры могут автоматически повышать некоторые запросы до HTTPS, а более опасные типы — блокировать.
Симптомы:
- нет значка защищённого соединения;
- не загружается JavaScript;
- пропадают стили;
- форма перестаёт работать;
- изображения не отображаются;
- в консоли браузера появляются сообщения
Mixed Content.
Где искать HTTP-ссылки
Проверяйте:
- HTML-шаблоны;
- CSS;
- JavaScript;
- базу данных CMS;
- настройки основного URL;
- виджеты;
- сторонние шрифты;
- рекламные скрипты;
- iframe;
- изображения в старых статьях;
- API-адреса;
- WebSocket-подключения.
Найти в файлах:
grep \
-RIn \
--exclude-dir=vendor \
--exclude-dir=node_modules \
'http://example.com' \
.
Найти любые HTTP-ссылки:
grep \
-RInE \
--exclude-dir=vendor \
--exclude-dir=node_modules \
'http://[^"'"'"' )]+' \
.
В CMS ссылки могут находиться не в файлах, а в базе данных.
Не заменяйте http:// на https:// вслепую
Массовая замена может повредить:
- сериализованные данные;
- внешние адреса, не поддерживающие HTTPS;
- API-конфигурацию;
- служебные ссылки;
- подписи и хэши;
- резервные копии SQL.
Для WordPress и других CMS используйте инструменты, которые понимают структуру данных.
Перед изменением базы создайте резервную копию.
Протокол-относительные ссылки
Раньше часто использовали:
<script src="//cdn.example.com/app.js"></script>
Браузер выбирал протокол текущей страницы.
Сегодня понятнее явно указывать HTTPS:
<script src="https://cdn.example.com/app.js"></script>
Это упрощает аудит и не оставляет двусмысленности.
upgrade-insecure-requests не заменяет исправление сайта
Content Security Policy может потребовать от браузера повышать небезопасные запросы:
Content-Security-Policy: upgrade-insecure-requests
Это полезный страховочный механизм при миграции, но он не исправляет:
- внешние ресурсы без HTTPS;
- неверные URL в базе;
- API, доступный только по HTTP;
- серверные запросы;
- старые ссылки вне браузера.
Сначала исправьте источники ссылок, затем используйте политику как дополнительную защиту.
Шаг 10. Проверьте формы, WebSocket и API
Страница может выглядеть защищённой, но отправлять данные на HTTP-адрес:
<form action="http://example.com/login">
или обращаться к API:
fetch("http://api.example.com/orders");
Для WebSocket защищённой странице обычно нужен:
wss://
вместо:
ws://
Проверяйте вкладки браузерных инструментов:
- Console;
- Network;
- Security.
Фильтруйте запросы по:
http://
ws://
blocked
mixed-content
Шаг 11. CDN создаёт два TLS-соединения
При использовании CDN или reverse proxy схема выглядит так:
Пользователь
│ TLS №1
▼
CDN
│ TLS №2 или HTTP
▼
Origin-сервер
Поэтому нужно различать:
- сертификат, который CDN показывает посетителю;
- сертификат origin-сервера;
- режим соединения CDN с origin.
Посетитель может видеть исправный сертификат CDN, хотя origin использует:
- просроченный сертификат;
- самоподписанный сертификат;
- сертификат другого домена;
- обычный HTTP.
И наоборот: origin может быть настроен правильно, а на CDN ещё не выпущен сертификат для нового имени.
Ошибка только при включённом CDN
Проверьте origin напрямую:
curl \
--resolve example.com:443:ORIGIN_IP \
-Iv \
https://example.com/
Если origin работает, а через CDN нет, проблема находится в:
- сертификате edge;
- режиме SSL;
- кэше;
- redirect rules;
- настройках origin;
- проверке имени origin;
- firewall, который блокирует CDN;
- списке разрешённых доменов.
Не отключайте проверку сертификата origin как постоянное решение. Лучше установить корректный сертификат и использовать строгую проверку.
Шаг 12. Проверьте HSTS до его включения
HSTS — HTTP Strict Transport Security.
Сервер отправляет заголовок:
Strict-Transport-Security: max-age=31536000
После этого браузер запоминает, что домен нужно открывать только через HTTPS.
Он может автоматически заменить:
http://example.com
на:
https://example.com
до отправки HTTP-запроса.
RFC 6797 определяет механизм HSTS, а MDN отмечает важное поведение: если у известного HSTS-домена возникает ошибка сертификата, браузер не должен предлагать пользователю просто проигнорировать предупреждение.
Почему HSTS опасно включать слишком рано
Если вы отправили:
Strict-Transport-Security:
max-age=31536000;
includeSubDomains
браузер будет требовать исправный HTTPS не только для основного домена, но и для поддоменов.
Проблемы возникнут, если:
- старый поддомен не поддерживает HTTPS;
- тестовый сервер использует самоподписанный сертификат;
- почтовая веб-панель работает только по HTTP;
- забытый сервис не имеет сертификата;
- сертификат основного сайта перестал продлеваться.
Сначала добейтесь стабильной работы HTTPS на всех нужных именах.
Начать можно с малого значения:
Strict-Transport-Security: max-age=300
Затем постепенно увеличить срок.
includeSubDomains
Параметр:
includeSubDomains
распространяет политику на поддомены.
Не добавляйте его, пока не проверены:
www.example.com
shop.example.com
api.example.com
mail.example.com
старые и технические поддомены
HSTS preload
Preload-список встраивается в браузеры.
Это сильная мера, отмена которой занимает время и не сводится к удалению одного заголовка на сервере.
Не включайте preload ради высокой оценки в автоматическом тесте. Сначала убедитесь, что организация готова поддерживать HTTPS для домена и поддоменов постоянно.
Почему очистка cookies иногда помогает при редиректе
Cookie может быть привязан к:
- домену;
- пути;
- протоколу через флаг
Secure; - состоянию авторизации;
- старой конфигурации приложения.
После перехода с HTTP на HTTPS могут сохраниться:
- конфликтующие сессии;
- старый канонический адрес;
- неверный redirect target;
- cookie от
wwwи корневого домена; - авторизационное состояние старой версии сайта.
Поэтому при ERR_TOO_MANY_REDIRECTS полезно:
- проверить цепочку через
curl; - открыть приватное окно;
- удалить cookies только проблемного домена.
Но очистка cookies не исправляет серверный цикл. Она лишь помогает отделить состояние браузера от конфигурации сайта.
Почему проблема возникает только у части пользователей
Возможные причины:
Разные DNS-ответы
Часть клиентов приходит на старый сервер.
IPv4 и IPv6 ведут на разные узлы
По IPv4 сертификат правильный, по IPv6 — чужой.
Несогласованный балансировщик
Один frontend обновил сертификат, другой — нет.
Неполная цепочка
Некоторые устройства достраивают её, другие не могут.
Устаревшая система доверия
Старое устройство не знает новый корневой центр или не поддерживает современную конфигурацию TLS.
Неверное время
Проблема существует на одном устройстве.
Кэш и HSTS
Браузер помнит старую политику или перенаправление.
При такой жалобе спрашивайте:
- устройство;
- операционную систему;
- браузер;
- сеть;
- точное время;
- текст ошибки;
- работает ли другой домен;
- какой IP получает устройство.
Безопасная конфигурация TLS
Кроме наличия сертификата важна конфигурация протокола.
Старые версии SSL/TLS и устаревшие наборы шифров не следует включать только ради очень старых клиентов. Современные рекомендации по безопасному использованию TLS собраны в RFC 9325.
На управляемом виртуальном хостинге эту конфигурацию обычно поддерживает провайдер.
На VPS администратор отвечает за:
- версии TLS;
- наборы шифров;
- цепочку;
- обновление веб-сервера;
- автоматическое продление;
- перезагрузку конфигурации;
- мониторинг срока сертификата.
Не копируйте конфигурацию десятилетней давности из случайной статьи.
Автоматическое продление нужно проверять
Сертификат успешно выпустился один раз. Это ещё не означает, что он будет продлеваться всегда.
Продлению могут помешать:
- изменение DNS;
- удаление домена из панели;
- закрытие порта 80;
- блокировка
/.well-known; - новая AAAA-запись;
- CDN;
- истёкший API-токен DNS;
- недостаточные права;
- ошибка ACME-клиента;
- переполненный диск;
- сбой перезагрузки веб-сервера.
После настройки проверьте:
- дату следующего продления;
- журнал ACME-клиента;
- уведомления об ошибках;
- фактически отдаваемый сертификат;
- мониторинг срока действия.
На управляемом хостинге выпуском и продлением обычно занимается панель. Но владелец сайта всё равно должен получать уведомление, если автоматизация не сработала.
Как это устроено на Siteko. Бесплатный Let's Encrypt входит во все тарифы, включая младший Start. Сертификат выпускается из панели — раздел «SSL-сертификаты», вариант Let's Encrypt — и продлевается автоматически. Главное условие то же, что описано выше: на момент выпуска домен уже должен вести на сервер хостинга, иначе HTTP-01-проверка не пройдёт. Если настраивать самостоятельно не хочется, поддержка бесплатно выпустит сертификат и проверит HTTPS. Платный сертификат тоже можно оформить, но для большинства сайтов, включая интернет-магазины, Let's Encrypt закрывает задачу полностью.
Мониторинг сертификата
Не ждите сообщения от клиента.
Проверку можно автоматизировать:
echo |
openssl s_client \
-connect example.com:443 \
-servername example.com \
2>/dev/null |
openssl x509 \
-noout \
-enddate
Результат:
notAfter=Oct 18 08:59:59 2026 GMT
Проверка, действует ли сертификат ещё минимум 30 дней:
echo |
openssl s_client \
-connect example.com:443 \
-servername example.com \
2>/dev/null |
openssl x509 \
-noout \
-checkend 2592000
Где:
2592000 секунд = 30 дней
Код завершения:
0 — сертификат действует дольше указанного срока
1 — истечёт раньше
Для нескольких доменов нужен внешний мониторинг, который проверяет сертификат независимо от самого сервера.
Быстрая диагностика одной командой
DOMAIN="example.com"
echo "=== DNS A ==="
dig +short A "$DOMAIN"
echo
echo "=== DNS AAAA ==="
dig +short AAAA "$DOMAIN"
echo
echo "=== HTTPS HEADERS ==="
curl -Iv "https://$DOMAIN/" 2>&1 | head -n 40
echo
echo "=== CERTIFICATE ==="
openssl s_client \
-connect "$DOMAIN:443" \
-servername "$DOMAIN" \
</dev/null 2>/dev/null |
openssl x509 \
-noout \
-subject \
-issuer \
-dates \
-ext subjectAltName
Для www:
DOMAIN="www.example.com"
запускаем ту же проверку ещё раз.
Пошаговый алгоритм
Шаг 1
Проверяем:
dig +short example.com A
dig +short example.com AAAA
Домен должен вести на ожидаемую инфраструктуру.
Шаг 2
Проверяем порт 443:
curl -Iv https://example.com/
Шаг 3
Смотрим сертификат:
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null |
openssl x509 \
-noout \
-subject \
-issuer \
-dates \
-ext subjectAltName
Шаг 4
Проверяем имя:
Есть ли example.com в Subject Alternative Name?
Есть ли www.example.com?
Шаг 5
Проверяем цепочку:
openssl s_client \
-connect example.com:443 \
-servername example.com \
-showcerts \
</dev/null
Ищем:
Verify return code: 0 (ok)
Шаг 6
Проверяем редиректы:
curl \
-IL \
--max-redirs 10 \
http://example.com/
Шаг 7
Открываем инструменты разработчика и ищем mixed content.
Шаг 8
Если используется CDN, проверяем origin отдельно:
curl \
--resolve example.com:443:ORIGIN_IP \
-Iv \
https://example.com/
Шаг 9
Проверяем HSTS, cookies и кэш только после проверки сервера.
Таблица: ошибка, причина и действие
| Ошибка или симптом | Вероятная причина | Следующее действие |
|---|---|---|
ERR_CERT_COMMON_NAME_INVALID |
Имя отсутствует в сертификате | Проверить SAN, DNS и SNI |
Работает без www |
www не включён в сертификат |
Перевыпустить сертификат на оба имени |
Работает только с www |
Корневой домен не покрыт | Добавить example.com |
| Сертификат истёк | Не сработало продление | Проверить ACME и установить новый сертификат |
| Сертификат ещё не действует | Неверное время или не тот сертификат | Проверить часы и notBefore |
| Неизвестный издатель | Самоподписанный сертификат | Использовать доверенный CA |
unable to get local issuer certificate |
Неполная цепочка | Установить fullchain |
| На одном IP чужой сертификат | Неверный виртуальный хост | Проверить SNI-конфигурацию |
Connection refused |
Порт 443 не обслуживается | Проверить сервер и firewall |
ERR_TOO_MANY_REDIRECTS |
Конфликт правил HTTPS | Проверить всю цепочку редиректов |
| Замка нет, сертификат правильный | Mixed content | Исправить HTTP-ресурсы |
| JS и CSS блокируются | Ресурсы загружаются по HTTP | Проверить Console и Network |
| CDN работает, origin нет | Сертификат origin неверен | Установить сертификат на origin |
| Origin работает, CDN нет | Ошибка edge-сертификата или режима SSL | Проверить CDN |
| Ошибка только по IPv6 | Старая AAAA-запись | Исправить IPv6 |
| Ошибка только на одном ПК | Время, hosts, HSTS или кэш | Проверить локальное устройство |
| Сертификат выпущен, но показывается старый | Сервер не применил новый файл | Перезагрузить конфигурацию |
| ACME возвращает 404 | Challenge-файл недоступен | Проверить /.well-known/ |
| ACME не подключается | Порт 80 закрыт или DNS неверен | Исправить DNS и HTTP-доступ |
| После HSTS нельзя обойти ошибку | Это нормальное поведение HSTS | Сначала исправить сертификат |
Что не следует делать
Не отключайте проверку сертификата
Флаги вроде:
curl -k
полезны только для краткой диагностики.
Они не исправляют сертификат и не должны использоваться в production-интеграциях как постоянное решение.
Не советуйте пользователям игнорировать предупреждение
Если браузер не доверяет сертификату, сначала выясните причину.
Не выпускайте сертификат снова и снова
Повторный выпуск не поможет, если:
- DNS ведёт не туда;
- сервер показывает сертификат другого сайта;
- mixed content находится в HTML;
- работает redirect loop;
- CDN показывает собственный сертификат.
Не включайте HSTS сразу на год
Начните с небольшого срока и проверьте все поддомены.
Не добавляйте includeSubDomains вслепую
Один забытый HTTP-поддомен станет недоступным.
Не заменяйте все строки http:// без резервной копии
Сначала найдите источник и используйте подходящий инструмент миграции.
Не отключайте порт 80 без причины
Он нужен для редиректа и часто для автоматического выпуска сертификата.
Не используйте самоподписанный сертификат на публичном сайте
Он не будет автоматически доверенным для посетителей.
Не проверяйте сертификат только по IP
Используйте доменное имя и SNI.
Не путайте TLS и ошибку приложения
Если HTTPS устанавливается, а сервер возвращает 500, читайте логи PHP и приложения.
Грабли HTTPS
| Грабля | Результат | Решение |
|---|---|---|
| Сертификат выпущен только для корня | www показывает предупреждение |
Включить оба имени |
| Старая AAAA ведёт на другой сервер | Ошибка только у части пользователей | Исправить IPv6 |
Установлен только cert.pem |
Некоторые клиенты не доверяют сайту | Использовать полную цепочку |
| Сертификат обновлён, сервер не перечитал его | Отдаётся старая версия | Применить конфигурацию |
| HTTP→HTTPS включён в пяти местах | Бесконечный редирект | Оставить согласованные правила |
| Прокси не сообщает исходный протокол | Приложение постоянно редиректит | Настроить trusted proxy |
| В базе остались HTTP-ссылки | Mixed content | Выполнить безопасную замену |
| HSTS включён до проверки поддоменов | Часть сервисов недоступна | Вводить HSTS постепенно |
| CDN и origin используют разные режимы | Ошибки и циклы | Проверить оба соединения |
| Порт 80 закрыт | Не продлевается HTTP-01 | Открыть порт или использовать DNS-01 |
| Wildcard считают сертификатом корня | example.com не покрыт |
Добавить корневое имя |
| Сертификат проверяют без SNI | Показывается сертификат заглушки | Передать -servername |
| Не проверяют дату устройства | Ошибка только у одного клиента | Синхронизировать часы |
| Ошибку TLS лечат очисткой CMS-кэша | Ничего не меняется | Проверять уровни по порядку |
Что приложить к обращению в поддержку
Плохое сообщение:
SSL не работает. Исправьте.
Полезное:
Домен:
www.example.com
Ошибка браузера:
NET::ERR_CERT_COMMON_NAME_INVALID
DNS:
example.com → 203.0.113.25
www.example.com → 203.0.113.25
AAAA-записей нет.
Проверка:
curl -Iv https://www.example.com/
Сертификат, который отдаёт сервер:
Subject Alternative Name:
DNS:example.com
Имя www.example.com в сертификате отсутствует.
Срок действия:
notAfter=Oct 18 08:59:59 2026 GMT
Для https://example.com сертификат работает.
Нужно добавить www.example.com и перевыпустить сертификат.
Для ошибки цепочки:
Команда:
openssl s_client \
-connect example.com:443 \
-servername example.com \
-showcerts
Результат:
unable to get local issuer certificate
Предполагаю, что сервер не передаёт промежуточный сертификат.
Для redirect loop:
curl -IL --max-redirs 10 http://example.com/
Цепочка:
http://example.com
→ https://example.com
→ https://www.example.com
→ https://example.com
Такое обращение сразу показывает конкретный уровень проблемы.
Минимальный чек-лист HTTPS
DNS
A ведёт на нужный сервер?
AAAA тоже правильная?
www настроен?
CDN включён осознанно?
Сертификат
Есть ли нужные имена в SAN?
Не истёк ли срок?
Уже начался ли срок действия?
Доверен ли издатель?
Передаётся ли полная цепочка?
Сервер
Открыт ли порт 443?
Привязан ли сертификат к нужному сайту?
Применена ли новая конфигурация?
Работает ли SNI?
Перенаправления
HTTP ведёт на окончательный HTTPS-адрес?
Нет ли цикла www ↔ без www?
Не спорят ли панель, CDN, CMS и .htaccess?
Страница
Нет ли mixed content?
Формы отправляются по HTTPS?
API использует HTTPS?
WebSocket использует wss?
Автоматизация
Может ли ACME пройти проверку?
Доступен ли порт 80?
Работает ли автопродление?
Есть ли мониторинг срока?
HSTS
Все ли поддомены поддерживают HTTPS?
Начали ли с короткого max-age?
Нужен ли includeSubDomains?
Действительно ли нужен preload?
Что в итоге
Сообщение браузера об ошибке SSL не означает, что нужно немедленно перевыпускать сертификат.
Сначала определите уровень:
1. DNS
Домен ведёт на правильный IP?
2. Сеть
Порт 443 отвечает?
3. Сертификат
Сервер показывает нужный сертификат?
4. Проверка
Совпадает ли имя, срок и цепочка?
5. HTTP
Нет ли цикла перенаправлений?
6. Страница
Нет ли mixed content?
7. Прокси
Совпадают ли настройки CDN и origin?
8. Политика
Не мешает ли HSTS диагностике?
Если браузер получает сертификат другого сайта, проверяйте DNS и виртуальный хост.
Если имя не входит в SAN, перевыпускайте сертификат с правильным набором доменов.
Если сертификат корректен, но нет замка, ищите HTTP-ресурсы внутри страницы.
Если появляется ERR_TOO_MANY_REDIRECTS, изучайте правила перенаправлений, а не срок сертификата.
Если проблема возникает только через CDN, проверяйте отдельно посетительское и origin-соединение.
Главный принцип:
HTTPS — это не одна галочка в панели, а цепочка из DNS, TLS, сертификата, веб-сервера, приложения и ресурсов страницы.
После настройки HTTPS сайт может прекрасно открываться, формы работать, а заказы создаваться. Но письма с подтверждением регистрации, восстановления пароля и оформления заказа начинают попадать в спам или не доходят вообще.
В следующей части разберём SMTP, SPF, DKIM и DMARC — и выясним, почему работающая функция mail() ещё не означает нормально настроенную почту.
- 1 Как выбрать хостинг для сайта и не купить себе вторую работу
- 2 Виртуальный хостинг, VPS или облако: что действительно нужно вашему сайту
- 3 Гигабайты ничего не решают: как читать характеристики тарифа хостинга
- 4 «Безлимитный» хостинг: что заканчивается раньше дискового пространства
- 5 Домен подключён, а сайт не открывается: DNS без мистики
- 6 HTTPS включён, а браузер всё равно ругается: SSL без паники вы здесь
- 7 Письма с сайта пропадают: SMTP, SPF, DKIM и DMARC на пальцах скоро
- 8 Современный PHP-хостинг: зачем Laravel и Symfony нужны SSH, Composer, Node.js, cron и отдельная public-директория скоро
- 9 Деплой без FTP на виртуальном хостинге: Git, Composer и безопасный откат скоро
- 10 Ошибка 500 после загрузки сайта: где искать причину до обращения в поддержку скоро
- 11 Сайт тормозит на хостинге: виноват тариф, код, база или внешний сервис скоро
- 12 Бэкап есть — восстановить нельзя: проверяем резервные копии до аварии скоро
- 13 Переезд на другой хостинг без потери сайта, писем и заказов скоро
- 14 Когда виртуальный хостинг стал тесен: пора на VPS или ещё можно остаться скоро
Была статья полезной: