HTTP/2 и HTTP/3 в Nginx: как включить за 15 минут

Сайты и веб-серверы
HTTP/2 и HTTP/3 в Nginx: как включить за 15 минут

Включить HTTP/2 и HTTP/3 в Nginx — задача на 15 минут, а отдача заметная: мультиплексирование запросов, быстрое установление соединения и устойчивость к потерям пакетов ускоряют загрузку сайта, особенно на мобильных сетях. HTTP/2 включается одной директивой http2 on, HTTP/3 требует чуть больше: сборки Nginx с модулем QUIC, директивы listen 443 quic reuseport, заголовка Alt-Svc и открытого UDP-порта 443. В этом руководстве пройдём весь путь на Ubuntu 24.04 LTS: проверим сборку, подключим официальный репозиторий nginx.org, напишем рабочий конфиг и убедимся, что браузер действительно ходит по h3.

Чем HTTP/2 и HTTP/3 лучше старого HTTP/1.1

HTTP/1.1 обрабатывает запросы в соединении по очереди: пока не отдана картинка, CSS ждёт. Браузеры обходят это, открывая по 6 параллельных TCP-соединений на домен, но это дорого и медленно. Современные протоколы решают проблему в корне:

  • HTTP/2 — мультиплексирование: десятки запросов идут параллельно в одном TCP-соединении, заголовки сжимаются (HPACK), у запросов есть приоритеты;
  • HTTP/3 — тот же принцип, но поверх QUIC (UDP): соединение и TLS-рукопожатие устанавливаются за один круговой обход, потерянный пакет тормозит только свой поток, а не всё соединение, при смене сети (Wi-Fi → LTE) соединение не рвётся.
СвойствоHTTP/1.1HTTP/2HTTP/3
ТранспортTCPTCPQUIC (UDP)
Запросов на соединение1 за разМного (мультиплекс)Много (мультиплекс)
Установление соединения + TLS2–3 RTT2–3 RTT1 RTT (0-RTT повторно)
Потеря пакетаТормозит соединениеТормозит все потокиТормозит один поток
Требует TLSНетВ браузерах — даДа, только TLS 1.3

Оба протокола работают только по HTTPS, так что сначала понадобится сертификат — если его ещё нет, начните со статьи о бесплатном SSL от Let's Encrypt.

Шаг 1. Проверяем, умеет ли ваш Nginx HTTP/3

HTTP/3 появился в Nginx начиная с версии 1.25, а в штатном репозитории Ubuntu 24.04 лежит Nginx 1.24 — без модуля QUIC. Проверьте свою сборку:

nginx -v
nginx -V 2>&1 | grep -o with-http_v3_module

Если вторая команда ничего не вывела, поставьте свежий Nginx из официального репозитория nginx.org (сборки для Ubuntu собраны с http_v3_module):

sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
  | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
  http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
  | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx

