Nginx: stream preread buffer limit exceeded — Настройка SSL Preread
При использовании Nginx для TCP/UDP проксирования со считыванием SNI (модуль ngx_stream_ssl_preread_module) входящие TLS-соединения сбрасываются. В логе error.log появляется запись: client connection rejected by preread buffer limit while prereading client data.
| Параметр Stream | Значение по умолчанию | Причина отказа |
|---|---|---|
preread_buffer_size | 16k | Пакет TLS Client Hello превысил размер буфера предварительного чтения |
ssl_preread on; | Парсинг SNI на L4 уровне | Клиент отправляет огромный список Cipher Suites / ALPN расширений |
| Тип соединения | TCP Raw Stream | Сброс TCP сокета клиенту (RST) |
- Клиенты не могут установить защищенное соединение на L4 TCP-балансировщике.
- Сбой возникает на клиентах с объемными расширениями рукопожатия TLS (ECH — Encrypted Client Hello, пост-квантовые шифры).
- Откройте блок конфигурации
stream {}в/etc/nginx/nginx.conf. - Увеличьте размер буфера предварительного чтения данных
preread_buffer_sizeв секцииstreamили целевомserver:stream { # Увеличиваем буфер предварительного чтения до 64k или 128k: preread_buffer_size 64k; preread_timeout 10s; # Роутинг TCP-трафика на основе домена (SNI) без расшифровки сертификата: map $ssl_preread_server_name $backend_pool { app.example.com backend_app_cluster; secure.example.com backend_secure_cluster; default backend_default; } server { listen 443; ssl_preread on; proxy_pass $backend_pool; } } - Убедитесь, что таймаут
preread_timeoutдостаточен для медленных мобильных клиентов. - Проверьте валидность файла конфигурации:
sudo nginx -t - Примените параметры:
sudo systemctl reload nginx.
ssl_preread позволяет Nginx извлекать доменное имя (SNI) из первого пакета TLS Client Hello без терминации TLS-соединения и без наличия приватных SSL-ключей, проксируя сырой зашифрованный TCP-трафик на конечные серверы.Частые вопросы (FAQ)
Зачем нужен preread_buffer_size в Nginx Stream?
Этот буфер выделяется в памяти для временного сохранения начальных байтов TCP-потока клиента, чтобы Nginx успел распарсить имя сервера (SNI) или заголовок PROXY-протокола до принятия решения о маршрутизации.
Почему пакет TLS Client Hello может превышать 16 КБ?
Современные браузеры могут передавать объемные списки поддерживаемых эллиптических кривых, ALPN протоколы, токены сессионных тикетов и новые экспериментальные постквантовые наборы шифров.
Требуется ли SSL сертификат на стороне Nginx при использовании ssl_preread?
Нет, Nginx работает как прозрачный TCP-маршрутизатор 4-го уровня (L4). Расшифровка трафика и проверка сертификатов происходят напрямую на целевых бэкендах.
Поддерживает ли stream модуль протокол UDP?
Да, Nginx Stream умеет балансировать как TCP, так и UDP потоки (например, DNS запросы на 53 порту).