Как настроить HSTS и не заблокировать себе доступ
Поэтапный и обратимый план внедрения Strict-Transport-Security, который улучшает приватность, не превращая один неудачный сертификат в простой.
Содержание
- HSTS прост, пока не становится сложным
- Что на самом деле делает заголовок HSTS
- Сценарии блокировки, которых нужно избежать
- 1. Забытый поддомен не готов к HTTPS
- 2. Сертификат истекает
- 3. Staging или внутренние инструменты находятся под production-доменом
- 4. Preload воспринимается как обычный чекбокс
- Безопасный план внедрения
- Шаг 1: Проведите аудит каждого hostname, который вы контролируете
- Шаг 2: Исправьте HTTPS до добавления HSTS
- Шаг 3: Начните с очень короткого max-age
- Шаг 4: Увеличивайте постепенно
- Шаг 5: Добавляйте includeSubDomains только после реального аудита
- Шаг 6: Рассматривайте preload как отдельный проект
- Примеры конфигурации
- Nginx
- Apache
- CDN или edge platform
- Как безопасно откатить HSTS
- Чеклист тестирования перед запуском
- Почему HSTS важен для приватности
HSTS прост, пока не становится сложным
HTTP Strict Transport Security, обычно сокращаемый до HSTS, сообщает браузерам: «для этого сайта всегда используйте HTTPS». Как только браузер получает этот заголовок через действительное HTTPS-соединение, он запоминает правило на указанный вами срок.
Это полезно. HSTS предотвращает атаки с понижением протокола, сокращает количество случайных небезопасных запросов и убирает неловкий момент, когда пользователь вводит example.com и на короткое время попадает в обычный HTTP перед перенаправлением.
Но это правило также «липкое». Если вы опубликуете неправильную политику HSTS, браузеры могут продолжать применять ее еще долго после того, как вы удалите заголовок с сервера. Так команды и блокируют себе доступ: не совсем к собственной админ-панели, а к браузерам пользователей, поддоменам, staging-системам, legacy-эндпоинтам и забытым сервисам, которые не готовы к принудительному HTTPS.
Цель не в том, чтобы избегать HSTS. Цель в том, чтобы внедрять его как миграцию, а не как переключатель.
Что на самом деле делает заголовок HSTS
Типичный заголовок HSTS выглядит так:
Strict-Transport-Security: max-age=31536000; includeSubDomains
У него есть три важные части:
max-age: как долго, в секундах, браузер должен принудительно использовать HTTPS для этого хоста.includeSubDomains: распространяется ли правило также на все поддомены.preload: сигнал о том, что вы хотите включить домен в списки preload браузеров.
Браузер доверяет этому заголовку только тогда, когда получает его через действительный HTTPS. Если сертификат недействителен, истек или не соответствует хосту, браузер не должен принимать новую политику HSTS из такого ответа.
После сохранения политики будущие попытки открыть http://example.com обновляются браузером до https://example.com еще до отправки запроса. В этом и состоит выигрыш для приватности: небезопасный запрос вообще не покидает устройство.
Сценарии блокировки, которых нужно избежать
Большинство сбоев HSTS вызваны не основным сайтом. Они происходят на краях.
1. Забытый поддомен не готов к HTTPS
includeSubDomains звучит аккуратно, но действует без исключений. Если вы задаете его на example.com, он применяется к:
www.example.comapi.example.comold-crm.example.comprinter-setup.example.comstaging.example.com- любому другому хосту под этим доменом
Если какой-либо из этих хостов не может отдавать действительный HTTPS, пользователи с закешированной политикой HSTS не смогут открыть его по HTTP.
2. Сертификат истекает
Без HSTS пользователи иногда проходят дальше, несмотря на предупреждения о сертификате. Это плохая практика безопасности, но такое случается.
С HSTS современные браузеры не позволяют легко обойти ошибки сертификата для этого хоста. В этом и смысл. Но это также означает, что продление сертификатов должно быть скучным, отслеживаемым и протестированным процессом.
3. Staging или внутренние инструменты находятся под production-доменом
Размещение внутренних инструментов под *.example.com может стать болезненным, когда родительский домен использует includeSubDomains. Если эти инструменты используют самоподписанные сертификаты, частные центры сертификации, старые конфигурации TLS или вообще не используют HTTPS, HSTS вскроет этот компромисс.
Это одна из причин, по которой многие команды держат внутренние и экспериментальные системы под отдельным доменом с собственной политикой безопасности.
4. Preload воспринимается как обычный чекбокс
HSTS preload — это не просто еще одна директива. Это означает, что ваш домен может поставляться внутри браузеров как работающий только по HTTPS еще до того, как пользователь впервые посетит ваш сайт.
Это закрывает пробел «первого визита», но откатить такое решение гораздо сложнее. Удаление из списков preload может занимать недели или месяцы, прежде чем дойдет до пользователей, в зависимости от циклов выпуска браузеров. Preload подходит для стабильных, зрелых доменов. Он не подходит сайту, который еще только выясняет полный список своих поддоменов.
Безопасный план внедрения
Шаг 1: Проведите аудит каждого hostname, который вы контролируете
Перед включением includeSubDomains перечислите каждый hostname под доменом. DNS-записи — хорошее начало, но это не вся картина. Проверьте конфигурации CDN, панели хостинга, hostnames, связанные с электронной почтой, старые маркетинговые инструменты, storage buckets и внутреннюю документацию.
Для каждого hostname ответьте:
- Он обслуживает HTTP, HTTPS или оба варианта?
- Действителен ли HTTPS-сертификат и продлевается ли он автоматически?
- Корректно ли он перенаправляет HTTP на HTTPS?
- Должен ли он быть публичным?
- Он все еще нужен?
Если у вашей команды уже есть привычка отлаживать production-заголовки, это естественно встраивается рядом с проверками перенаправлений и заголовков. Мы описывали этот workflow в небольшом наборе инструментов для отладки redirects и HTTP headers в production.
Шаг 2: Исправьте HTTPS до добавления HSTS
HSTS не делает сломанную настройку HTTPS безопасной. Он только делает HTTPS обязательным.
Перед включением проверьте:
- TLS-сертификаты покрывают правильные hostnames.
- Сертификаты продлеваются автоматически.
- HTTP перенаправляется на HTTPS одним чистым переходом там, где это возможно.
- Перенаправления канонического хоста согласованы, например с non-
wwwнаwwwили наоборот. - Ресурсы приложения не зависят от небезопасных URL вида
http://.
Mixed content встречается реже, чем раньше, но все еще появляется в старых темах CMS, analytics snippets, встроенных медиа и жестко заданных путях к изображениям.
Шаг 3: Начните с очень короткого max-age
Не начинайте с одного года. Начните с пяти минут:
Strict-Transport-Security: max-age=300
Разверните это только на hostname, который вы тестируете, обычно на каноническом production-сайте. Пока не добавляйте includeSubDomains.
Затем протестируйте в реальных браузерах и с помощью запросов из командной строки:
curl -I https://example.com
Вы должны увидеть ровно один заголовок Strict-Transport-Security. Дублирующиеся заголовки HSTS от app server и CDN — частый источник путаницы. Браузеры обычно применяют эффективную политику, но людям, которые отлаживают инцидент, неоднозначность не нужна.
Шаг 4: Увеличивайте постепенно
Если ничего не ломается, увеличивайте длительность поэтапно:
Strict-Transport-Security: max-age=86400
Затем:
Strict-Transport-Security: max-age=604800
Затем, возможно:
Strict-Transport-Security: max-age=2592000
Практичный график:
- 5 минут
- 1 день
- 1 неделя
- 1 месяц
- 6 месяцев или 1 год
За спешку призов не дают. Весь смысл поэтапного внедрения — дать вашему мониторингу, support inbox и пограничным случаям время показать, что пропустил ваш чеклист.
Шаг 5: Добавляйте includeSubDomains только после реального аудита
Когда каждый публичный поддомен готов к HTTPS, можно рассмотреть:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Это момент, когда стоит быть консервативными. Если одному legacy-сервису все еще нужен HTTP, не добавляйте includeSubDomains на родительский домен. Либо мигрируйте этот сервис, либо перенесите его на другой домен, либо примите, что ваша политика HSTS пока должна оставаться более узкой.
Security headers должны отражать реальность. Их не стоит использовать как мотивационные плакаты для инфраструктуры, которую вы надеетесь построить позже.
Шаг 6: Рассматривайте preload как отдельный проект
Думайте о preload только если верно все следующее:
- Домен и все поддомены поддерживают действительный HTTPS.
- HTTP перенаправляется на HTTPS.
- Заголовок HSTS использует
max-ageне менее 31536000 секунд. - Заголовок включает
includeSubDomains. - Заголовок включает
preload. - Вы уверены, что вам нигде под этим доменом не понадобится plain HTTP.
Заголовок, готовый к preload, выглядит так:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Отправка в preload list — это долгосрочное обязательство. Если сайт — campaign microsite, временный продуктовый домен или домен с неясными границами владения, пропустите этот шаг.
Примеры конфигурации
Nginx
Используйте always, чтобы заголовок отправлялся и в ответах с ошибками:
add_header Strict-Transport-Security "max-age=300" always;
После стабилизации rollout:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Apache
С включенным mod_headers:
Header always set Strict-Transport-Security "max-age=300"
Позже:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
CDN или edge platform
Если ваш CDN задает response headers, предпочтительно управлять HSTS в одном месте. Не задавайте одну политику на origin и другую на edge, если у вас нет очень ясной причины.
Также проверьте, применяет ли CDN заголовки к redirects, cached errors и custom error pages. Production-сайт — это не только его ответ 200 OK.
Как безопасно откатить HSTS
Если нужно отключить HSTS, отправьте:
Strict-Transport-Security: max-age=0
Но есть нюанс: браузер должен успешно достичь сайта по действительному HTTPS, чтобы получить этот заголовок. Если сам HTTPS сломан, пользователи с закешированной политикой HSTS не смогут получить инструкцию, которая ее очистит.
Поэтому обычный порядок восстановления такой:
- Восстановить действительный HTTPS.
- Отдавать
Strict-Transport-Security: max-age=0. - Держать его достаточно долго, чтобы возвращающиеся пользователи успели его получить.
- Удалить или заменить заголовок после разрешения инцидента.
Если домен находится в preload, отдавать max-age=0 недостаточно для новых профилей браузера. Нужно также запросить удаление из preload list и дождаться, пока это изменение попадет к пользователям через обновления браузеров.
Чеклист тестирования перед запуском
Используйте этот чеклист перед увеличением max-age или добавлением includeSubDomains:
- Канонический HTTPS URL возвращает действительный сертификат.
- HTTP перенаправляется на HTTPS.
- Есть только один заголовок HSTS.
- Заголовок появляется на redirects и error responses там, где это уместно.
- Все публичные поддомены имеют действительный HTTPS.
- Продление сертификатов отслеживается мониторингом.
- Ни одна критичная внутренняя система не зависит от HTTP под тем же родительским доменом.
- Preload был явно обсужден, а не добавлен по привычке.
Lighthouse также может отмечать отсутствующие или слабые security headers в некоторых контекстах, но он не должен быть вашим единственным способом проверки. Если вы используете его как часть более широкого review, воспринимайте findings как сигналы, а не как приговоры; тот же подход полезен, когда вы читаете отчет Lighthouse без паники.
<!-- tool-cta:start -->
💡 Попробуйте это: До и после каждого изменения HSTS проверяйте ответ Strict-Transport-Security с помощью Get Headers, чтобы убедиться, что max-age, includeSubDomains и preload соответствуют вашим ожиданиям.
<!-- tool-cta:end -->
Почему HSTS важен для приватности
HSTS часто описывают как security header, и это так. У него также есть польза для приватности: он снижает вероятность того, что первый запрос пользователя уйдет по plain HTTP в недоверенной сети.
Это важно в airport Wi-Fi, гостиничных сетях, корпоративных гостевых сетях и везде, где трафик пользователя могут наблюдать или изменять. Plain HTTP request может раскрыть hostname, path, cookies без флага Secure и другие детали запроса. HTTPS — не магия, но его последовательное принудительное использование устраняет целый класс утечек, которых можно избежать.
Лучшие внедрения HSTS неинтересны. Они выполняются медленно, опираются на надежные сертификаты и достаточно скучны, чтобы их никто не заметил. Именно этого и нужно ожидать от заголовка, чей режим отказа может быть драматичным.