Привет читатель!
В этой записи подразумевается, что на вашем сайте уже используется HTTPS…
Что такое HSTS?
HTTPS (HTTP, зашифрованный с помощью SSL или TLS) является неотъемлемой частью мер по обеспечению безопасности трафика на вашем веб-сайте, что делает перехват, изменение или подделку трафика между пользователем и веб-сайтом очень сложным.
Когда пользователь вводит веб-домен вручную (имя домена без префикса http:// или https://) или переходит по простой ссылке с http://, первый запрос на веб-сайт отправляется незашифрованным, используя простой HTTP. Большинство защищенных веб-сайтов немедленно перенаправляют пользователя на HTTPS-соединение, но хорошо подготовленный злоумышленник может задействовать атаку «человек-по-середине» (man‑in‑the‑middle или MITM) для перехвата исходного HTTP-запроса и далее управлять сессией пользователя.
HSTS стремится справиться с потенциальной уязвимостью, указав браузеру, что доступ к домену возможен только с помощью HTTPS. Даже если пользователь переходит по простой HTTP-ссылке, браузер обновляет соединение строго по HTTPS:
Как работает HSTS?
Политика HSTS определяется путем отправки ответа с защищенных (HTTPS) сайтов следующего HTTP-заголовка:
1 |
Strict-Transport-Security: max-age=31536000 |
Когда браузер «видит» этот заголовок с HTTPS сайта, он «обучается», что к этому домену должен быть применён только HTTPS (SSL или TLS). Браузер кэширует эту информацию на максимальный период (обычно 31 536 000 секунд, равный примерно 1 году).
Опциональный параметр includeSubDomains указывает браузеру, что политика HSTS также применяется ко всем поддоменам текущего домена. Имейте ввиду, что www это поддомен и перед включением HSTS для всех остальных поддоменов необходимо настроить HTTPS на всех серверах и протестировать работоспособность.
1 |
Strict-Transport-Security: max-age=31536000; includeSubDomains |
Когда клиент «узнаёт» о политике HSTS, он кэширует информацию за указанный max-age
период. В течение этого периода браузер отказывается получить доступ к сайту по незашифрованному HTTP и отказывается предоставлять исключения для ошибок сертификата (если сайт ранее представлял действительный сертификат). Если вы укажете параметр includeSubDomains
для политики HSTS, эти ограничения также применимы ко всем поддоменам текущего домена.
ВНИМАНИЕ! Когда вы тестируете HSTS, для начала используйте очень короткий max-age
тайм-аут и убедитесь, что HTTPS везде работает и вас устраивает обязательство поддерживать HTTPS-версию вашего сайта, как минимум на срок равный параметру max-age
, который успели получить ваши пользователи.
После изменения параметра max-age
отслеживайте объем трафика пользователей, что-бы определить их нормальное прибывание на сайте. Если HSTS работает исправно у вас и у ваших пользователей перенаправляя на HTTPS, только тогда постепенно увеличивайте значение директивы max-age в заголовках HSTS.
Настройка HTTP Strict Transport Security (HSTS) в NGINX
1 |
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; |
Параметр always
гарантирует, что заголовок устанавливается для всех ответов, в том числе внутренние сгенерированные отчеты об ошибках. Старые версии NGINX (до версии 1.7.5) не поддерживают этот параметр и не устанавливают заголовок для внутренних сообщений об ошибках.
Настройка производится в конфигурационном файле,
/etc/nginx/conf.d
который обычно, имеет имя файла схожее с именем вашего домена или IP адрес сервера. Для пользователей панели управления VestaCP:
/home/<username>/conf/web
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
server { listen 443 ssl; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Этот блок «location» наследует заголовок STS location / { root /home/dmitry/web/test1.java.md/public_html; } # Блок 'location' содержит и другие заголовки 'add_header', # необходимо повторно указать STS заголовок location /servlet { add_header X-Served-By "My Servlet"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; proxy_pass http://localhost:8080; } } |
Блоки конфигурации NGINX наследуют add_header
директивы от своих закрывающих блоков, поэтому вам нужно просто поместить add_header
директиву в server
блок верхнего уровня. Есть одно важное исключение: если блок включает в себя add_header
директиву, он не наследует заголовки от верхних блоков и вам нужно повторно объявить все add_header
директивы.
Требуется ли каждому HTTPS-ответу заголовок STS?
Необходимо как можно скорее предоставить политику HSTS. Если браузер не получает политику HSTS сразу во время первого подключения, это станет уязвимо для атаки (перехват, изменение или подделка трафика). Браузеру необходимо получить заголовок STS только один раз. Однако добавить его только на главную страницу сайта или страницу входа, недостаточно, ведь пользователь может перейти на ваш сайт по ссылке на другую страницу. Так же, если вы добавите заголовок только в кэшируемые (статические) страницы, клиент может этого не увидеть. Удостоверьтесь, что вы покрываете все ответы от вашего сайта и с особым вниманием к динамическому (не кэшируемому) контенту.
HTTP и HTTPS-версии веб-сайта на одном сервере NGINX
Некоторые сайты используют HTTP и HTTPS-версии веб-сайта на одном сервере NGINX, чтобы сделать его контент доступным через любой из протоколов:
1 2 3 4 5 |
server { listen 80; listen 443 ssl; # ... } |
При использовании HSTS это недопустимо, т.к. вы не хотите, чтобы пользователи обращались к контенту через HTTP. Вместо этого необходимо перенаправить все обращения с HTTP на HTTPS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
server { listen 80 default_server; listen [::]:80 default_server; server_name _; # постоянная переадресация всех переходов на HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl; server_name test1.java.md; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; } |
На этом всё? Статический список HSTS
Исходный вариант HSTS не защищает первое подключение пользователя к сайту. Злоумышленник может легко перехватить первое подключение, если оно происходит по протоколу http. Пользователь защищен от HTTP-перехвата только после того, как он получил заголовок STS для соответствующего домена в течение объявленного max-age
периода.
Однако HSTS не является идеальным решением для защиты HTTP сессии. Пользователи по-прежнему уязвимы для атак, если они получают доступ к сайту, защищенному HSTS, через HTTP и выполняются следующие условия:
- Пользователь никогда ранее не посещал сайт
- Пользователь недавно переустановил свою операционную систему
- Пользователь недавно переустановил браузер
- Пользователь подключился с нового браузера
- Пользователь переключился на новое устройство (например, смартфон)
- Пользователь очистил кеш браузера
- Пользователь давно не посещал сайт и период
max-age
закончился.
Чтобы решить эту проблему, Google ведет «список предварительной загрузки HSTS» (HSTS preload list) доменов и поддоменов, которые используют HSTS и отправили свои доменные имена через сервис hstspreload. Этот список доменов распределён и жёстко закреплён в основных браузерах. Пользователи, которые обращаются к доменам из этого списка, автоматически используют HTTPS и отказываются обращаться к сайту с помощью HTTP.
Имейте в виду, что как только вы установите заголовок STS и отправите свой домен в список предварительной загрузки HSTS, его невозможно оттуда удалить. Это одностороннее решение сделать ваши домены доступными через HTTPS. Вы берёте на себя обязанность перед пользователями поддерживать HTTPS версию сайта, включая поддержку вашего доверенного сертификата.
Ошибка NET::ERR_CERT_AUTHORITY_INVALID
Если механизм HSTS настроен, а с сертификатом (конфигурацией) не всё в порядке или на странице используются небезопасные внутренние HTTP ссылки — браузер сообщит, что:
На сайте *.* для защиты ваших данных обычно используется шифрование. Однако учетные данные, которые мы получили от сайта *.* сейчас, отличаются от тех, которые он отправляет обычно. Вероятно, вредоносный сайт пытается выдать себя за *.*, либо страница подключения к сети Wi-Fi прервала соединение. Ваша информация по-прежнему в безопасности, так как браузер Google Chrome разорвал соединение до того, как произошел обмен данными.
Веб-сайт *.* использует механизм HSTS. Открыть сайт в настоящее время нельзя. Сбой мог быть вызван сетевой ошибкой или действиями злоумышленников. Скорее всего, сайт заработает через некоторое время.
В этом случае, вашим пользователям вход на сайт будет невозможен, т.к. отсутствует возможность игнорировать ошибку. Для решения проблемы необходимо очистить настройки HSTS.
Как удалить настройки HSTS в Chrome:
- Перейдите к chrome://net-internals#hsts
- Для проверки наличия домена в списке HSTS, введите имя хоста в разделе «Query HSTS/PKP domain» и нажмите Query. В списке появятся данные STS.
- Введите то же самое имя хоста в раздел Delete domain security policies и нажмите Delete.
Как удалить настройки HSTS в Firefox:
- Закройте все открытые вкладки в Firefox.
- Откройте окно истории с помощью сочетания клавиш Ctrl + Shift + H (Cmd + Shift + H на Mac).
- Найдите сайт, на котором хотите удалить настройки HSTS
- Выберите правой кнопкой мыши сайт из списка элементов и нажмите «Забыть об этом сайте». Это должно очистить настройки HSTS (и другие данные кеша) для этого домена.
Ваш браузер больше не будет устанавливать HTTPS-соединение для этого сайта. Вы можете проверить, правильно ли он работает, обновив или перейдя на HTTP страницу. Имейте ввиду, что в зависимости от настроек HSTS, предоставляемых сайтом, вам может потребоваться повторить процедуру для всех поддоменов. Домен из «списка предварительной загрузки HSTS» (HSTS preload list, preloaded entries), который строго закреплён браузером удалить невозможно.
Тестирование сертификата и конфигурации
Рассмотрим сервис https://www.ssllabs.com/ssltest/. Этот бесплатный сервис выполняет глубокий анализ конфигурации любого веб-сервера, который использует SSL.
Используя обычный SSL, вы как правило, получите оценку «А».
После настройки HSTS, оценка повышается до А+.
PS: Не стоит настраивать HSTS, только ради этой оценки. 😉
Источники:
https://ru.wikipedia.org/wiki/HSTS
https://news.netcraft.com/archives/2016/03/17/95-of-https-servers-vulnerable-to-trivial-mitm-attacks.html