← Назад в базу знаний

QUIC и HTTP/3: ломаем прокси-костыли

QUIC и HTTP/3: ломаем прокси-костыли

Традиционное проксирование трафика держалось на трёх китах: TCP-соединения, фиксированные порты, прозрачные заголовки. QUIC и HTTP/3 выбивают эти опоры одну за другой.

UDP вместо TCP. Шифрование на уровне транспорта. Невозможность подменять пакеты на лету. Для прокси — это катастрофа. Или возможность пересобрать архитектуру с нуля.

Почему QUIC не дружит с классическими прокси

Классический HTTP-прокси работает просто: клиент шлёт `CONNECT example.com:443`, прокси поднимает TCP-туннель. Всё прозрачно, всё контролируемо.

QUIC ломает эту схему на старте. Соединение начинается с handshake, где уже зашит TLS 1.3. Прокси видит UDP-пакеты, но не может их расшифровать. Нет способа понять, куда клиент на самом деле стучится.

Пример: curl через HTTP/3 без прокси:

```bash

curl --http3 https://example.com

```

Пакеты уходят на 443 порт UDP. Прокси, ожидающий TCP, просто молча дропает трафик.

Проблема с маршрутизацией UDP

QUIC использует Connection ID — уникальный идентификатор, вшитый в каждый пакет. Это позволяет клиенту менять IP-адреса без разрыва соединения. Для прокси это ад.

Представьте: клиент начал сессию через Wi-Fi, переключился на мобильный интернет. IP изменился. Connection ID остался тот же. Прокси, который балансировал трафик по IP, теперь не знает, куда отправлять пакеты.

Пример настройки nginx для проксирования QUIC:

```nginx

stream {

upstream quic_backend {

server 10.0.0.1:443;

server 10.0.0.2:443;

}

server {

listen 443 udp;

proxy_pass quic_backend;

}

}

```

Проблема: без поддержки Connection ID балансировщик будет разбрасывать пакеты одной сессии на разные серверы. Клиент получит кашу из данных.

Шифрование на уровне транспорта — невидимый враг

HTTP/2 шифровал только данные. Заголовки можно было читать, кешировать, подменять. HTTP/3 шифрует всё — включая заголовки и даже часть транспортного уровня.

Для прокси это значит: вы не видите, какой хост запрашивает клиент. Нет возможности применить правила доступа на основе URL. Нет кеширования по доменам.

Единственное, что видит прокси — IP-адрес назначения и UDP-порт. Всё остальное — чёрный ящик.

Кейс: балансировщик на HAProxy сломался на QUIC

Проблема: HAProxy 2.4 не умел корректно обрабатывать QUIC. При попытке проксировать трафик на backend серверы, клиенты получали ошибку `QUIC connection error`.

Причина: HAProxy пытался переписать Connection ID в пакетах. QUIC использует этот ID для проверки целостности сессии. Любое изменение — и соединение рвётся.

Технические детали: в QUIC каждый пакет содержит Connection ID длиной 8 байт. HAProxy менял его на свой. Backend сервер не мог сверить ID с оригиналом — ответ не доходил до клиента.

Решение: обновление до HAProxy 2.6 с поддержкой `quic-ccid` — опция, заставляющая балансировщик не трогать Connection ID. Плюс настройка `tune.quic.socket-owner` для корректной маршрутизации.

Кейс: nginx как прокси для HTTP/3

Проблема: nginx 1.25 с поддержкой HTTP/3 работал, но клиенты жаловались на задержки до 500 мс при переключении между сетями.

Причина: nginx не поддерживал миграцию соединений QUIC. Когда клиент менял IP, прокси сбрасывал сессию. Клиент был вынужден делать новый handshake — это +300-500 мс.

Технические детали: QUIC поддерживает миграцию через механизм PATH_CHALLENGE и PATH_RESPONSE. nginx 1.25 не реализовал этот механизм для проксируемых соединений. Пакеты с новым IP просто игнорировались.

