Módulo Stream#

El módulo principal de stream implementa la funcionalidad básica para gestionar conexiones TCP y UDP: esto incluye definir bloques de servidor, enrutamiento de tráfico, configuración de proxy, soporte SSL/TLS y gestión de conexiones para servicios de streaming, como bases de datos, DNS y otros protocolos que operan sobre TCP y UDP.

Los demás módulos de esta sección amplían esta funcionalidad, permitiendo configurar y optimizar de forma flexible el servidor stream para diversos escenarios y requisitos.

Al compilar desde el código fuente, este módulo no se construye por defecto; debe habilitarse con la opción de compilación --with-stream build option. En los paquetes e imágenes de nuestros repos, el módulo está incluido en la compilación.

Ejemplo de Configuración#

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;
    }
}

Directivas#

listen#

Sintaxis

listen address[:port] [ssl] [udp] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on | off] [reuseport] [so_keepalive=on|off|[keepidle]:[samp:keepintvl]:[samp:keepcnt]];

Predeterminado

Contexto

server

Define la address y el port del socket en el que el servidor aceptará conexiones. Es posible especificar solo el port, de modo que Angie escuche en todas las interfaces IPv4 (y también IPv6, si está habilitado). La dirección también puede ser un nombre de host, por ejemplo:

listen 127.0.0.1:12345;
listen *:12345;
listen 12345;     # igual que *:12345
listen localhost:12345;

Las direcciones IPv6 se especifican entre corchetes:

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

Los sockets de dominio UNIX se especifican con el prefijo unix::

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

Los rangos de puertos se indican con el primer y último puerto separados por un guion:

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

Nota

Los distintos servidores deben escuchar en pares address:port diferentes.

ssl

permite especificar que todas las conexiones aceptadas en este puerto funcionen en modo SSL.

udp

configura un socket de escucha para trabajar con datagramas. Para gestionar paquetes del mismo origen y puerto en la misma sesión, también debe especificarse el parámetro reuseport.

proxy_protocol

permite especificar que todas las conexiones aceptadas en este puerto utilicen el protocolo PROXY.

La directiva listen puede tener parámetros adicionales específicos de las llamadas al sistema relacionadas con sockets.

setfib=number

establece la tabla de enrutamiento asociada, FIB (la opción SO_SETFIB) para el socket de escucha. Actualmente solo funciona en FreeBSD.

fastopen=number

habilita "TCP Fast Open" para el socket de escucha y limita la longitud máxima de la cola de conexiones que aún no han completado el three-way handshake.

Advertencia

No habilite esta función a menos que el servidor pueda gestionar la recepción del mismo paquete SYN con datos más de una vez.

backlog=number

establece el parámetro backlog en la llamada listen() que limita la longitud máxima de la cola de conexiones pendientes. Por defecto, backlog se establece en -1 en FreeBSD, DragonFly BSD y macOS, y en 511 en otras plataformas.

rcvbuf=size

establece el tamaño del buffer de recepción (opción SO_RCVBUF) para el socket de escucha.

sndbuf=size

establece el tamaño del buffer de envío (opción SO_SNDBUF) para el socket de escucha.

accept_filter=filter

establece el nombre del filtro de aceptación (opción SO_ACCEPTFILTER) para el socket de escucha, que filtra conexiones entrantes antes de pasarlas a accept(). Funciona solo en FreeBSD y NetBSD 5.0+. Valores aceptados: dataready y httpready.

deferred

indica usar un accept() diferido (opción de socket TCP_DEFER_ACCEPT) en Linux.

bind

indica realizar una llamada bind() separada para un par address:port determinado. Si hay varias directivas listen con el mismo port pero distintas direcciones, y una de ellas escucha en todas las direcciones para ese puerto (*:port), Angie hará bind() solo a *:port. En este caso, se ejecutará la llamada getsockname() para determinar la dirección que aceptó la conexión. Si se usan parámetros como setfib, fastopen, backlog, rcvbuf, sndbuf, accept_filter, deferred, ipv6only, reuseport o so_keepalive, siempre se hará una llamada bind() separada para ese par address:port.

ipv6only=on | off

este parámetro determina (mediante la opción de socket IPV6_V6ONLY) si un socket IPv6 que escucha en la dirección comodín [::] aceptará solo conexiones IPv6 o tanto IPv6 como IPv4. Este parámetro está activado por defecto. Solo puede configurarse una vez al inicio.

reuseport

