Потоковый модуль#
Базовый потоковый модуль реализует основную функциональность для обработки TCP- и UDP-соединений: это определение серверных блоков, маршрутизация трафика, настройка проксирования, поддержка SSL/TLS и управление подключениями для потоковых сервисов, таких как базы данных, DNS и другие протоколы, работающие на основе TCP и UDP.
Остальные модули этого раздела расширяют эту функциональность, позволяя гибко настраивать и оптимизировать работу потокового сервера под различные сценарии и требования.
При сборке из исходного кода модуль не собирается по умолчанию; его необходимо
включить с помощью параметра сборки
По умолчанию — server Задает адрес и порт для сокета, на котором сервер будет принимать соединения. Можно указать только порт. Кроме того, адрес может быть именем хоста, например: IPv6-адреса задаются в квадратных скобках: UNIX-сокеты задаются префиксом Диапазоны портов задаются при помощи указания первого и последнего порта через дефис: Важно Разные серверы должны слушать на разных парах адрес:порт. указывает на то, что все соединения, принимаемые на данном слушающем сокете, должны работать в режиме SSL. конфигурирует слушающий сокет для работы с датаграммами. Для обработки пакетов с одного адреса и порта в рамках одной сессии необходимо также указывать параметр reuseport. указывает на то, что все соединения, принимаемые на данном порту, должны использовать протокол PROXY. В директиве listen можно также указать несколько дополнительных параметров, специфичных для связанных с сокетами системных вызовов. устанавливает связанную таблицу маршрутизации, FIB (параметр
включает "TCP Fast Open" для слушающего сокета и ограничивает максимальную длину очереди соединений, которые еще не завершили процесс трехстороннего рукопожатия. Осторожно Не включайте "TCP Fast Open", не убедившись, что сервер может адекватно обрабатывать многократное получение одного и того же SYN-пакета с данными. задает параметр backlog в вызове listen(), который ограничивает максимальный размер очереди ожидающих приема соединений. По умолчанию backlog устанавливается равным -1 для FreeBSD, DragonFly BSD и macOS, и 511 для других платформ. задает размер буфера приема (параметр SO_RCVBUF) для слушающего сокета. задает размер буфера передачи (параметр SO_SNDBUF) для слушающего сокета. задает имя принимающего фильтра (параметр указывает использовать отложенный указывает, что для данного слушающего сокета нужно делать bind()
отдельно. Это нужно потому, что если описаны несколько директив listen
с одинаковым портом, но разными адресами, и одна из директив listen
слушает на всех адресах для данного порта (*:порт), то Angie
сделает bind() только на *:порт. Необходимо заметить, что в этом
случае для определения адреса, на который пришло соединение, делается
системный вызов getsockname(). Если же используются параметры setfib,
fastopen, backlog, rcvbuf, sndbuf, accept_filter, deferred,
ipv6only, reuseport или so_keepalive, то для данной пары
адрес:порт всегда делается отдельный вызов bind(). определяет (через параметр сокета IPV6_V6ONLY), будет ли слушающий на wildcard-адресе [::] IPv6-сокет принимать только IPv6-соединения, или же одновременно IPv6- и IPv4-соединения. указывает, что нужно создавать отдельный слушающий сокет для каждого рабочего процесса (через параметр сокета SO_REUSEPORT для Linux 3.9+ и DragonFly BSD или SO_REUSEPORT_LB для FreeBSD 12+), позволяя ядру распределять входящие соединения между рабочими процессами. В настоящий момент это работает только на Linux 3.9+, DragonFly BSD и FreeBSD 12+. Осторожно Ненадлежащее использование параметра reuseport может быть небезопасно. если параметр опущен, для сокета будут действовать настройки операционной системы для сокета включается параметр SO_KEEPALIVE для сокета параметр SO_KEEPALIVE выключается Некоторые операционные системы поддерживают настройку параметров "TCP keepalive" на уровне сокета посредством параметров TCP_KEEPIDLE, TCP_KEEPINTVL и TCP_KEEPCNT. На таких системах их можно сконфигурировать с помощью параметров keepidle, keepintvl и keepcnt. Один или два параметра могут быть опущены, в таком случае для соответствующего параметра сокета будут действовать стандартные системные настройки. Например, установит таймаут бездействия (TCP_KEEPIDLE) в 30 минут, для интервала проб (TCP_KEEPINTVL) будет действовать стандартная системная настройка, а счетчик проб (TCP_KEEPCNT) будет равен 10. Задает размер буфера предварительного чтения. Задает время фазы предварительного чтения. Задает время для завершения операции чтения заголовка протокола PROXY. Если по истечении этого времени заголовок полностью не получен, соединение закрывается. По умолчанию — stream, server, upstream Задает серверы DNS, используемые для преобразования имен вышестоящих серверов в адреса, например: Адрес может быть указан в виде доменного имени или IP-адреса, и необязательного порта. Если порт не указан, используется порт 53. Серверы DNS опрашиваются циклически. По умолчанию Angie кэширует ответы, используя значение TTL из ответа. Необязательный параметр valid позволяет это переопределить: необязательный параметр, позволяет переопределить срок кэширования ответа По умолчанию Angie будет искать как IPv4-, так и IPv6-адреса при преобразовании имен в адреса. запрещает поиск IPv4-адресов запрещает поиск IPv6-адресов необязательный параметр;
включает сбор метрик запросов и ответов DNS-сервера
(/status/resolvers/<зона>)
в указанной зоне Совет Для предотвращения DNS-спуфинга рекомендуется использовать DNS-серверы в защищенной доверенной локальной сети. Подсказка При запуске в Docker используйте соответствующий внутренний адрес DNS-сервера, например Задает таймаут для преобразования имени в адрес, например: Задает конфигурацию для сервера. Задает имена виртуального сервера, например: Первое имя становится основным именем сервера. Имена серверов могут включать звездочку ( Такие имена называются шаблонными именами. Первые два примера, приведенные выше, можно объединить в один: Также можно использовать регулярные выражения в именах серверов, предваряя имя
тильдой ( Регулярные выражения могут включать захваты, которые можно использовать в других
директивах: Именованные захваты в регулярных выражениях создают переменные, которые можно
использовать в других директивах: Если параметр директивы установлен на При поиске виртуального сервера по имени, если имя совпадает с более чем одним
из указанных вариантов (например, совпадают и шаблонное имя, и регулярное
выражение), будет выбрано первое совпавшее имя в следующем порядке приоритета: Точное имя Самое длинное шаблонное имя, начинающееся с звездочки, например,
Самое длинное шаблонное имя, заканчивающееся звездочкой, например,
Первое совпавшее регулярное выражение (в порядке появления в конфигурационном
файле) Внимание Для TLS-соединений используйте модуль SSL Preread. По умолчанию stream Задает размер корзины для хэш-таблиц имен серверов. Значение по умолчанию
зависит от размера кэш-линии процессора. По умолчанию stream Задает максимальный размер хэш-таблиц имен серверов. Выделяет зону разделяемой памяти для сбора метрик
/status/stream/server_zones/<зона>. Несколько контекстов Синтаксис с одним значением зоны
объединяет все метрики для текущего контекста в одну зону разделяемой памяти: Альтернативный синтаксис позволяет задавать следующие параметры: значение Строка с переменными, значение которой определяет группировку подключений
в зоне. Все подключения, дающие одинаковые значения после подстановки,
объединяются в одну группу. Если подстановка возвращает пустое значение,
метрики не обновляются. зона Имя зоны разделяемой памяти. число (необязательный) Максимальное количество отдельных групп для сбора метрик.
Если новые значения ключа превышают этот лимит, они объединяются в группу zone. Значение по умолчанию — 1. В следующем примере все соединения с одинаковым значением Результирующие метрики разделяются по отдельным серверам в выводе API. Предоставляет контекст конфигурационного файла, в котором указываются директивы stream-сервера. Разрешает или запрещает использование параметра TCP_NODELAY. Параметр включается как для клиентских соединений, так и для соединений с проксируемыми серверами. Задает размер корзины в хэш-таблице переменных. Подробнее настройка хэш-таблиц обсуждается отдельно. Задает максимальный размер хэш-таблиц переменных. Подробнее настройка хэш-таблиц обсуждается отдельно. Модуль stream core поддерживает встроенные переменные: версия Angie адрес клиента в бинарном виде, длина значения всегда 4 байта для IPv4-адресов или 16 байт для IPv6-адресов число байт, полученных от клиента число байт, переданных клиенту порядковый номер соединения имя хоста текущее время в секундах с точностью до миллисекунд номер (PID) рабочего процесса протокол, используемый для работы с клиентом: TCP или UDP адрес клиента, полученный из заголовка протокола PROXY порт клиента, полученный из заголовка протокола PROXY адрес сервера, полученный из заголовка протокола PROXY порт сервера, полученный из заголовка протокола PROXY TLV, полученный из заголовка протокола PROXY. Имя может быть именем типа TLV или его числовым значением. В последнем случае значение задается в шестнадцатеричном виде и должно начинаться с 0x: SSL TLV могут также быть доступны как по имени типа TLV, так и по его числовому значению, оба должны начинаться с Поддерживаются следующие имена типов 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. адрес клиента порт клиента адрес сервера, принявшего соединение порт сервера, принявшего соединение длительность сессии в секундах с точностью до миллисекунд статус сессии, может принимать одно из следующих значений: сессия завершена успешно невозможно разобрать данные, полученные от клиента, например заголовок протокола PROXY доступ запрещен, например при ограничении доступа для определенных адресов клиентов внутренняя ошибка сервера плохой шлюз, например если невозможно выбрать сервер группы или сервер недоступен сервис недоступен, например при ограничении по числу соединений локальное время в формате по стандарту ISO 8601 локальное время в Common Log Format‑‑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
] [setfib=
число] [fastopen=
число] [backlog=
число] [rcvbuf=
размер] [sndbuf=
размер] [accept_filter=
фильтр] [deferred
] [bind
] [ipv6only=
on
| off
] [reuseport
] [so_keepalive=
on|off|[keepidle]:[keepintvl]:[keepcnt]];listen 127.0.0.1:12345;
listen *:12345;
listen 12345; # то же, что и *:12345
listen localhost:12345;
listen [::1]:12345;
listen [::]:12345;
unix:
listen unix:/var/run/angie.sock;
listen 127.0.0.1:12345-12399;
listen 12345-12399;
ssl
udp
proxy_protocol
setfib=
числоSO_SETFIB
) для слушающего сокета. Пока это работает только на
FreeBSD.fastopen=
числоbacklog=
числоrcvbuf=
размерsndbuf=
размерaccept_filter=
фильтрSO_ACCEPTFILTER
) для
слушающего сокета, который фильтрует входящие соединения перед их
передачей в accept()
. Работает только на FreeBSD и NetBSD 5.0+.
Допустимые значения: dataready
и httpready
.deferred
accept()
(параметр
TCP_DEFER_ACCEPT
) на Linux.bind
ipv6only=on
| off
По умолчанию параметр включен. Установить его можно только один раз на старте.reuseport
so_keepalive=on
| off
| [keepidle]:[keepintvl]:[keepcnt]
конфигурирует для слушающего сокета поведение "TCP keepalive".''
on
off
so_keepalive=30m::10
preread_buffer_size#
preread_timeout#
proxy_protocol_timeout#
resolver#
resolver
адрес ... [valid=
время] [ipv4=
on
| off
] [ipv6=
on
| off
] [status_zone=
зона];resolver 127.0.0.53 [::1]:5353;
valid
resolver 127.0.0.53 [::1]:5353 valid=30s;
ipv4=off
ipv6=off
status_zone
127.0.0.11
.resolver_timeout#
resolver_timeout 5s;
server#
server_name#
server {
server_name example.com www.example.com;
}
*
), заменяющую первую или
последнюю часть имени:server {
server_name example.com *.example.com www.example.*;
}
server {
server_name .example.com;
}
~
):server {
server_name www.example.com ~^www\d+\.example\.com$;
}
server {
server_name ~^(www\.)?(.+)$;
proxy_pass www.$2:12345;
}
server {
server_name ~^(www\.)?(?<domain>.+)$;
proxy_pass www.$domain:12345;
}
$hostname
, будет вставлено имя
хоста машины.*.example.com
mail.*
server_names_hash_bucket_size#
server_names_hash_bucket_size
размер;server_names_hash_bucket_size 32|64|128;
server_names_hash_max_size#
server_names_hash_max_size
размер;server_names_hash_max_size 512;
status_zone#
server
могут совместно использовать одну и ту же зону для сбора данных.server {
listen 80;
server_name *.example.com;
status_zone single;
# ...
}
$server_addr
группируются в host_zone
. Метрики собираются отдельно для каждого
уникального значения $server_addr
до тех пор, пока количество групп
метрик не достигнет 10. После этого любые новые значения $server_addr
будут добавляться в группу server_zone
:stream {
upstream backend {
server 192.168.0.1:3306;
server 192.168.0.2:3306;
# ...
}
server {
listen 3306;
proxy_pass backend;
status_zone $server_addr zone=server_zone:10;
}
}
stream#
tcp_nodelay#
variables_hash_bucket_size#
variables_hash_max_size#
Встроенные переменные#
$angie_version
#$binary_remote_addr
#$bytes_received
#$bytes_sent
#$connection
#$hostname
#$msec
#$pid
#$protocol
#$proxy_protocol_addr
#
Протокол PROXY должен быть предварительно включен при помощи установки параметра proxy_protocol в директиве listen.$proxy_protocol_port
#
Протокол PROXY должен быть предварительно включен при помощи установки параметра proxy_protocol в директиве listen.$proxy_protocol_server_addr
#
Протокол PROXY должен быть предварительно включен при помощи установки параметра proxy_protocol в директиве listen.$proxy_protocol_server_port
#
Протокол PROXY должен быть предварительно включен при помощи установки параметра proxy_protocol в директиве listen.$proxy_protocol_tlv_<имя>
#$proxy_protocol_tlv_alpn
$proxy_protocol_tlv_0x01
ssl_
:$proxy_protocol_tlv_ssl_version
$proxy_protocol_tlv_ssl_0x21
$remote_addr
#$remote_port
#$server_addr
#
Получение значения этой переменной обычно требует одного системного вызова. Чтобы избежать системного вызова, в директивах listen следует указывать адреса и использовать параметр bind
.$server_port
#$session_time
#$status
#200
400
403
500
502
503
$time_iso8601
#$time_local
#