Модуль ngx_stream_core_module

Пример конфигурации
Директивы
     listen
     preread_buffer_size
     preread_timeout
     proxy_protocol_timeout
     resolver
     resolver_timeout
     server
     stream
     tcp_nodelay
     variables_hash_bucket_size
     variables_hash_max_size
Встроенные переменные

Модуль ngx_stream_core_module доступен начиная с версии 1.9.0. По умолчанию этот модуль не собирается, его сборку необходимо разрешить с помощью конфигурационного параметра --with-stream.

Пример конфигурации

worker_processes auto;

error_log /var/log/nginx/error.log info;

events {
    worker_connections  1024;
}

stream {
    upstream backend {
        hash $remote_addr consistent;

        server backend1.example.com:12345 weight=5;
        server 127.0.0.1:12345            max_fails=3 fail_timeout=30s;
        server unix:/tmp/backend3;
    }

    upstream dns {
       server 192.168.0.1:53535;
       server dns.example.com:53;
    }

    server {
        listen 12345;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass backend;
    }

    server {
        listen 127.0.0.1:53 udp reuseport;
        proxy_timeout 20s;
        proxy_pass dns;
    }

    server {
        listen [::1]:12345;
        proxy_pass unix:/tmp/stream.socket;
    }
}

Директивы

Синтаксис: listen адрес:порт [ssl] [udp] [proxy_protocol] [fastopen=число] [backlog=число] [rcvbuf=размер] [sndbuf=размер] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
Умолчание:
Контекст: server

Задаёт адрес и порт для сокета, на котором сервер будет принимать соединения. Можно указать только порт. Кроме того, адрес может быть именем хоста, например:

listen 127.0.0.1:12345;
listen *:12345;
listen 12345;     # то же, что и *:12345
listen localhost:12345;

IPv6-адреса задаются в квадратных скобках:

listen [::1]:12345;
listen [::]:12345;

UNIX-сокеты задаются префиксом “unix:

listen unix:/var/run/nginx.sock;

Диапазоны портов (1.15.10) задаются при помощи указания первого и последнего порта через дефис:

listen 127.0.0.1:12345-12399;
listen 12345-12399;

Параметр ssl указывает на то, что все соединения, принимаемые на данном порту, должны работать в режиме SSL.

Параметр udp конфигурирует слушающий сокет для работы с датаграммами (1.9.13). Для обработки пакетов с одного адреса и порта в рамках одной сессии необходимо также указывать параметр reuseport.

Параметр proxy_protocol (1.11.4) указывает на то, что все соединения, принимаемые на данном порту, должны использовать протокол PROXY.

Протокол PROXY версии 2 поддерживается начиная с версии 1.13.11.

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

fastopen=число
включает “TCP Fast Open” для слушающего сокета (1.21.0) и ограничивает максимальную длину очереди соединений, которые ещё не завершили процесс three-way handshake.
Не включайте “TCP Fast Open”, не убедившись, что сервер может адекватно обрабатывать многократное получение одного и того же SYN-пакета с данными.
backlog=число
задаёт параметр backlog в вызове listen(), который ограничивает максимальный размер очереди ожидающих приёма соединений (1.9.2). По умолчанию backlog устанавливается равным -1 для FreeBSD, DragonFly BSD и macOS, и 511 для других платформ.
rcvbuf=размер
задаёт размер буфера приёма (параметр SO_RCVBUF) для слушающего сокета (1.11.13).
sndbuf=размер
задаёт размер буфера передачи (параметр SO_SNDBUF) для слушающего сокета (1.11.13).
bind
параметр указывает, что для данной пары адрес:порт нужно делать bind() отдельно. Это нужно потому, что если описаны несколько директив listen с одинаковым портом, но разными адресами, и одна из директив listen слушает на всех адресах для данного порта (*:порт), то nginx сделает bind() только на *:порт. Необходимо заметить, что в этом случае для определения адреса, на которой пришло соединение, делается системный вызов getsockname(). Если же используются параметры backlog, rcvbuf, sndbuf, ipv6only, reuseport или so_keepalive, то для данной пары адрес:порт всегда делается отдельный вызов bind().
ipv6only=on|off
этот параметр определяет (через параметр сокета IPV6_V6ONLY), будет ли слушающий на wildcard-адресе [::] IPv6-сокет принимать только IPv6-соединения, или же одновременно IPv6- и IPv4-соединения. По умолчанию параметр включён. Установить его можно только один раз на старте.
reuseport
этот параметр (1.9.1) указывает, что нужно создавать отдельный слушающий сокет для каждого рабочего процесса (через параметр сокета SO_REUSEPORT для Linux 3.9+ и DragonFly BSD или SO_REUSEPORT_LB для FreeBSD 12+), позволяя ядру распределять входящие соединения между рабочими процессами. В настоящий момент это работает только на Linux 3.9+, DragonFly BSD и FreeBSD 12+ (1.15.1).
Ненадлежащее использование параметра может быть небезопасно.
so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]
этот параметр конфигурирует для слушающего сокета поведение “TCP keepalive”. Если этот параметр опущен, то для сокета будут действовать настройки операционной системы. Если он установлен в значение “on”, то для сокета включается параметр SO_KEEPALIVE. Если он установлен в значение “off”, то для сокета параметр SO_KEEPALIVE выключается. Некоторые операционные системы поддерживают настройку параметров “TCP keepalive” на уровне сокета посредством параметров TCP_KEEPIDLE, TCP_KEEPINTVL и TCP_KEEPCNT. На таких системах (в настоящий момент это Linux 2.4+, NetBSD 5+ и FreeBSD 9.0-STABLE) их можно сконфигурировать с помощью параметров keepidle, keepintvl и keepcnt. Один или два параметра могут быть опущены, в таком случае для соответствующего параметра сокета будут действовать стандартные системные настройки. Например,
so_keepalive=30m::10
установит таймаут бездействия (TCP_KEEPIDLE) в 30 минут, для интервала проб (TCP_KEEPINTVL) будет действовать стандартная системная настройка, а счётчик проб (TCP_KEEPCNT) будет равен 10.