indica crear un socket de escucha individual para cada proceso worker (usando la opción de socket SO_REUSEPORT en Linux 3.9+ y DragonFly BSD, o SO_REUSEPORT_LB en FreeBSD 12+), permitiendo al kernel distribuir las conexiones entrantes entre procesos worker. Actualmente funciona solo en Linux 3.9+, DragonFly BSD y FreeBSD 12+.

Advertencia

El uso inapropiado de esta opción puede tener implicaciones de seguridad.

multipath

habilita la aceptación de conexiones mediante el protocolo Multipath TCP (MPTCP), soportado en el kernel de Linux desde la versión 5.6. Este parámetro es incompatible con udp.

so_keepalive=on | off | [keepidle]:[samp:keepintvl]:[samp:keepcnt]

Configura el comportamiento de "TCP keepalive" para el socket de escucha.

''

si se omite este parámetro, se aplicarán los valores por defecto del sistema operativo para el socket

on

activa la opción SO_KEEPALIVE para el socket

off

desactiva la opción SO_KEEPALIVE para el socket

Algunos sistemas operativos permiten establecer parámetros de TCP keepalive por socket usando las opciones de socket TCP_KEEPIDLE, TCP_KEEPINTVL y TCP_KEEPCNT. En dichos sistemas (actualmente Linux 2.4+, NetBSD 5+ y FreeBSD 9.0-STABLE), pueden configurarse usando los parámetros keepidle, keepintvl y keepcnt. Se pueden omitir uno o dos parámetros, en cuyo caso se aplicarán los valores por defecto del sistema.

Por ejemplo,

so_keepalive=30m::10

establecerá el tiempo de inactividad (TCP_KEEPIDLE) en 30 minutos, mantendrá el intervalo de sondeo (TCP_KEEPINTVL) en el valor por defecto del sistema, y fijará el número de sondeos (TCP_KEEPCNT) en 10.

preread_buffer_size#

Sintaxis

preread_buffer_size size;

Predeterminado

preread_buffer_size 16k;

Contexto

stream, server

Especifica el tamaño del buffer de preread.

preread_timeout#

Sintaxis

preread_timeout timeout;

Predeterminado

preread_timeout 30s;

Contexto

stream, server

Especifica un timeout para la fase de preread.

proxy_protocol_timeout#

Sintaxis

proxy_protocol_timeout timeout;

Predeterminado

proxy_protocol_timeout 30s;

Contexto

stream, server

Especifica un timeout para completar la lectura de la cabecera del protocolo PROXY. Si no se transmite la cabecera completa en este tiempo, la conexión se cierra.

resolver#

Sintaxis

resolver address ... [valid=time] [ipv4=on | off] [ipv6=on | off] [status_zone=zone];

Predeterminado

Contexto

stream, server, upstream

Configura los servidores de nombres utilizados para resolver direcciones de upstream servers, por ejemplo:

resolver 127.0.0.53 [::1]:5353;

La dirección puede especificarse como un nombre de dominio o una dirección IP, con un puerto opcional. Si no se especifica puerto, se usa el 53. Los servidores de nombres se consultan en orden round-robin.

Por defecto, Angie almacena en caché las respuestas usando el valor TTL de la respuesta. El parámetro opcional valid permite sobrescribirlo:

valid

parámetro opcional que permite sobrescribir la validez de la entrada en caché

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

Por defecto, Angie buscará direcciones tanto IPv4 como IPv6.

ipv4=off

desactiva la búsqueda de direcciones IPv4

ipv6=off

desactiva la búsqueda de direcciones IPv6

status_zone

parámetro opcional; habilita la recopilación de métricas de solicitudes y respuestas de los servidores DNS (/status/resolvers/<zone>) en la zona especificada

Truco

Para prevenir ataques de DNS spoofing, se recomienda usar servidores DNS en una red local de confianza adecuadamente asegurada.

Truco

Cuando se ejecute en Docker, use la dirección del servidor DNS interno correspondiente como 127.0.0.11.

resolver_timeout#

Sintaxis

resolver_timeout time;

Predeterminado

resolver_timeout 30s;

Contexto

stream, server, upstream

Define un timeout para la resolución de nombres, por ejemplo:

resolver_timeout 5s;

server#

Sintaxis

server { ... }

Predeterminado

Contexto

stream

Define la configuración de un servidor.

server_name#

Sintaxis

server_name name ...;

Predeterminado

server_name "";

Contexto

server

Define los nombres de un servidor virtual.

Advertencia