Решение: настройка `quic_migration on` в nginx 1.26+. И проксирование через UDP-сокет с привязкой к Connection ID, а не к IP.

Кейс: корпоративный прокси и QUIC — конфликт поколений

Проблема: корпоративный прокси на Squid блокировал все UDP-пакеты на 443 порт. Клиенты не могли открыть YouTube через HTTP/3.

Причина: Squid не поддерживает QUIC. Все UDP-пакеты на 443 порт дропались правилом `deny udp 443`. Админы просто не знали, что YouTube перешёл на QUIC.

Технические детали: YouTube использует QUIC для 70% трафика. Без проксирования QUIC — клиенты получают ошибку `ERR_QUIC_PROTOCOL_ERROR`. Браузер падает на TCP-версию, но с задержкой в 1-2 секунды.

Решение: настройка `acl QUIC proto UDP` и `http_access allow QUIC`. Плюс проброс трафика на сервер, поддерживающий QUIC-прокси. Или полный отказ от проксирования — прямой доступ к YouTube.

Как проксировать QUIC: рабочие схемы

Есть три способа проксировать QUIC. Ни один не идеален.

Первый — пассивное проксирование. Прокси просто пересылает UDP-пакеты без анализа. Пример настройки iptables:

```bash

iptables -t nat -A PREROUTING -p udp --dport 443 -j DNAT --to-destination 10.0.0.1:443

```

Минус: нет балансировки, нет кеширования, нет логирования.

Второй — прокси с поддержкой QUIC на уровне ядра. Например, Envoy с конфигом:

```yaml

static_resources:

listeners:

- name: quic_listener

address:

socket_address:

protocol: UDP

address: 0.0.0.0

port_value: 443

udp_listener_config:

downstream_quic_config:

quic_config:

crypto_config:

crypto_key: "/etc/ssl/private/key.pem"

```

Плюс: полный контроль, балансировка, метрики. Минус: сложная настройка, высокие требования к CPU.

Третий — прокси на уровне приложения. Например, Python-скрипт с aioquic:

```python

import asyncio

from aioquic.asyncio import connect

from aioquic.quic.configuration import QuicConfiguration

async def proxy_quic():

config = QuicConfiguration(is_client=True)

async with connect("example.com", 443, configuration=config) as client:

async with client.open_stream() as stream:

await stream.send(b"GET / HTTP/3")

response = await stream.receive()

print(response)

asyncio.run(proxy_quic())

```

Минус: медленно, не подходит для продакшена.

Что делать с DNS-over-QUIC

DNS-over-QUIC (DoQ) — ещё один вызов для прокси. Стандартный DNS-прокси ожидает UDP на 53 порту. DoQ использует QUIC на 853 порту.

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

Решение: либо отключать DoQ на клиентах, либо использовать DNS-прокси с поддержкой QUIC. Например, Unbound с опцией `do-quic: yes`.

Будущее проксирования: QUIC как стандарт

QUIC и HTTP/3 — это не временная мода. Это фундаментальный сдвиг. TCP умирает, UDP становится транспортом для всего.

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

Пример: lexic.ml уже поддерживает QUIC-проксирование с 2023 года. Настройка балансировки по Connection ID, а не по IP. Поддержка миграции соединений. Прозрачное проксирование без потери скорости.

Итог: три правила для работы с QUIC

Первое — не трогай пакеты. Любое изменение Connection ID или заголовков — и соединение рвётся.

Второе — используй UDP-балансировку с поддержкой QUIC. nginx 1.26+, HAProxy 2.6+, Envoy 1.28+ — только эти версии.

Третье — готовься к тому, что 50% трафика уйдёт в QUIC в ближайшие два года. Если твой прокси не умеет работать с UDP на 443 порту — ты отрезан от половины интернета.

QUIC ломает прокси. Но это не проблема. Это возможность пересобрать архитектуру правильно. С нуля. Без костылей.

✔️Купить прокси