Модуль stream_core#

При сборке из исходного кода модуль необходимо включить с помощью параметра сборки ‑‑with‑stream. В пакетах из наших репозиториев модуль включен в сборку.

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

worker_processes auto;

error_log /var/log/angie/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#

Синтаксис:

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/angie.sock;

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

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

Важно

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

ssl

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

udp

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

proxy_protocol

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

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

fastopen=число

включает «TCP Fast Open» для слушающего сокета и ограничивает максимальную длину очереди соединений, которые еще не завершили процесс трехстороннего рукопожатия.

Осторожно

Не включайте «TCP Fast Open», не убедившись, что сервер может адекватно обрабатывать многократное получение одного и того же SYN-пакета с данными.

backlog=число

задает параметр backlog в вызове listen(), который ограничивает максимальный размер очереди ожидающих приема соединений. По умолчанию backlog устанавливается равным -1 для FreeBSD, DragonFly BSD и macOS, и 511 для других платформ.

rcvbuf=размер

задает размер буфера приема (параметр SO_RCVBUF) для слушающего сокета.

sndbuf=размер

задает размер буфера передачи (параметр SO_SNDBUF) для слушающего сокета.

bind

указывает, что для данного слушающего сокета нужно делать bind() отдельно. Это нужно потому, что если описаны несколько директив listen с одинаковым портом, но разными адресами, и одна из директив listen слушает на всех адресах для данного порта (*:порт), то Angie PRO сделает bind() только на *:порт. Необходимо заметить, что в этом случае для определения адреса, на который пришло соединение, делается системный вызов getsockname(). Если же используются параметры backlog, rcvbuf, sndbuf, ipv6only, reuseport или so_keepalive, то для данной пары адрес:порт всегда делается отдельный вызов bind().

ipv6only=on | off

определяет (через параметр сокета IPV6_V6ONLY), будет ли слушающий на wildcard-адресе [::] IPv6-сокет принимать только IPv6-соединения, или же одновременно IPv6- и IPv4-соединения.
По умолчанию параметр включен. Установить его можно только один раз на старте.

reuseport

указывает, что нужно создавать отдельный слушающий сокет для каждого рабочего процесса (через параметр сокета SO_REUSEPORT для Linux 3.9+ и DragonFly BSD или SO_REUSEPORT_LB для FreeBSD 12+), позволяя ядру распределять входящие соединения между рабочими процессами. В настоящий момент это работает только на Linux 3.9+, DragonFly BSD и FreeBSD 12+.

Осторожно

Ненадлежащее использование параметра reuseport может быть небезопасно.

so_keepalive=on | off | [keepidle]:[keepintvl]:[keepcnt]
конфигурирует для слушающего сокета поведение «TCP keepalive».

''

если параметр опущен, для сокета будут действовать настройки операционной системы

on

для сокета включается параметр SO_KEEPALIVE

off

для сокета параметр SO_KEEPALIVE выключается

Некоторые операционные системы поддерживают настройку параметров «TCP keepalive» на уровне сокета посредством параметров TCP_KEEPIDLE, TCP_KEEPINTVL и TCP_KEEPCNT. На таких системах их можно сконфигурировать с помощью параметров keepidle, keepintvl и keepcnt. Один или два параметра могут быть опущены, в таком случае для соответствующего параметра сокета будут действовать стандартные системные настройки.

Например,

so_keepalive=30m::10

установит таймаут бездействия (TCP_KEEPIDLE) в 30 минут, для интервала проб (TCP_KEEPINTVL) будет действовать стандартная системная настройка, а счетчик проб (TCP_KEEPCNT) будет равен 10.

preread_buffer_size#

Синтаксис:

preread_buffer_size размер;

Умолчание:

preread_buffer_size 16k;

Контекст:

stream, server

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

preread_timeout#

Синтаксис:

preread_timeout время;

Умолчание:

preread_timeout 30s;

Контекст:

stream, server

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

proxy_protocol_timeout#

Синтаксис:

proxy_protocol_timeout время;

Умолчание:

proxy_protocol_timeout 30s;

Контекст:

stream, server

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

resolver#

Синтаксис:

resolver адрес … [valid=время] [ipv4=on|off] [ipv6=on|off] [status_zone=зона];

Умолчание:

Контекст:

stream, server, upstream

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

resolver 127.0.0.53 [::1]:5353;

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

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

valid

необязательный параметр, позволяет переопределить срок кэширования ответа

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

По умолчанию Angie PRO будет искать как IPv4-, так и IPv6-адреса при преобразовании имен в адреса.

ipv4=off

запрещает поиск IPv4-адресов

ipv6=off

запрещает поиск IPv6-адресов

status_zone

необязательный параметр, включает сбор информации о запросах и ответах сервера DNS в указанной зоне

Совет

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

resolver_timeout#

Синтаксис:

resolver_timeout время;

Умолчание:

resolver_timeout 30s;

Контекст:

stream, server, upstream

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

resolver_timeout 5s;

server#

Синтаксис:

server { … }

Умолчание:

Контекст:

stream

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

status_zone#

Added in version 1.0.0.

Синтаксис:

status_zone зона;

Умолчание:

Конеткст:

server

Директива включает выделение зоны в разделяемой памяти для сбора метрик. Несколько server могут разделять одну зону для сбора данных.

stream#

Синтаксис:

stream { … }

Умолчание:

Контекст:

main

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

tcp_nodelay#

Синтаксис:

tcp_nodelay on | off;

Умолчание:

tcp_nodelay on;

Контекст:

stream, server

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

variables_hash_bucket_size#

Синтаксис:

variables_hash_bucket_size размер;

Умолчание:

variables_hash_bucket_size 64;

Контекст:

stream

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

variables_hash_max_size#

Синтаксис:

variables_hash_max_size размер;

Умолчание:

variables_hash_max_size 1024;

Контекст:

stream

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

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

Модуль stream core поддерживает встроенные переменные:

$angie_version#

версия Angie PRO

$binary_remote_addr#

адрес клиента в бинарном виде, длина значения всегда 4 байта для IPv4-адресов или 16 байт для IPv6-адресов

$bytes_received#

число байт, полученных от клиента

$bytes_sent#

число байт, переданных клиенту

$connection#

порядковый номер соединения

$hostname#

имя хоста

$msec#

текущее время в секундах с точностью до миллисекунд

$pid#

номер (PID) рабочего процесса

$protocol#

протокол, используемый для работы с клиентом: TCP или UDP

$proxy_protocol_addr#

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

$proxy_protocol_port#

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

$proxy_protocol_server_addr#

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

$proxy_protocol_server_port#

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

$proxy_protocol_tlv_ имя#

TLV, полученный из заголовка протокола PROXY. Имя может быть именем типа 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#

длительность сессии в секундах с точностью до миллисекунд

$status#

статус сессии, может принимать одно из следующих значений:

200

сессия завершена успешно

400

невозможно разобрать данные, полученные от клиента, например заголовок протокола PROXY

403

доступ запрещен, например при ограничении доступа для определенных адресов клиентов

500

внутренняя ошибка сервера

502

плохой шлюз, например если невозможно выбрать сервер группы или сервер недоступен

503

сервис недоступен, например при ограничении по числу соединений

$time_iso8601#

локальное время в формате по стандарту ISO 8601

$time_local#

локальное время в Common Log Format