Учтите: пакет с nginx.org не использует каталоги sites-available/sites-enabled — конфиги сайтов кладите в /etc/nginx/conf.d/*.conf. Если ставите Nginx с нуля, базовая настройка разобрана в статье об установке Nginx на Ubuntu.

Шаг 2. Включаем HTTP/2

С Nginx 1.25.1 протокол включается отдельной директивой http2 on; — старый вариант listen 443 ssl http2; объявлен устаревшим. Минимальный HTTPS-блок:

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

    server_name example.ru;

    ssl_certificate     /etc/letsencrypt/live/example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    root /var/www/example.ru;
    index index.html;
}

Примените и проверьте:

sudo nginx -t && sudo systemctl reload nginx
curl -sI --http2 https://example.ru | head -1

Ответ HTTP/2 200 означает, что протокол работает. Никаких изменений в приложении не требуется — HTTP/2 прозрачен для сайта.

Шаг 3. Включаем HTTP/3: listen 443 quic и Alt-Svc

Теперь главное. HTTP/3 живёт на UDP, поэтому серверу нужен второй слушающий сокет — listen 443 quic — и способ сообщить браузеру о его существовании — заголовок Alt-Svc. Полный конфиг:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;

    http2 on;
    http3 on;

    server_name example.ru;

    ssl_certificate     /etc/letsencrypt/live/example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # сообщаем браузеру, что сайт доступен по HTTP/3 на UDP 443
    add_header Alt-Svc 'h3=":443"; ma=86400' always;

    root /var/www/example.ru;
    index index.html;
}

Что здесь важно понимать:

  • listen 443 quic reuseport — открывает UDP-сокет для QUIC. Параметр reuseport даёт каждому worker-процессу свой сокет (иначе пакеты одного QUIC-соединения могут разъехаться по разным процессам), но указывается только один раз на адрес:порт — во втором server-блоке пишите просто listen 443 quic;;
  • http3 on; — разрешает согласование HTTP/3 (включена по умолчанию при наличии quic-сокета, но явная запись делает конфиг понятнее);
  • Alt-Svc: h3=":443"; ma=86400 — браузер узнаёт о HTTP/3 именно из этого заголовка: первый визит идёт по TCP (HTTP/2), а следующие запросы — уже по QUIC; ma=86400 велит помнить это сутки;
  • TLSv1.3 обязателен — QUIC использует его как встроенный слой шифрования.

Осталось открыть UDP-порт в файрволе — про это чаще всего и забывают:

sudo ufw allow 443/udp
sudo nginx -t && sudo systemctl reload nginx

Шаг 4. Проверяем, что HTTP/3 работает

Способ 1 — браузер. Откройте DevTools (F12) → вкладка Network → правой кнопкой по шапке таблицы → включите колонку Protocol. Обновите страницу два-три раза: сначала увидите h2, затем запросы перейдут на h3 (браузеру нужно получить Alt-Svc и запомнить его).

Способ 2 — curl, если он собран с поддержкой HTTP/3 (проверьте curl -V | grep HTTP3):

curl -sI --http3 https://example.ru | head -1

Способ 3 — онлайн-проверки: http3check.net или тест HTTP/2/3 в любом сервисе анализа заголовков. Дополнительно можно логировать протокол в access-логе, добавив в log_format переменную $server_protocol — в строках появится HTTP/3.0.

Подводные камни и тонкая настройка

  • UDP заблокирован по пути. Некоторые корпоративные сети режут UDP 443 — это штатно: браузер тихо откатится на HTTP/2. Именно поэтому HTTP/3 всегда включают в дополнение к TCP-протоколам, а не вместо них.
  • Несколько сайтов на сервере. reuseport — только в одном server-блоке; заголовок Alt-Svc и http3 on нужны в каждом.
  • 0-RTT. Директива ssl_early_data on; ускоряет повторные подключения ещё на один RTT, но открывает теоретическую возможность replay-атак на не-идемпотентные запросы — включайте осознанно и только если приложение к этому готово.
  • Буферы UDP. На нагруженных серверах увеличьте системные буферы: sudo sysctl -w net.core.rmem_max=2500000 net.core.wmem_max=2500000 (и зафиксируйте в /etc/sysctl.d/). Остальные приёмы разгона — в статье об оптимизации Nginx под нагрузку.
  • Сжатие никто не отменял. HTTP/3 ускоряет доставку, но объём данных сокращают Gzip и Brotli — включите их тоже, эффекты складываются.

И о железе: QUIC шифрует и собирает пакеты в user-space, поэтому HTTP/3 заметно требовательнее к CPU, чем HTTP/2 (ядро Linux оптимизирует TCP десятилетиями, а UDP-стек QUIC работает силами самого Nginx). На слабом однопроцессорном VPS под трафиком это чувствуется. У Cheap-Host для таких задач подходит тариф Pro — 12 vCPU, 16 ГБ RAM и NVMe за 750 ₽/мес: запаса по ядрам хватает и на TLS, и на QUIC даже в пиках, а канал 100 Мбит/с с безлимитным трафиком не добавит своих ограничений. Сервер выдаётся за 45–60 секунд — быстрее, чем обновится DNS.

FAQ

Насколько HTTP/3 быстрее HTTP/2?

На стабильном проводном канале — единицы процентов. Выигрыш заметен на мобильных и нестабильных сетях: соединение за 1 RTT, отсутствие блокировки очереди на потерянных пакетах, переживание смены сети без переподключения. На практике — минус 100–300 мс к первой загрузке у мобильных посетителей.

Почему HTTP/3 не включается, хотя конфиг правильный?

Три типичные причины: закрыт UDP 443 (нужно ufw allow 443/udp), в сборке нет http_v3_module (проверьте nginx -V) или отключён TLSv1.3. И помните: браузер переходит на h3 только после получения Alt-Svc — обновите страницу пару раз.

Можно ли включить HTTP/3 и оставить HTTP/2 и HTTP/1.1?

Да, так и нужно: listen 443 ssl, http2 on и listen 443 quic работают в одном server-блоке. Клиенты без QUIC остаются на TCP, современные браузеры переключаются на HTTP/3 сами.

Зачем нужен reuseport и почему Nginx ругается на дубликат?

reuseport даёт каждому worker-процессу собственный UDP-сокет, чтобы пакеты одного соединения попадали в один процесс. Указывать его можно только в одном server-блоке на адрес:порт — в остальных пишите просто listen 443 quic;.

Нужен ли для HTTP/3 особый сертификат?

Нет, подойдёт любой действующий, включая бесплатный Let's Encrypt. Единственное требование — поддержка TLS 1.3 на сервере.

Вывод

HTTP/2 включается одной строкой, HTTP/3 — четырьмя: свежий Nginx, listen 443 quic reuseport, http3 on и заголовок Alt-Svc плюс открытый UDP 443. Пятнадцать минут работы — и сайт использует те же протоколы, что и крупнейшие площадки интернета, а мобильные посетители получают страницы ощутимо быстрее. Если для экспериментов или продакшена нужен сервер — у Cheap-Host тариф Pro от 750 ₽/мес: 12 vCPU, 16 ГБ RAM, NVMe, KVM, безлимитный трафик и выдача за минуту. Все тарифы — на cheap-host.onl.

Читайте также