К основному содержимому

HSTS: принудительный HTTPS для защиты сайта

Безопасность · 19.04.2026 · 4 мин чтения
Иллюстрация к статье «HSTS: принудительный HTTPS для защиты сайта»

HSTS (HTTP Strict Transport Security) — заголовок, который инструктирует браузер всегда использовать HTTPS для вашего домена, даже если пользователь набрал http://. Это защита от SSL-stripping атак и случайного перехода по HTTP.

Как работает HSTS

  1. Браузер впервые посещает сайт по HTTPS
  2. Получает заголовок Strict-Transport-Security
  3. Сохраняет домен в список HSTS на время max-age
  4. При следующем визите — автоматически открывает HTTPS без редиректа с сервера

Настройка через .htaccess

<IfModule mod_headers.c>
    # Базовый HSTS: 1 год
    Header always set Strict-Transport-Security "max-age=31536000"
    
    # С включением поддоменов
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    
    # С preload (для включения в браузерный список)
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

Настройка через Nginx

server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
⚠️ Начните с max-age=300 (5 минут) для тестирования. Переключитесь на 31536000 только после того, как убедитесь что HTTPS работает идеально на всех поддоменах.

HSTS Preload

Директива preload позволяет добавить домен в встроенные списки браузеров. Это означает, что HTTPS будет форсироваться даже при первом посещении (до получения заголовка):

  • Подать заявку: hstspreload.org
  • Требования: max-age не менее 1 года, includeSubDomains, действующий HTTPS на поддоменах
💡 После включения в preload-список удаление занимает месяцы. Добавляйте только если уверены, что HTTPS будет постоянным.

Проверка HSTS

# curl
curl -I https://example.com | grep Strict

# Или Chrome DevTools:
# Network → ваш запрос → Response Headers → Strict-Transport-Security

Разбор типичных ошибок с HSTS

  • NET::ERR_CERT_AUTHORITY_INVALID без кнопки «Перейти всё равно» — на HSTS-домене браузер не даёт обойти ошибку сертификата, как на обычном сайте. Если сертификат просрочен или выпущен для другого домена, сайт становится полностью недоступен до починки сертификата, а не просто «небезопасным».
  • net::ERR_SSL_PROTOCOL_ERROR на поддомене при включённом includeSubDomains — если хотя бы у одного поддомена нет рабочего HTTPS, браузер всё равно принудительно обращается к нему по HTTPS и получает ошибку соединения вместо мягкого отката на HTTP.
  • net::ERR_TOO_MANY_REDIRECTS — типичный результат, когда редирект на HTTPS настроен одновременно и на CDN или балансировщике, и на самом сервере: два редиректа зацикливаются друг на друге.
  • Заголовок Strict-Transport-Security, отправленный по обычному HTTP-соединению, браузер обязан проигнорировать по спецификации — если конфиг отдаёт его и на http, и на https, защита самого первого захода всё равно не появляется без включения в preload-список.
  • Страница chrome://net-internals/#hsts — встроенный инструмент Chrome для проверки и ручного удаления локальной HSTS-записи браузера по конкретному домену, без ожидания истечения max-age.

Значения max-age: что когда выставлять

Значение max-ageПродолжительностьКогда использоватьРиск
3005 минутТестирование настройки на реальном трафикеМинимальный — откатывается почти мгновенно
864001 суткиПервый этап продакшена после успешного тестаОшибку ещё можно исправить в течение суток
259200030 сутокСтабильная работа HTTPS без нареканийНужно поддерживать сертификат весь этот период без сбоев
315360001 годФинальная стадия, обязательное условие для preloadОткат недоступен для посетителей с уже сохранённой записью до истечения срока

Когда HSTS ещё рано включать

  • Сайт периодически обслуживает часть трафика по HTTP для легаси-интеграций — старых платёжных шлюзов или IoT-устройств без поддержки TLS — HSTS с длинным max-age сделает такие интеграции недоступными сразу для всех браузерных клиентов.
  • Поддомены выдаются пользователям автоматически, например SaaS на wildcard-домене, и не все гарантированно получают сертификат сразу — includeSubDomains заблокирует доступ к ещё не подготовленным поддоменам.
  • Домен используется для локальной разработки или тестового стенда с самоподписанным сертификатом — HSTS с длинным сроком превратит любые дальнейшие эксперименты с сертификатами в необходимость вручную чистить настройки каждого браузера.
  • Есть шанс, что домен придётся временно вернуть на HTTP — при миграции или смене CDN без TLS-терминации — preload-список редактируется медленно, удаление из него занимает месяцы, а до этого ни один браузер не откроет сайт по HTTP вообще.

Проверка, что HSTS реально защищает

# Проверить заголовок и его значение
curl -sI https://example.com | grep -i strict-transport-security

# Убедиться, что HTTP-версия того же домена всё ещё редиректит на HTTPS
curl -sI http://example.com | grep -i location

# В Chrome: chrome://net-internals/#hsts → Query domain → ввести домен

Поле static_sts_domain в результате запроса означает, что домен зашит в preload-список браузера, а не просто хранится в локальном кеше после первого визита. Это разные состояния: запись из кеша исчезнет сама по истечении max-age, запись из preload-списка — нет.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке