Настраиваем Ngnix с поддержкой HTTP/2 в Ubuntu

Nginx — быстрый и надежный веб-сервер с открытым кодом. Так популярен он стал благодаря низкой нагрузке на память, высокой масштабируемости, лёгкости в настройке и поддержке множества протоколов.

HTTP/2 — обновленная версия HTTP-протокола, используемого в интернете для передачи страниц с сервера на браузер. Это первое значительное обновление HTTP за почти двадцать лет: HTTP1.1 представили еще в 1999, когда веб-страницы были намного меньше. С тех пор интернет изменился до неузнаваемости, и пользователям приходится всё чаще сталкиваться с ограничениями, накладываемыми протоколом HTTP1.1. Этот протокол снижает потенциальную скорость передачи для большей части современных сайтов, т.к. загружает страницы частями: текущая часть должна подгрузиться полностью, прежде чем начнет загружаться следующая, — а среднестатистическая современная веб-страница подгружает десятки отдельных CSS, JS-файлов и изображений.

HTTP/2 решает эту проблему, т.к. он вносит несколько фундаментальных перемен:

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

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

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

Требования

  • Виртуальный сервер (для этого руководства мы используем Ubuntu 20.04, настроенный в соответствии с нашим туториалом, включая пользователя sudo без root-полномочий и брандмауэр).
  • Установленный по нашему руководству веб-сервер Nginx.
  • Доменное имя, ведущее к вашему серверу.  Можно приобрести его на Namecheap или получить бесплатно на Freenom.
  • TSL/SSL-сертификат, настроенный под ваш сервер. Сгенерировать самоподписанный сертификат можно следуя нашему туториалу. Кроме того, его можно получить бесплатно от Let’s Encrypt или заказать у другого провайдера.
  • Nginx, настроенный на перенаправление трафика с порта 80 на 443.
  • Nginx, поддерживающий 2048-битные и более крупные ключи Диффи-Хеллмана (DHE)

1: Включаем поддержку HTTP/2

Если вы установили Nginx по нашему руководству, у вас должен быть виртуальный хост для вашего домена в /etc/nginx/sites-available/your_domain с предустановленной директивой server_name. Первое изменение, которое мы внесем, будет модификация вашего виртуального хоста под использование HTTP/2. Откроем файл конфигурации вашего домена при помощи nano или другого редактора.

$ sudo nano /etc/nginx/sites-enabled/your_domain

В файле найдём переменные listen, связанные с портом 443:

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

Первая — для соединений IPv6. Вторая — для всех подключений IPv4. Мы включим HTTP/2 для обоих типов.

Добавим http2 в каждую директиву listen:

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

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

Сохраните конфиг и выйдите из текстового редактора. Если вы пользуетесь nano, нажмите Ctrl+X, затем Y, а потом Enter.

Каждый раз, внося изменения в файлы конфигурации Nginx, проверяйте их на наличие ошибок, используя флаг -t, запускающий встроенную команду для проверки синтаксиса в Nginx:

$ sudo nginx -t

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

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

Дальше мы настроим сервер Nginx так, чтобы он использовал ограниченный список шифров, что обеспечит безопасность вашего сервера.

2: Удаление устаревших шифров

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

От настройки ваших TSL/SSL-сертификатов для Nginx будет зависеть и метод, которым вы воспользуетесь для удаления шифров.

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

Откроем файл конфигурации виртуального хоста для вашего домена:

sudo nano /etc/nginx/sites-enabled/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;

Сохраняем файл и закрываем редактор.

Опять же, проверяем конфиг на ошибки в синтаксисе используя nginx -t-команду:

$ sudo nginx -t

Если какие-то ошибки нашлись, исправьте их, прежде чем продолжать.

Когда проверка синтаксиса будет пройдена, перезапустим Nginx командой systemctl:

$ sudo systemctl reload nginx.service

После перезагрузки сервера убедитесь, что он работает.

3: Проверка HTTP/2

Давайте убедимся, что сервер поддерживает протокол HTTP/2.

Воспользуемся командой curl, чтобы сделать запрос на ваш сайт и просмотреть заголовки:

$ curl -I -L --http2 https://your_domain

Мы получим следующий результат:

HTTP/2 200
server: nginx/1.18.0 (Ubuntu)
date: Wed, 10 Nov 2021 17:53:10 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 09 Nov 2021 23:18:37 GMT
etag: "618b01cd-264"
accept-ranges: bytes

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

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

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

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

Сейчас HTTP-запросы перенаправляются на HTTPS, и мы можем включить HTTP Strict Transport Security (HSTS), чтобы избежать этих перенаправлений. Если браузер обнаружит заголовок HSTS, он не будет пытаться снова подключиться к серверу через обычный HTTP. Он будет обмениваться данными с использованием только зашифрованного HTTPS-соединения. Этот заголовок также защитит от downgrade-атак.

Снова откроем файл конфигурации виртуального хоста для вашего домена:

sudo nano /etc/nginx/your_domain

Добавим эту строку к тому же блоку с шифрами SSL, чтобы включить HSTS:

server {
...
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    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.service

Заключение

Теперь ваш сервер Nginx обслуживает страницы HTTP/2. Если вы хотите проверить надежность SSL-соединения, посетите Qualys SSL Lab и запустите тест на своем сервере. Если все настроено верно, вы получите оценку A+ за безопасность.

Чтобы узнать больше о том, как Nginx анализирует и реализует правила блокировки сервера, прочтите нашу статью про алгоритмы выбора блоков server и location в Nginx

Tags: ,

Добавить комментарий