HTTP/2 в Nginx: какой способ включения выбрать
В Nginx 1.25.1 появился отдельный параметр http2 on, а старый вариант с http2 в listen помечен устаревшим. Сравниваем оба подхода, разбираем TLS, проверку через curl и ошибки, из-за которых сайт продолжает работать по HTTP/1.1.

В Nginx 1.25.1 настройка HTTP/2 разделилась на современный и устаревающий варианты: теперь протокол включают директивой http2 on, а параметр http2 внутри listen оставили для совместимости. Ошибка в выборе синтаксиса обычно не ломает сайт полностью: Nginx может запуститься, но клиент продолжит подключаться по HTTP/1.1 или конфигурация не пройдёт проверку. Ниже — три рабочих подхода для Nginx с модулем ngx_http_v2_module, их цена и способ убедиться, что HTTP/2 действительно используется.
Сначала определите версию и сценарий
Материал рассчитан на Nginx 1.25.x и новее, установленный с модулем ngx_http_v2_module. Проверить версию и набор модулей можно командой:
nginx -v
nginx -V 2>&1 | grep http_v2
В выводе второй команды должна встретиться опция --with-http_v2_module. Если её нет, директивы HTTP/2 не заработают: понадобится пакет Nginx с этим модулем или сборка из исходников.
Для обычного публичного сайта нужен HTTP/2 поверх TLS. Браузеры договариваются о протоколе через ALPN во время TLS-соединения, поэтому одного параметра http2 on недостаточно: сервер должен слушать HTTPS-порт и иметь корректный сертификат.
ALPN1 — расширение TLS, с помощью которого клиент и сервер выбирают прикладной протокол, например HTTP/2 или HTTP/1.1, ещё до отправки обычного HTTP-запроса.
Три способа настроить HTTP/2
| Подход | Когда использовать | Плюсы | Цена и риск |
|---|---|---|---|
http2 on в блоке server | Nginx 1.25.1 и новее | Актуальный синтаксис, HTTP/2 включается отдельно от listen | Нужно проверить версию и наличие модуля |
listen 443 ssl http2 | Nginx старше 1.25.1 или конфигурация, которую нельзя быстро обновить | Работает в старых версиях и знаком большинству администраторов | В новых версиях параметр помечен устаревшим; при обновлении появится предупреждение |
| HTTP/2 без TLS, h2c | Редкие контролируемые внутренние сценарии | Нет TLS-рукопожатия между конкретными узлами | Не является заменой HTTPS для браузерного сайта; совместимость и настройка зависят от клиента и прокси |
Для внешнего сайта выбор обычно сводится не к «HTTP/2 или HTTP/1.1», а к «современная директива в новой версии Nginx или совместимый синтаксис в старой».
Подход 1: отдельная директива http2
Это основной вариант для Nginx 1.25.1+. HTTP/2 включается в том же виртуальном хосте, где настроен TLS:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
http2 on;
root /var/www/example.com;
index index.html;
}
Пути к сертификату здесь примерные: замените их на реальные пути вашей системы. Перенаправление с 80-го порта не включает HTTP/2 само по себе — оно только отправляет клиента на HTTPS.
Почему это предпочтительнее в новых версиях: транспортный порт и свойства HTTP-протокола не смешаны в одной строке. Позже проще добавлять другие параметры и переносить блок между окружениями.
Проверка конфигурации и мягкая перезагрузка:
sudo nginx -t
sudo systemctl reload nginx
Команда nginx -t должна завершиться сообщением syntax is ok и test is successful. После reload новые соединения начнут использовать обновлённую конфигурацию.
Подход 2: параметр http2 внутри listen
До Nginx 1.25.1 HTTP/2 обычно включали так:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
root /var/www/example.com;
index index.html;
}
Для старого Nginx это нормальный рабочий синтаксис. В Nginx 1.25.1 и новее он считается устаревшим, поэтому при проверке конфигурации можно увидеть предупреждение о deprecated parameter. Само предупреждение не означает, что HTTP/2 уже отключён, но его не стоит игнорировать перед плановым обновлением.
Не используйте оба способа одновременно в одном виртуальном хосте. Например, сочетание listen 443 ssl http2 и http2 on не добавляет производительности и может привести к конфликту или предупреждению. Выберите синтаксис по версии Nginx.
Подход 3: h2c и почему он не заменяет HTTPS
h2c — это HTTP/2 без TLS. Такой режим иногда нужен между сервисами в закрытой сети, но для публичного сайта он не равен привычному HTTP/2 в браузере. Клиент должен поддерживать соответствующий способ установления соединения, а промежуточный балансировщик или CDN может вернуть трафик к HTTP/1.1.
Практический вывод простой: не пытайтесь убрать TLS ради HTTP/2 на сайте. Используйте HTTPS, ALPN и обычную схему с портом 443. Если нужен HTTP/2 между внутренними сервисами, сначала проверьте документацию конкретной версии Nginx и всех прокси в цепочке. Подробная настройка h2c выходит за рамки этого материала.
Как проверить, что клиент получил HTTP/2
Статус 200 ещё ничего не доказывает: тот же ответ может прийти по HTTP/1.1. Нужна проверка версии протокола. В актуальном curl используйте:
curl -I --http2 https://example.com/
В первой строке ожидается HTTP/2 200 или другой код ответа уже в формате HTTP/2. Если curl собран без HTTP/2, он сообщит об этом вместо выполнения запроса. Узнать возможности конкретной сборки:
curl -V
В списке features должна присутствовать поддержка HTTP/2, обычно обозначенная как HTTP2. Для просмотра согласования протокола и сертификата можно использовать подробный режим:
curl -I --http2 -v https://example.com/
Ищите в выводе строки о согласованном протоколе, а не только успешный код ответа. Дополнительно проверьте сайт в панели разработчика браузера: в таблице сетевых запросов колонка Protocol должна показывать h2.
Что ломается чаще всего
Nginx не знает директиву http2
Ошибка вида unknown directive "http2" обычно означает старую версию Nginx либо сборку без модуля HTTP/2. Сначала выполните nginx -v и nginx -V. Для старой версии временно используйте синтаксис с listen ... http2; если модуля нет, смена синтаксиса не поможет.
HTTP/2 включён, но браузер показывает h1
Проверьте, что запрос идёт на HTTPS, сертификат подходит имени сайта, а порт 443 действительно обслуживает нужный блок server. За Nginx может стоять CDN или балансировщик, который устанавливает клиентское соединение сам и до вашего сервера ходит по HTTP/1.1.
curl пишет, что HTTP/2 недоступен
Это может быть ограничением сборки curl, а не Nginx. Сравните результат curl -V и попробуйте проверить сайт из браузера или другой машины с curl, собранным с HTTP/2.
После изменения сайт перестал открываться
Не перезапускайте Nginx вслепую. Выполните sudo nginx -t, исправьте конкретную строку из сообщения об ошибке и только затем делайте reload. Если ошибка связана с сертификатом или ключом, HTTP/2 здесь ни при чём: сначала восстановите корректный TLS.
Когда выбирать какой вариант
- У вас Nginx 1.25.1 или новее — используйте
listen 443 sslи отдельную директивуhttp2 on. - У вас старая версия, которую нельзя обновить сейчас, — оставьте
listen 443 ssl http2и запланируйте миграцию синтаксиса. - Вам нужен протокол между внутренними сервисами — сначала подтвердите поддержку h2c каждым клиентом, прокси и балансировщиком. Не переносите такую схему на публичный сайт.
- Сайт работает за CDN — проверяйте HTTP/2 на внешнем домене и отдельно между CDN и origin. Это два разных соединения.
Что сделать после включения
Сначала зафиксируйте версию Nginx, конфигурацию TLS и результат проверки через curl. Затем проверьте реальные страницы с большим числом мелких ресурсов: именно на них виден эффект мультиплексирования HTTP/2, когда несколько запросов идут в одном соединении. Не ожидайте автоматического ускорения тяжёлого серверного рендера или медленных SQL-запросов — HTTP/2 меняет транспорт, но не исправляет узкие места приложения.
В проде смотрите на долю соединений по протоколам h2 и http/1.1, ошибки TLS, время до первого байта и количество открытых соединений. После обновления Nginx отдельно уберите устаревший параметр из listen и оставьте один способ включения HTTP/2.
1 ALPN расшифровывается как Application-Layer Protocol Negotiation — согласование протокола прикладного уровня внутри TLS-соединения.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Официальная документация Nginx: ngx_http_v2_module, Официальная документация Nginx: директива listen
Частые вопросы
Нужно ли включать HTTP/2 на порту 80?
Можно ли одновременно указать http2 on и http2 в listen?
Почему сайт после настройки всё ещё работает по HTTP/1.1?
Что делать, если у меня Nginx старше 1.25.1?
HTTP/2 обязательно ускорит сайт?
Есть ли риск включать HTTP/2 на работающем сайте?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.