Реми ван Элст. HSTS - строгая безопасность транспорта HTTP в Apache, nginx и Lighttpd, 2016

Перевод статьи: HTTP Strict Transport Security for Apache, NGINX and Lighttpd

Автор: Реми ван Элст (Remy van Elst)

Строгая безопасность транспорта HTTP (часто сокращается как HSTS) - это функция безопасности, которая позволяет веб-серверу сообщать веб-браузерам, что должно использоваться подключение только по HTTPS вместо HTTP. В этом руководстве рассказывается, как настроить HSTS в Apache, nginx и Lighttpd. Руководство протестировано со всеми перечисленными серверами: nginx 1.1.19, Lighttpd 1.4.28 и Apache 2.2.22 в Ubuntu 12.04, Debian 6 и 7, а также в CentOS 6. Руководство может быть пригодным и для других дистрибутивов, а данные дистрибутивы указаны в качестве эталона.

1. Что такое "строгая безопасность транспорта HTTP"?

Процитируем Mozilla Developer Network - сеть разработчиков Mozilla:

Если веб-сайт принимает подключения по HTTP и перенаправляет их на HTTPS, то пользователь в этом случае обращается сначала к нешифрованной версии сайта и только потом перенаправляется. Например, если пользователь введёт http://www.foo.com/ или даже просто foo.com.

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

Функция строгой безопасности транспорта HTTP позволяет веб-сайту проинформировать веб-браузер, что он никогда не должен загружать этот сайт по протоколу HTTP и должен автоматически преобразовывать все попытки обратиться к сайту по протоколу HTTP в запросы по протоколу HTTPS.

Пример использования:

Вы заходите на бесплатную точку доступа WiFi в аэропорту и начинаете бродить по интернету, заходите на сайт банк-клиента для проверки баланса и чтобы оплатить несколько счетов. Неожиданно, используемая вами точка доступа оказывается ноутбуком злоумышленника, и он перехватывает исходный запрос HTTP и перенаправляет вас на сайт-клон банк-клиента, а не на настоящий сайт. Теперь ваши секретные данные доступны злоумышленнику.

Строгая безопасность транспорта решает проблему. После первого обращения к сайту банк-клиента по протоколу HTTPS, если сайт банк-клиента использует строгую безопасность транспорта, браузер будет знать, что все последующие запросы нужно автоматически преобразовывать в запросы по протоколу HTTPS. Это позволяет защититься от злоумышленников, пытающихся осуществить атаку типа "человек в середине".

Отметим, что HSTS не сработает, если вы ранее никогда не были на этом веб-сайте. Веб-сайт должен сообщить, что он доступен только по протоколу HTTPS.

2. Важное замечание о предварительной загрузке

В конфигурации ниже использовалась директива предварительной загрузки. По просьбе Лукаса Гэррона (Lucas Garron) из Google, я удалил её, поскольку у многих людей возникли с ней проблемы.

Учтите, что директива предварительной загрузки повлечёт за собой почти постоянные последствия. Если вы потестировали её, ошиблись или больше не хотите использовать HSTS, то сайт может оказаться в списке предварительной загрузки.

Важно, чтобы вы понимали то, что делаете и чтобы вы понимали, что директива предварительной загрузки в конечном счёте действует в браузере. Если конфигурация HTTPS неправильная, неисправная или вы больше не хотите использовать HTTPS, у вас возникнут проблемы. Обратитесь к этой странице.

Если вы всё ещё хотите использовать предварительную загрузку, просто добавьте preload в заголовок после точки с запятой.

3. Настройка HSTS в Apache

Отредактируйте файл конфигурации Apache (например, /etc/apache2/sites-enabled/website.conf и /etc/apache2/httpd.conf) и добавьте следующие настройки в секцию VirtualHost:

# Необязательная загрузка модуля headers:
LoadModule headers_module modules/mod_headers.so

<VirtualHost 67.89.123.45:443>
  Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
</VirtualHost>

Теперь веб-сайт будет при каждом посещении устанавливать заголовок со сроком годности два года (в секундах). Заголовок будет устанавливаться при каждом посещении. Например, завтра он опять будет иметь годность два года.

Заголовок нужно устанавливать только в виртуальном хосте, работающем по протоколу HTTPS. Его не может быть в виртуальном хосте, работающем по протоколу HTTP.

Чтобы перенаправить посетителей на HTTPS-версию сайта, воспользуйтесь следующими настройками:

<VirtualHost *:80>
  [...]
  ServerName example.com
  Redirect permanent / https://example.com/
</VirtualHost>

Если всегда будет происходить только перенаправление, то корень документов указывать не требуется.

Можно также воспользоваться modrewrite, хотя метод выше проще и безопаснее. Однако, вариант с modrewrite ниже перенаправляет пользователя на HTTPS-версию той страницы, на которую он хотел попасть, а конфигурация выше просто перенаправляет в /:

<VirtualHost *:80>
  [...]
  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
  </IfModule>
</VirtualHost>

И не забудьте перезапустить Apache.

4. 4. 4. 4. Lighttpd

В случае Lighttpd всё очень просто. Добавим в файл конфигурации Lighttpd (например, в /etc/lighttpd/lighttpd.conf) следующие строки:

server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
  setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=63072000; includeSubdomains; ")
}

И перезапустим Lighttpd. В этой конфигурации срок действия такой же - два года.

5. nginx

Настройка nginx даже ещё короче. Добавьте следующую строку в блок server, относящийся к настройке HTTPS:

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; ";

Не забудьте перезапустить nginx.

6. Заголовок X-Frame-Options

Последний совет, который я хочу дать - это заголовок X-Frame-Options, который можно добавить к веб-сайту HTTPS, чтобы предотвратить его встраивание в frame или iframe. Это позволит избежать кликджекинга и может быть полезно для веб-сайтов HTTPS. Снова процитирую Mozilla Developer Network - сеть разработчиков Mozilla:

Заголовок в HTTP-ответе X-Frame-Options может использоваться для того, чтобы обозначить, должен ли браузер показывать страницу в "<frame>" или в "<iframe>". Сайты могут использовать этот заголовок для защиты от кликджекинга, чтобы быть уверенным в том, что их страницы не будут встроены в другие сайты.

Вы можете заменить DENY (запретить) на SAMEORIGIN (тот же источник) или ALLOW-FROM (разрешено при переходе с) URI. Обратитесь по ссылке выше за более подробной информацией (или к RFC).

6.1. X-Frame-Options в Apache2

Как и в прошлый раз, добавим строчку в конфигурацию Apache:

Header always set X-Frame-Options DENY

6.2. Lighttpd

То же самое можно сделать и в Lighttpd. Убедитесь, что не дублируете настройки, указанные выше. Если настройки уже есть, просто добавьте в них новое правило.

server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
  setenv.add-response-header = ( "X-Frame-Options" => "DENY")
}

6.3. nginx

И снова, в блоке server:

add_header X-Frame-Options "DENY";

Написать автору перевода