En el módulo stream, la directiva server_name se basa en la Server Name Indication (SNI) y solo funciona con conexiones TLS. Para usarla, debe configurar la terminación TLS o habilitar TLS preread en el bloque server correspondiente.

Ejemplo de configuración:

server {
    listen 443 ssl;
    server_name example.com www.example.com;
    ssl_certificate /etc/angie/cert.pem;
    ssl_certificate_key /etc/angie/key.pem;
}

El primer nombre se convierte en el nombre principal del servidor.

Los nombres de servidor pueden incluir un asterisco (*) para sustituir la primera o última parte de un nombre:

server {
    server_name example.com *.example.com www.example.*;
}

Estos nombres se denominan wildcard names.

También se pueden usar expresiones regulares en nombres de servidor anteponiendo el nombre con una tilde (~):

server {
    server_name www.example.com ~^www\d+\.example\.com$;
}

Las expresiones regulares pueden incluir captures que se pueden usar en otras directivas:

server {
    server_name ~^(www\.)?(.+)$;

    proxy_pass www.$2:12345;
}

Las named captures en expresiones regulares crean variables que pueden usarse en otras directivas:

server {
    server_name ~^(www\.)?(?<domain>.+)$;

    proxy_pass www.$domain:12345;
}

Si el parámetro de la directiva se establece en $hostname, se insertará el nombre de host de la máquina.

Al buscar un servidor virtual por nombre, si el nombre coincide con más de una de las variantes especificadas (p. ej., tanto un wildcard name como una expresión regular), se elegirá la primera variante coincidente en el siguiente orden de prioridad:

  • El nombre exacto

  • El nombre comodín más largo que empieza con un asterisco, p. ej. *.example.com

  • El nombre comodín más largo que termina con un asterisco, p. ej. mail.*

  • La primera expresión regular coincidente (en orden de aparición en el archivo de configuración)

server_names_hash_bucket_size#

Sintaxis

server_names_hash_bucket_size size;

Predeterminado

server_names_hash_bucket_size 32|64|128;

Contexto

stream

Define el tamaño del bucket para las tablas hash de nombres de servidor. El valor por defecto depende del tamaño de la línea de caché del procesador.

server_names_hash_max_size#

Sintaxis

server_names_hash_max_size size;

Predeterminado

server_names_hash_max_size 512;

Contexto

stream

Define el tamaño máximo de las tablas hash de nombres de servidor.

status_zone#

Sintaxis

status_zone zone | key zone=zone[:count];

Predeterminado

Contexto

server

Asigna una zona de memoria compartida para recopilar métricas de /status/stream/server_zones/<zone>.

Varios contextos server pueden compartir la misma zona para la recopilación de datos.

La sintaxis de valor único zone agrega todas las métricas del contexto actual en una sola zona de memoria compartida:

server {

    listen 80;
    server_name *.example.com;

    status_zone single;
    # ...
}

La sintaxis alternativa permite especificar los siguientes parámetros:

key

Una cadena con variables, cuyo valor determina la agrupación de conexiones en la zona. Todas las conexiones que produzcan valores idénticos tras la sustitución se agrupan juntas. Si la sustitución produce un valor vacío, las métricas no se actualizan.

zone

El nombre de la zona de memoria compartida.

count (opcional)

El número máximo de grupos separados para recopilar métricas. Si los nuevos valores de key superan este límite, se agrupan bajo zone.

El valor por defecto es 1.

En el siguiente ejemplo, todas las conexiones con el mismo valor $server_addr se agrupan en host_zone. Las métricas se recopilan por separado para cada $server_addr único hasta que el número de grupos de métricas alcanza 10. Después de eso, cualquier nuevo valor de $server_addr se añadirá al grupo 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;
    }
}

Las métricas resultantes se dividen entre servidores individuales en la salida de la API.

stream#

Sintaxis

stream { ... }

Predeterminado

Contexto

main

Proporciona el contexto de archivo de configuración en el que se especifican las directivas del servidor stream.

tcp_nodelay#

Sintaxis

tcp_nodelay on | off;

Predeterminado

tcp_nodelay on;

Contexto

stream, server

Habilita o deshabilita el uso de la opción TCP_NODELAY. La opción se habilita tanto para las conexiones de cliente como para las conexiones a servidores proxied.

variables_hash_bucket_size#

Sintaxis

variables_hash_bucket_size size;

Predeterminado

variables_hash_bucket_size 64;

Contexto

stream

Define el tamaño de bucket para la tabla hash de variables. Los detalles de la configuración de tablas hash se proporcionan en un documento separado.

variables_hash_max_size#