Разные серверы должны слушать на разных парах адрес:порт.

Синтаксис: preread_buffer_size размер;
Умолчание:
preread_buffer_size 16k;
Контекст: stream, server

Эта директива появилась в версии 1.11.5.

Задаёт размер буфера предварительного чтения.

Синтаксис: preread_timeout время;
Умолчание:
preread_timeout 30s;
Контекст: stream, server

Эта директива появилась в версии 1.11.5.

Задаёт время фазы предварительного чтения.

Синтаксис: proxy_protocol_timeout время;
Умолчание:
proxy_protocol_timeout 30s;
Контекст: stream, server

Эта директива появилась в версии 1.11.4.

Задаёт время для завершения операции чтения заголовка протокола PROXY. Если по истечении этого времени заголовок полностью не получен, соединение закрывается.

Синтаксис: resolver адрес ... [valid=время] [ipv4=on|off] [ipv6=on|off] [status_zone=зона];
Умолчание:
Контекст: stream, server

Эта директива появилась в версии 1.11.3.

Задаёт серверы DNS, используемые для преобразования имён вышестоящих серверов в адреса, например:

resolver 127.0.0.1 [::1]:5353;

Адрес может быть указан в виде доменного имени или IP-адреса, и необязательного порта. Если порт не указан, используется порт 53. Серверы DNS опрашиваются циклически.

По умолчанию nginx будет искать как IPv4-, так и IPv6-адреса при преобразовании имён в адреса. Если поиск IPv4- или IPv6-адресов нежелателен, можно указать параметр ipv4=off (1.23.1) или ipv6=off.

По умолчанию nginx кэширует ответы, используя значение TTL из ответа. Необязательный параметр valid позволяет это переопределить:

resolver 127.0.0.1 [::1]:5353 valid=30s;

Для предотвращения DNS-спуфинга рекомендуется использовать DNS-серверы в защищённой доверенной локальной сети.

Необязательный параметр status_zone (1.17.1) включает сбор информации о запросах и ответах сервера DNS в указанной зоне. Параметр доступен как часть коммерческой подписки.

До версии 1.11.3 эта директива была доступна как часть коммерческой подписки.

Синтаксис: resolver_timeout время;
Умолчание:
resolver_timeout 30s;
Контекст: stream, server

Эта директива появилась в версии 1.11.3.

Задаёт таймаут для преобразования имени в адрес, например:

resolver_timeout 5s;

До версии 1.11.3 эта директива была доступна как часть коммерческой подписки.

Синтаксис: server { ... }
Умолчание:
Контекст: stream

Задаёт конфигурацию для сервера.

Синтаксис: stream { ... }
Умолчание:
Контекст: main

Предоставляет контекст конфигурационного файла, в котором указываются директивы stream-сервера.

Синтаксис: tcp_nodelay on | off;
Умолчание:
tcp_nodelay on;
Контекст: stream, server

Эта директива появилась в версии 1.9.4.

Разрешает или запрещает использование параметра TCP_NODELAY. Параметр включается как для клиентских соединений, так и для соединений с проксируемыми серверами.

Синтаксис: variables_hash_bucket_size размер;
Умолчание:
variables_hash_bucket_size 64;
Контекст: stream

