Настройка Nginx с поддержкой HTTP/2 в Ubuntu 18.04

Nginx – это быстрый и надёжный веб-сервер с открытым исходным кодом. Он приобрел популярность благодаря своей легковесности, высокой масштабируемости, простоте настройки и поддержке большого количества протоколов, среди которых и HTTP/2.

HTTP/2 – новая версия протокола HTTP, который используется для передачи страниц с сервера в браузер. HTTP/2 – первое серьёзное обновление HTTP/2 за почти два десятилетия: текущая версия протокола, HTTP 1.1, вышла еще в 1999 году, когда веб-страницы, как правило, представляли собой всего один HTML-файл со встроенной таблицей стилей CSS. За это время сеть Интернет кардинально изменилась, и теперь пользователи часто сталкиваются с ограничениями, связанными с протоколом HTTP 1.1.В частности, протокол ограничивает потенциальную скорость передачи для большинства современных веб-сайтов, поскольку он загружает страницы по частям (предыдущая часть должна быть полностью загружена, прежде чем начнётся загрузка следующей части); для загрузки среднестатистической современной веб-страницы требуется около 100 запросов (каждый запрос представляет собой изображение, JS-файл, CSS-файл и т.д.).

Протокол HTTP/2 устраняет эти проблемы, поскольку он имеет ряд фундаментальных изменений:

  • Запросы загружаются параллельно, а не по очереди.
  • HTTP-заголовки сжимаются.
  • Страница передаётся в виде двоичного, а не текстового файла.
  • Сервер может передавать данные даже без запроса пользователя, что позволяет повысить скорость.

HTTP/2 не требует шифрования, однако разработчики популярных браузеров Google Chrome и Mozilla Firefox заявили, что по соображениям безопасности они будут поддерживать HTTP/2 только для HTTPS-соединений. Именно поэтому при настройке сервера с поддержкой HTTP/2 нужно настраивать и поддержку HTTPS.

Этот мануал поможет установить и настроить веб-сервер Nginx с поддержкой HTTP/2.

Требования

  • Сервер Ubuntu 18.04, настроенный по этому мануалу.
  • Веб-сервер Nginx, который можно установить по этому мануалу.
  • Зарегистрированный домен, направленный на ваш сервер. Полезную информацию вы найдете в статье Как настроить имя хоста.
  • Сертификат SSL. Сгенерируйте самоподписанный сертификат, получите бесплатный от Let’s Encrypt или закажите его у другого провайдера.
  • Nginx должен перенаправлять трафик с порта 80 на 443.
  • Nginx должен поддерживать 2048-битные и более длинные ключи Диффи-Хеллмана (DHE).

1: Включение поддержки HTTP/2

Если вы выполнили этот мануал по установке Nginx, в /etc/nginx/sites-available/your_domain у вас должен быть виртуальный хост (блок server) с правильно настроенной директивой server_name.

Теперь нужно настроить виртуальный хост для поддержки HTTP/2.

Откройте конфигурационный файл:

sudo nano /etc/nginx/sites-available/your_domain

Найдите переменные listen, связанные с портом 443.

...
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
...

Первая отвечает за соединения IPv6, вторая – за IPv4. Включите шифрование для обоих типов подключений. Добавьте в эти строки http2:

...
listen [::]:443 ssl http2 ipv6only=on;
listen 443 ssl http2;
...

Теперь в  поддерживаемых браузерах Nginx будет использовать HTTP/2.

Всегда проверяйте конфигурации на наличие ошибок после внесения любых изменений в файл:

sudo nginx -t

Если ошибок нет, команда выведет:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

2: Отключение устаревших и ненадежных шифров

HTTP/2 имеет огромный черный список старых и небезопасных шифров, которых следует избегать. Наборы шифров – это криптографические алгоритмы, которые описывают методы шифрования передачи данных.

Метод, который вы будете использовать для определения шифров, зависит от того, как вы настроили свои сертификаты TLS/SSL для Nginx.

Если вы получили сертификаты с помощью Certbot, у вас также есть файл /etc/letsencrypt/options-ssl-nginx.conf, где содержатся шифры, но они недостаточно надежны для HTTP / 2. Модификация этого файла, к сожалению, не позволит Certbot в дальнейшем обновлять сертификаты, поэтому просто отключите поддержку этого файла в Nginx и создайте собственный список шифров.

Откройте виртуальный хост:

sudo nano /etc/nginx/sites-available/your_domain

Найдите и закомментируйте строку с файлом options-ssl-nginx.conf:

# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot<^>

Под этой строкой добавьте такую строку:

ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

Сохраните и закройте файл.

Если вы создали самоподписанный сертификат или использовали сертификат другого ЦС, откройте файл /etc/nginx/snippets/ssl-params.conf в текстовом редакторе:

sudo nano /etc/nginx/snippets/ssl-params.conf

Найдите такую строку:

...
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
...

Отредактируйте ее:

...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

Сохраните и закройте файл.

Проверьте ошибки в конфигурации:

sudo nginx -t

Если команда нашла ошибки, исправьте их, прежде чем продолжить. Затем перезапустите Nginx:

sudo systemctl reload nginx

3: Тестирование поддержки HTTP/2

С помощью команды curl отправьте запрос на свой сайт и просмотрите заголовки.

curl -I -L https://your_domain

Команда выведет:

HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 06 Jul 2018 19:07:12 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://your_domain/
HTTP/2 200
server: nginx/1.14.0 (Ubuntu)
date: Fri, 06 Jul 2018 19:07:12 GMT
content-type: text/html
content-length: 16
last-modified: Fri, 06 Jul 2018 16:55:37 GMT
etag: "5b3f9f09-10"
accept-ranges: bytes

Также вы можете проверить протокол в Google Chrome. Откройте браузер и перейдите по ссылке http://your_domain. Откройте Chrome Developer Tools (View -> Developer -> Developer Tools) и перезагрузите страницу (View -> Reload This Page). Откройте вкладку Network, кликните правой кнопкой мыши по заголовку, который начинается с Name, и выберите Protocol в выпадающем меню.

Если вы видите h2 (что значит HTTP/2) в столбце Protocol, значит, HTTP/2 поддерживается.

4: Включение HSTS

Ранее вы настроили перенаправление HTTP на HTTPS. Теперь нужно включить Strict Transport Security, чтобы форсировать защищённое соединение через протокол HTTPS.

То есть, если браузер найдёт HSTS-заголовок, он не будет пытаться подключиться через HTTP. Обмен данными будет происходить исключительно по защищённому соединению HTTPS. Это защитит вас от downgrade-атак.

Откройте конфигурационный файл:

sudo nano /etc/nginx/nginx.conf

Добавьте в него:

http {
...
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
add_header Strict-Transport-Security "max-age=15768000" always;
}
...

Опция max-age устанавливается в секундах. 15768000 секунд – это 6 месяцев.

По умолчанию этот заголовок не будет добавляться в запросы поддомена. Если у вас есть поддомены и вы хотите настроить поддержку HSTS для них, добавьте переменную includeSubDomains:

add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Сохраните и закройте файл.

Проверьте синтаксис:

sudo nginx -t

Перезапустите Nginx:

sudo systemctl reload nginx

Заключение

Теперь сервер работает по защищённому соединению и может передавать конфиденциальные данные. Чтобы проверить надёжность сертификата SSL, посетите Qualys SSL Lab и запустите тест. Если все сделано правильно, вы получите А+.

Tags: ,