Поиск по сайту:

Как настроить Nginx с поддержкой HTTP/2 в Ubuntu 16.04


Введение

NGINX — это быстрый и надежный веб-сервер с открытым исходным кодом. Он завоевал свою популярность благодаря небольшому объему памяти, высокой масштабируемости, простоте настройки и поддержке подавляющего большинства различных протоколов.

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

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

Предпосылки

Прежде чем мы начнем, нам понадобится несколько вещей:

  • Дроплет Ubuntu 16.04
  • Пользователь без полномочий root с правами sudo (подробности см. в разделе Initial Server Setup with Ubuntu 16.04).
  • Полностью зарегистрированный домен. Вы можете приобрести его на Freenom.
  • Убедитесь, что имя вашего домена указывает на ваш дроплет. Ознакомьтесь с этим руководством, если вам нужна помощь.
  • Сертификат SSL. купить у другого поставщика.

Вот и все. Если у вас есть все перечисленное выше, вы готовы к работе.

Различия между HTTP 1.1 и HTTP/2

HTTP/2 — это новая версия протокола передачи гипертекста, который используется в Интернете для доставки страниц с сервера в браузер. HTTP/2 — это первое крупное обновление HTTP почти за два десятилетия: HTTP1.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.

Шаг 1 — Установка последней версии Nginx

Поддержка протокола HTTP/2 появилась в Nginx 1.9.5. К счастью, репозиторий по умолчанию в Ubuntu 16.04 содержит более позднюю версию, поэтому нам не нужно добавлять сторонний репозиторий.

Сначала обновите список доступных пакетов в системе пакетов apt:

  1. sudo apt-get update

Затем установите Nginx:

  1. sudo apt-get install nginx

После завершения процесса установки вы можете проверить версию Nginx, набрав:

  1. sudo nginx -v

Вывод должен быть похож на следующий:

nginx version: nginx/1.10.0 (Ubuntu)

На следующих нескольких шагах мы изменим файлы конфигурации Nginx. Каждый шаг изменит параметр конфигурации Nginx. По ходу мы проверим синтаксис конфигурационного файла. Наконец, мы проверим, поддерживает ли Nginx HTTP/2, и внесем несколько изменений для оптимизации производительности.

Шаг 2 — Изменение порта прослушивания и включение HTTP/2

Первым изменением, которое мы внесем, будет изменение порта прослушивания с 80 на 443.

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

  1. sudo nano /etc/nginx/sites-available/default

По умолчанию Nginx настроен на прослушивание порта 80, который является стандартным портом HTTP:

listen 80 default_server;
listen [::]:80 default_server;

Как видите, у нас есть две разные переменные listen. Первый предназначен для всех подключений IPv4. Второй — для соединений IPv6. Мы включим шифрование для обоих.

Измените порт прослушивания на 443, который используется протоколом HTTPS:

listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;

Обратите внимание, что в дополнение к ssl мы также добавили в строку http2. Эта переменная указывает Nginx использовать HTTP/2 с поддерживаемыми браузерами.

Шаг 3 — Изменение имени сервера

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

По умолчанию для server_name установлено значение _ (подчеркивание), что означает, что файл конфигурации отвечает за все входящие запросы. Измените _ на свой фактический домен, например:

server_name example.com;

Сохраните файл конфигурации и отредактируйте текстовый редактор.

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

  1. sudo nginx -t

Если синтаксис не содержит ошибок, вы увидите следующий вывод:

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

Шаг 4. Добавление SSL-сертификатов

Затем вам нужно настроить Nginx для использования вашего SSL-сертификата. Если вы не знаете, что такое SSL-сертификат, или в настоящее время у вас его нет, воспользуйтесь одним из руководств в разделе «Предварительные условия» этой статьи.

Создайте каталог для хранения ваших SSL-сертификатов внутри каталога конфигурации Nginx:

  1. sudo mkdir /etc/nginx/ssl

Скопируйте свой сертификат и закрытый ключ в это место. Мы также переименуем файлы, чтобы показать, с каким доменом они связаны. Это пригодится в будущем, когда у вас будет более одного домена, связанного с этим сервером. Замените example.com вашим фактическим именем хоста:

  1. sudo cp /path/to/your/certificate.crt /etc/nginx/ssl/example.com.crt
  2. sudo cp /path/to/your/private.key /etc/nginx/ssl/example.com.key

Теперь давайте снова откроем наш файл конфигурации и настроим SSL.

  1. sudo nano /etc/nginx/sites-available/default

В новых строках внутри блока server укажите расположение ваших сертификатов:

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

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

Шаг 5 — Избегайте старых наборов шифров

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

Мы будем использовать действительно популярный набор шифров, безопасность которого была одобрена такими интернет-гигантами, как CloudFlare. Он не позволяет использовать шифрование MD5 (которое с 1996 года было известно как небезопасное, но, несмотря на это, широко распространено и по сей день).

Откройте следующий файл конфигурации:

  1. sudo nano /etc/nginx/nginx.conf

Добавьте эту строку после ssl_prefer_server_ciphers on;.

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

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

Еще раз проверьте конфигурацию на наличие синтаксических ошибок:

  1. sudo nginx -t

Шаг 6 — Повышение безопасности обмена ключами

