2 заметки с тегом

HTTP Public Key Pinning

Повышение безопасности сервера при помощи заголовков

Для увеличения степени безопасности сервера понадобится добавить или удалить несколько заголовков, которые он отдает при запросе страниц. Я не буду подробно расписывать какой из них за что отвечает, ограничусь лишь кратким описанием.

  1. HTTP Strict Transport Security (HSTS) — позволяет форсировать HTTPS подключение.
  2. HTTP Public Key Pinning (HPKP)  — позволяет создать своеобразную «электронную подпись» для вашего сайта.
  3. X-Download-Options со значением «noopen» позволяет запретить открытие любых файлов с вашего сайта (например, документов в формате PDF), становится возможно только скачать их.
  4. X-Content-Type-Options со значением «nosniff» инструктирует Internet Explorer версии 8 не определять автоматически content-type, а использовать уже полученный.
  5. Еще один заголовок X-XSS-Protection со значением «1; mode=block» активирует встроенную защиту от XSS (Cross-Site Scripting, «межсайтовый скриптинг»).
  6. X-Frame-Options со значением «SAMEORIGIN» запрещает открывать страницы вашего сайта во фрейме на чужом сайте.
  7. Заголовок Set-Cookie должен указываться с параметрами HttpOnly и Secure. Это предотвратит XSS-атаки и защитит cookie от кражи при помощи скрипта javascript.
  8. В заголовке Server также должна быть указана минимальная информация о сервере. Например, просто Apache. Это не даст злоумышленнику получить дополнительную информацию о программном обеспечении, установленном на вашем сервере.
  9. По аналогичным причинам рекомендуется убрать заголовок X-Powered-By, если таковой присутствует.

И, как обычно, есть ресурсы, с помощью которых можно проверить насколько корректно вы указали эти заголовки. Первый из них — securityheaders.io, работает очень быстро, корректно указанные по его мнению заголовки выделяются зеленым цветом. Некоторые он не выделяет, но, думаю, что на них он просто не обращает внимание.

Второй ресурс — Redbot. В левой части страницы он показывает заголовки, которые он смог получить. В правой вкратце описывается действие заголовка, также значками выделяется корректность их указания. Стадия их получения почему-то немного затянута, на мой взгляд — около 1 минуты, будем надеяться, что это будет исправлено. Также есть возможность включить в запрос дополнительные параметры.

Если вы думаете, что я что-то пропустил, то пишите в комментариях.

Защита сайта при помощи HTTP Public Key Pinning (HPKP)

Данная технология призвана защитить посетителя вашего сайта от атаки типа MITM (Man in the middle, человек посередине). Иными словами посетитель может быть уверен, что данные, которые он получает, исходят с вашего сайта, а не с какого-то другого.

Суть технологии состоит в создании публичного ключа на основе сертификата, который установлен на вашем сайте. Соответственно, чтобы она работала, требуется валидный сертификат. Впрочем, она будет работать и на самоподписанных (self-signed) сертификатах. Полученный на основе вашего сертификата ключ добавляется в заголовок ответа вашего сервера, после чего браузер сравнивает полученный ключ с тем, который он вычисляет после получения данных о вашем сертификате.

Итак, что нам требуется:

  1. Какой-либо установленный для сайта сертификат.
  2. Консоль для получения публичного ключа.

Кстати, не так давно для нормального функционирования этой технологии требовался всего лишь один ключ, сейчас же нужно указывать два или более ключей. На мой взгляд двух будет достаточно, от этого и будем отталкиваться. Второй ключ является «резервным», этот момент я не совсем понимаю, но не будем отступать от требований.

Действовал я по следующей схеме:

  • — получаем сертификат на сайте Let’s Encrypt для двух сайтов: example.com и www.example.com;
  • — так как я использую вариант без www, то ключ, полученный на базе первого будет основным, на базе второго — резервным;
  • — генерируем ключи для обоих сертификатов;
  • — добавляем нужные инструкции в файл /etc/httpd2/conf/sites-available/default-http.conf.

О получении сертификата рассказывать не буду, достаточно почитать главную страницу сайта. Допустим, вы его получили и установили на свой сайт. Теперь требуется создать ключи при помощи следующей команды:

openssl x509 -noout -in certificate.pem -pubkey | openssl rsa -pubin -outform der | \
openssl dgst -sha256 -binary | base64

где certificate.pem — полный путь к сертфикату.

После выполнения команды вы получите нечто подобное:

LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=

Это и есть нужный вам ключ. Повторяем команду для второго сертификата и добавляем данные в файл конфигурации сайта:

Header set Public-Key-Pins "pin-sha256=\"pin1\"; pin-sha256=\"pin2\"; max-age=time"

где:

  • pin1 — основной ключ для данного сайта. В моем случае example.com;
  • pin2 — резервный ключ для сайта. То есть www.example.com;
  • time — время действия ключа в секундах.

Опциональный параметр includeSubDomains указывает на то, что ключи действительны также для поддоменов. Еще один необязательный параметр report-uri указывает на адрес, куда должны отправляться отчеты об ошибках в формате JSON. Его я, возможно, добавлю на сайт, но пока что считаю его ненужным для себя.

Какие тут есть нюансы? Если вы неправильно настроите HPKP, ваш сайт станет недоступен. Можно также настроить отправку отчетов в случае каких-либо ошибок. Для этого немного меняем заголовок (или просто добавляем еще одной строкой):

Header set Public-Key-Pins-Report-Only "pin-sha256=\"pin1\"; pin-sha256=\"pin2\"; max-age=time"