Настраиваем Ngnix с поддержкой HTTP/2 в Ubuntu
Development, 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: HTTP, HTTP/2