Первым шагом в установлении безопасного соединения является обмен закрытыми ключами между сервером и клиентом. Проблема в том, что до этого момента соединение между ними не шифруется — а значит, передача данных видна любому третьему лицу. Вот почему нам нужен алгоритм Диффи-Хеллмана-Меркла. Технические подробности о том, как это работает, — сложный вопрос, который невозможно объяснить в двух словах, но если вас действительно интересуют подробности, вы можете посмотреть это видео на YouTube.

По умолчанию Nginx использует 1028-битный ключ DHE (Ephemeral Diffie-Hellman), который относительно легко расшифровать. Чтобы обеспечить максимальную безопасность, мы должны создать собственный, более безопасный ключ DHE.

Для этого введите следующую команду:

  1. sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

Имейте в виду, что мы должны генерировать параметры DH в той же папке, что и наши SSL-сертификаты. В этом руководстве сертификаты находятся в /etc/nginx/ssl/. Причина этого в том, что Nginx всегда ищет предоставленный пользователем ключ DHE в папке сертификатов и использует его, если он существует.

Переменная после пути к файлу (в нашем случае это 2048) указывает длину ключа. Ключ длиной 2048 бит достаточно надежен и рекомендован Mozilla Foundation, но если вам нужно еще больше шифрования, вы можете изменить его на 4096.

Процесс генерации займет около 5 минут.

После завершения снова откройте файл конфигурации Nginx по умолчанию:

  1. sudo nano /etc/nginx/sites-available/default

В новой строке внутри блока server определите местоположение вашего пользовательского ключа DHE:

ssl_dhparam  /etc/nginx/ssl/dhparam.pem;

Шаг 7 — Перенаправление всех HTTP-запросов на HTTPS

Поскольку мы заинтересованы в обслуживании контента только через HTTPS, мы должны указать Nginx, что он должен делать, если сервер получает HTTP-запрос.

Внизу нашего файла мы создадим новый блок сервера для перенаправления всех HTTP-запросов на HTTPS (не забудьте заменить имя сервера на ваше фактическое доменное имя):

server {
       listen         80;
       listen    [::]:80;
	   server_name    example.com;
       return         301 https://$server_name$request_uri;
}

Сохраните файл и выйдите из файла конфигурации.

Проверьте конфигурацию на наличие синтаксических ошибок:

  1. sudo nginx -t

Шаг 8 — Перезагрузка Nginx

Вот и все изменения конфигурации Nginx. Поскольку мы проверяли наличие синтаксических ошибок при каждом изменении, вы должны быть готовы перезапустить Nginx и протестировать свои изменения.

Подводя итог, игнорируя закомментированные строки, ваш файл конфигурации теперь должен выглядеть примерно так:

server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name example.com;

        location / {
                try_files $uri $uri/ =404;
        }

        ssl_certificate /etc/nginx/ssl/example.com.crt;
        ssl_certificate_key /etc/nginx/ssl/example.com.key;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
}


server {
       listen         80;
       listen    [::]:80;
       server_name    example.com;
       return         301 https://$server_name$request_uri;
}

Чтобы применить изменения, перезапустите сервер Nginx.

  1. sudo systemctl restart nginx

Шаг 9 — Проверка изменений

Давайте проверим, что наш сервер запущен и работает. Откройте веб-браузер и перейдите к своему домену (замените example.com своим фактическим доменным именем):

example.com

Если все настроено правильно, вы должны автоматически перенаправиться на HTTPS. Теперь давайте проверим, работает ли HTTP/2: откройте Инструменты разработчика Chrome (Вид -> Разработчик -> Инструменты разработчика) и перезагрузите страницу (Вид -> Перезагрузить эту страницу). Затем перейдите на вкладку «Сеть», щелкните строку заголовка таблицы, начинающуюся с «Имя», щелкните ее правой кнопкой мыши и выберите параметр «Протокол».

Теперь вы должны увидеть h2 (что означает HTTP/2) в новом столбце для вашего веб-сайта, обслуживающего содержимое HTTP/2.

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

Шаг 10 — Оптимизация Nginx для лучшей производительности

На этом этапе мы настроим основной файл конфигурации Nginx для обеспечения максимальной производительности и безопасности.

Прежде всего, давайте откроем nginx.conf, введя в консоли следующее:

  1. sudo nano /etc/nginx/nginx.conf

Включение кэширования учетных данных подключения

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

Чтобы включить кеширование сеанса, добавьте следующие строки в конец блока http вашего файла nginx.conf:

ssl_session_cache shared:SSL:5m;
ssl_session_timeout 1h;

ssl_session_cache указывает размер кеша, который будет содержать информацию о сеансе. 1 МБ может хранить информацию примерно о 4000 сессиях. Значение по умолчанию 5 МБ будет более чем достаточно для большинства пользователей, но если вы ожидаете действительно большой трафик, вы можете соответственно увеличить это значение.

ssl_session_timeout ограничивает время, в течение которого определенные сеансы хранятся в кеше. Это значение не должно быть слишком большим (более часа), но и устанавливать слишком низкое значение также бессмысленно.

Включение строгой безопасности транспорта HTTP (HSTS)

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

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

Добавьте эту строку в nginx.conf:

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;

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

Еще раз проверьте конфигурацию на наличие синтаксических ошибок:

  1. sudo nginx -t

Наконец, перезапустите сервер Nginx, чтобы изменения вступили в силу.

  1. sudo systemctl restart nginx

Заключение

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