Эта директива появилась в версии 1.11.2.

Задаёт размер корзины в хэш-таблице переменных. Подробнее настройка хэш-таблиц обсуждается в отдельном документе.

Синтаксис: variables_hash_max_size размер;
Умолчание:
variables_hash_max_size 1024;
Контекст: stream

Эта директива появилась в версии 1.11.2.

Задаёт максимальный размер хэш-таблицы переменных. Подробнее настройка хэш-таблиц обсуждается в отдельном документе.

Встроенные переменные

Модуль ngx_stream_core_module поддерживает переменные начиная с версии 1.11.2.

$binary_remote_addr
адрес клиента в бинарном виде, длина значения всегда 4 байта для IPv4-адресов или 16 байт для IPv6-адресов
$bytes_received
число байт, полученных от клиента (1.11.4)
$bytes_sent
число байт, переданных клиенту
$connection
порядковый номер соединения
$hostname
имя хоста
$msec
текущее время в секундах с точностью до миллисекунд
$nginx_version
версия nginx
$pid
номер (PID) рабочего процесса
$protocol
протокол, используемый для работы с клиентом: TCP или UDP (1.11.4)
$proxy_protocol_addr
адрес клиента, полученный из заголовка протокола PROXY (1.11.4)

Протокол PROXY должен быть предварительно включён при помощи установки параметра proxy_protocol в директиве listen.

$proxy_protocol_port
порт клиента, полученный из заголовка протокола PROXY (1.11.4)

Протокол PROXY должен быть предварительно включён при помощи установки параметра proxy_protocol в директиве listen.

$proxy_protocol_server_addr
адрес сервера, полученный из заголовка протокола PROXY (1.17.6)

Протокол PROXY должен быть предварительно включён при помощи установки параметра proxy_protocol в директиве listen.

$proxy_protocol_server_port
порт сервера, полученный из заголовка протокола PROXY (1.17.6)

Протокол PROXY должен быть предварительно включён при помощи установки параметра proxy_protocol в директиве listen.

$proxy_protocol_tlv_имя
TLV, полученный из заголовка протокола PROXY (1.23.2). Имя может быть именем типа TLV или его числовым значением. В последнем случае значение задаётся в шестнадцатеричном виде и должно начинаться с 0x:
$proxy_protocol_tlv_alpn
$proxy_protocol_tlv_0x01
SSL TLV могут также быть доступны как по имени типа TLV, так и по его числовому значению, оба должны начинаться с ssl_:
$proxy_protocol_tlv_ssl_version
$proxy_protocol_tlv_ssl_0x21

Поддерживаются следующие имена типов TLV:

  • alpn (0x01) - протокол более высокого уровня, используемый поверх соединения
  • authority (0x02) - значение имени хоста, передаваемое клиентом
  • unique_id (0x05) - уникальный идентификатор соединения
  • netns (0x30) - имя пространства имён
  • ssl (0x20) - структура SSL TLV в бинарном виде

Поддерживаются следующие имена типов SSL TLV:

  • ssl_version (0x21) - версия SSL, используемая в клиентском соединении
  • ssl_cn (0x22) - Common Name сертификата
  • ssl_cipher (0x23) - имя используемого шифра
  • ssl_sig_alg (0x24) - алгоритм, используемый для подписи сертификата
  • ssl_key_alg (0x25) - алгоритм публичного ключа

Также поддерживается следующее специальное имя типа SSL TLV:

  • ssl_verify - результат проверки клиентского сертификата: 0, если клиент предоставил сертификат и он был успешно верифицирован, либо ненулевое значение

Протокол PROXY должен быть предварительно включён при помощи установки параметра proxy_protocol в директиве listen.

$remote_addr
адрес клиента
$remote_port
порт клиента
$server_addr
адрес сервера, принявшего соединение

Получение значения этой переменной обычно требует одного системного вызова. Чтобы избежать системного вызова, в директивах listen следует указывать адреса и использовать параметр bind.

$server_port
порт сервера, принявшего соединение
$session_time
длительность сессии в секундах с точностью до миллисекунд (1.11.4);
$status
статус сессии (1.11.4), может принимать одно из следующих значений:
200
сессия завершена успешно
400
невозможно разобрать данные, полученные от клиента, например заголовок протокола PROXY
403
доступ запрещён, например при ограничении доступа для определённых адресов клиентов
500
внутренняя ошибка сервера
502
плохой шлюз, например если невозможно выбрать сервер группы или сервер недоступен
503
сервис недоступен, например при ограничении по числу соединений
$time_iso8601
локальное время в формате по стандарту ISO 8601
$time_local
локальное время в Common Log Format