Sintaxis

variables_hash_max_size size;

Predeterminado

variables_hash_max_size 1024;

Contexto

stream

Define el tamaño máximo de la tabla hash de variables. Los detalles de la configuración de tablas hash se proporcionan en un documento separado.

Variables integradas#

El módulo core stream admite las siguientes variables integradas:

$angie_version#

Versión de Angie

$binary_remote_addr#

Dirección del cliente en forma binaria, la longitud del valor es siempre de 4 bytes para direcciones IPv4 o 16 bytes para direcciones IPv6

$bytes_received#

Número de bytes recibidos desde un cliente

$bytes_sent#

Número de bytes enviados a un cliente

$connection#

Número de serie de la conexión

$hostname#

Nombre del host

$msec#

Hora actual en segundos con resolución en milisegundos

$pid#

PID del proceso worker

$protocol#

Protocolo utilizado para comunicarse con el cliente: TCP o UDP

$proxy_protocol_addr#

Dirección del cliente desde la cabecera PROXY protocol. El PROXY protocol debe estar habilitado previamente configurando el parámetro proxy_protocol en la directiva listen.

$proxy_protocol_port#

Puerto del cliente desde la cabecera PROXY protocol. El PROXY protocol debe estar habilitado previamente configurando el parámetro proxy_protocol en la directiva listen.

$proxy_protocol_server_addr#

Dirección del servidor desde la cabecera PROXY protocol. El PROXY protocol debe estar habilitado previamente configurando el parámetro proxy_protocol en la directiva listen.

$proxy_protocol_server_port#

Puerto del servidor desde la cabecera PROXY protocol. El PROXY protocol debe estar habilitado previamente configurando el parámetro proxy_protocol en la directiva listen.

$proxy_protocol_tlv_<name>#

TLV obtenido de la cabecera PROXY protocol. El name puede ser un nombre de tipo TLV o su valor numérico. En este último caso, el valor se especifica en hexadecimal y debe comenzar con 0x:

$proxy_protocol_tlv_alpn
$proxy_protocol_tlv_0x01

Los TLVs de SSL también pueden accederse tanto por nombre de tipo TLV como por valor numérico, ambos deben comenzar con ssl_:

$proxy_protocol_tlv_ssl_version
$proxy_protocol_tlv_ssl_0x21

Los siguientes nombres de tipo TLV son compatibles:

  • alpn (0x01) - protocolo de capa superior usado sobre la conexión

  • authority (0x02) - nombre de host proporcionado por el cliente

  • unique_id (0x05) - identificador único de conexión

  • netns (0x30) - nombre del namespace

  • ssl (0x20) - estructura TLV SSL en formato binario

Los siguientes nombres de tipo TLV SSL son compatibles:

  • ssl_version (0x21) - versión de SSL usada en la conexión del cliente

  • ssl_cn (0x22) - Common Name del certificado

  • ssl_cipher (0x23) - nombre del cifrado utilizado

  • ssl_sig_alg (0x24) - algoritmo usado para firmar el certificado

  • ssl_key_alg (0x25) - algoritmo de clave pública

También se admite el siguiente nombre de tipo TLV SSL especial:

  • ssl_verify - resultado de la verificación del certificado del cliente: 0 si el cliente presentó un certificado y fue verificado con éxito, o un valor distinto de cero en caso contrario

El PROXY protocol debe estar habilitado previamente configurando el parámetro proxy_protocol en la directiva listen.

$remote_addr#

Dirección del cliente

$remote_port#

Puerto del cliente

$server_addr#

Dirección del servidor que aceptó la conexión. Calcular el valor de esta variable normalmente requiere una llamada al sistema. Para evitar esta llamada, las directivas listen deben especificar direcciones y usar el parámetro bind.

$server_port#

Puerto del servidor que aceptó la conexión

$session_time#

Duración de la sesión en segundos con resolución en milisegundos

$status#

Estado de la sesión, puede ser uno de los siguientes:

200

sesión completada con éxito

400

no se pudieron analizar los datos del cliente, por ejemplo, la cabecera PROXY protocol

403

acceso prohibido, por ejemplo, cuando el acceso está limitado para ciertas direcciones de cliente

500

error interno del servidor

502

bad gateway, por ejemplo, si no se pudo seleccionar o alcanzar un servidor upstream

503

servicio no disponible, por ejemplo, cuando el acceso está limitado por el número de conexiones

$time_iso8601#

Hora local en formato estándar ISO 8601

$time_local#

Hora local en el formato Common Log Format