HSTS (HTTP Strict Transport Security) — заголовок, який інструктує браузер завжди використовувати HTTPS для вашого домену, навіть якщо користувач набрав http://. Це захист від SSL-stripping атак і випадкового переходу по HTTP.
Як працює HSTS
- Браузер вперше відвідує сайт по HTTPS
- Отримує заголовок
Strict-Transport-Security - Зберігає домен у список HSTS на час max-age
- При наступному візиті — автоматично відкриває 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 на піддоменах
Перевірка 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 | Тривалість | Коли використовувати | Ризик |
|---|---|---|---|
| 300 | 5 хвилин | Тестування налаштування на реальному трафіку | Мінімальний — відкочується майже миттєво |
| 86400 | 1 доба | Перший етап продакшену після успішного тесту | Помилку ще можна виправити протягом доби |
| 2592000 | 30 діб | Стабільна робота HTTPS без нарікань | Потрібно підтримувати сертифікат увесь цей період без збоїв |
| 31536000 | 1 рік | Фінальна стадія, обовʼязкова умова для 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-списку — ні.