HSTS и HSTS Preload: полное руководство по принудительному HTTPS
HSTS и HSTS Preload: полное руководство по принудительному HTTPS
HTTP Strict Transport Security (HSTS) — механизм безопасности, который говорит браузеру: «для этого домена всегда используй SSL/TLS проверку, даже если пользователь набрал http://». Preload идёт дальше: ваш домен вшивается в браузеры до первой загрузки. Правильно настроенный HSTS защищает от MITM-атак на первом соединении, неправильно — блокирует сайт на месяцы. Разберём, как настроить безопасно.
Как работает HSTS
Сервер отдаёт заголовок Strict-Transport-Security в HTTPS-ответе:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Директивы:
max-age— сколько секунд браузер помнит правило (обычно 1 год = 31536000).includeSubDomains— применяется ко всем поддоменам.preload— готовность к включению в preload-лист (сам лист этим не обновляется).
После получения заголовка браузер кеширует правило. При следующем обращении к http://example.com он не делает запрос — просто внутренне переписывает на https://. Это защищает от SSL-stripping атак: атакующий в Wi-Fi не может подменить HTTPS-запрос на HTTP.
Ограничение первого визита (TOFU)
HSTS работает по модели Trust-On-First-Use: правило попадает в браузер только после первого HTTPS-визита. Если пользователь никогда не был на сайте и его первый запрос — по HTTP, атакующий может перехватить и проксировать через себя, оставаясь на HTTP. Решение — preload-лист: ваш домен включается в исходники Chrome/Firefox/Safari/Edge, и правило HSTS применяется ещё до первого визита.
Пошаговое включение HSTS
Шаг 1: убедиться, что весь сайт на HTTPS
Проверьте, что все поддомены, CDN, API документацию, картинки работают по HTTPS. Mixed content должен быть устранён — см. mixed content fix.
Шаг 2: короткий max-age для теста
# nginx
add_header Strict-Transport-Security "max-age=300" always;
300 секунд (5 минут) — достаточно, чтобы проверить, что сайт работает. Если что-то сломалось — правило протухнет за 5 минут. Протестируйте через DevTools и Security Scanner enterno.io.
Шаг 3: увеличить max-age
add_header Strict-Transport-Security "max-age=86400" always; # 1 день
# через неделю
add_header Strict-Transport-Security "max-age=2592000" always; # 1 месяц
# через месяц
add_header Strict-Transport-Security "max-age=31536000" always; # 1 год
Шаг 4: добавить includeSubDomains
Только когда уверены, что все поддомены работают по HTTPS. Иначе у пользователей сломается blog.example.com, если тот на HTTP.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Шаг 5: подача в preload-лист
После месяца с большим max-age и includeSubDomains — подаёте на hstspreload.org.
Требования для preload-листа
- Валидный сертификат на apex и всех поддоменах.
- HTTP редиректит на HTTPS с 301.
- HTTPS на apex работает и отдаёт HSTS-заголовок.
- Заголовок содержит все три директивы:
max-age=31536000; includeSubDomains; preload. - max-age не менее 1 года.
Проверка перед подачей: curl -sI https://example.com | grep -i strict-transport. После одобрения попадёте в Chrome через 6-12 недель, в другие браузеры позже.
Редирект HTTP → HTTPS в nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# ... ssl-конфигурация ...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
Важно: заголовок должен быть с флагом always, иначе nginx не добавит его к ответам 4xx/5xx (и preload-валидатор откажет).
Подводные камни
Невозможно откатить
После включения HSTS с большим max-age вы не можете «выключить» HTTPS — все пользователи, кешировавшие правило, будут ломаться, если сайт упадёт на HTTPS. Для исправления: установите max-age=0 и ждите, пока у всех истечёт (до года). Preload-лист удаляется из Chrome полгода и дольше — fresh-домены удалить проще.
Поддомены должны все работать
includeSubDomains применяется ко ВСЕМ поддоменам, включая забытые. Проверьте через Certificate Transparency:
curl "https://crt.sh/?q=%25.example.com&output=json" | jq '.[].name_value' | sort -u
Увидите все выпущенные сертификаты — по ним можно восстановить список поддоменов. Каждый должен работать по HTTPS, иначе блокируется у пользователей.
Dev/staging окружения
Если у вас есть dev.example.com без HTTPS — includeSubDomains сломает его. Решение: вынести dev на отдельный домен (dev.example-dev.com) или наладить HTTPS везде.
HSTS и Let's Encrypt
Проблема: если Let's Encrypt перестаёт работать, сертификат истекает, а HSTS не даёт пользователям обойти предупреждение. Это защищает от MITM, но усиливает ущерб от настоящей ошибки (см. истекший сертификат). Решение — надёжный мониторинг сайтов: Enterno.io Monitors с алертами за 14/7/3 дня до истечения, плюс SMS-эскалация для критичных сервисов.
Проверка конфигурации
- Security Scanner enterno.io — покажет наличие и корректность HSTS.
- hstspreload.org — валидирует готовность к preload.
- SSL Labs — покажет HSTS и общую оценку TLS.
- DevTools → Application → Manifest или
chrome://net-internals/#hsts— увидеть, что именно закешировал ваш браузер.
Часто задаваемые вопросы
Нужен ли HSTS, если у меня везде HTTPS?
Да. HSTS защищает от первого HTTP-запроса. Без preload первый визит всё равно уязвим к SSL-stripping.
Как удалить домен из preload-листа?
Подайте заявку на удаление на hstspreload.org. Обработка — от 3 до 12 месяцев. Если домен недавно добавлен — быстрее; долгоживущий preload удаляется с задержкой.
HSTS работает на поддомены без заголовка?
С includeSubDomains — да, правило наследуется. Но сам поддомен должен отдавать валидный SSL.
Можно ли HSTS без редиректа HTTP→HTTPS?
Технически да, но preload требует редирект. Без редиректа пользователь, набравший example.com, получит отказ от HTTP-сервера (если его нет) или HTTP-страницу (если есть), что нивелирует смысл.
Заключение
HSTS с preload — обязательный элемент современного HTTPS-сайта. Настройка простая, но требует аккуратности: начните с короткого max-age, протестируйте, добавьте includeSubDomains, подайте в preload. Проверьте готовность через Security Scanner, защитите от регрессий через Monitors. Связанные темы — mixed content и слабые cipher suites.
HSTS — RFC 6797. Preload — hstspreload.org. OWASP HSTS Cheat Sheet — cheatsheetseries.owasp.org.
Проверьте ваш сайт прямо сейчас
Проверить →