ngx_stream_module
TCP and UDP proxying with TLS termination and SNI preread
Overview
ngx_stream_module (1.9.0) proxies raw TCP and UDP connections. A stream block holds servers that listen on a port, optionally with the udp parameter (1.9.13) for datagrams, and hand each session to a proxied server or an upstream group, with load balancing, health checking and PROXY protocol support on both sides.
ngx_stream_ssl_module terminates TLS on a listen port with the ssl parameter, and ngx_stream_ssl_preread_module (1.11.5) reads the ClientHello without terminating TLS, exposing $ssl_preread_server_name, $ssl_preread_alpn_protocols (1.13.10) and $ssl_preread_protocol (1.15.2) so a map can route by SNI, ALPN or protocol version. Since 1.25.5 stream servers also support server_name based on SNI. Variables such as $protocol, $status, $session_time and $proxy_protocol_addr have been available since 1.11.2 and 1.11.4.
It is an official nginx module that upstream does not build by default; it needs --with-stream, --with-stream_ssl_module and --with-stream_ssl_preread_module. The n.wtf packages build it as a dynamic module shipped in libnginx-mod-stream, and the base nginx metapackage depends on it, so every n.wtf install has it. Typical uses are forwarding DNS, database or mail ports and sharing port 443 between TLS services by SNI.
Key directives
listenPort the server accepts on; udp (1.9.13) handles datagrams and should be combined with reuseport, ssl enables TLS.proxy_passAddress of the proxied server or upstream group; the value may contain variables so a map can choose the target.ssl_prereadExtracts SNI, ALPN and protocol version from the ClientHello at the preread phase without terminating TLS; default off.$ssl_preread_server_nameServer name requested through SNI, available while ssl_preread is on; the usual key for routing port 443 by host.proxy_protocollisten parameter (1.11.4) that expects a PROXY protocol header; version 2 is supported since 1.13.11.resolverName servers used to resolve upstream names, with valid=time to override the TTL; default port 53.Example
Availability
Ships as a dynamic module in libnginx-mod-stream, installed with nginx, nginx-full and nginx-extras. The package drops a load_module config into /etc/nginx/modules-enabled/, so it loads on start.