Verifying Stream Module Support
The Nginx Stream module operates at Layer 4 (TCP/UDP), allowing for efficient traffic forwarding and load balancing outside of the standard HTTP context. Before attempting configuration, verify if your Nginx binary includes the module by executing the following command:
nginx -V 2>&1 | grep --color -- '--with-stream'
If the output does not contain --with-stream, the module is not active. For users managing Nginx via source compilation, you must include the flag during the configuration stage:
./configure --prefix=/usr/local/nginx --with-stream
make
sudo make install
For users on modern Linux distributions (like Ubuntu or CentOS), the Stream module is often provided as a dynamic module. You may need to install a package like nginx-mod-stream and ensure the module is loaded at the top of you're nginx.conf file:
load_module /usr/lib/nginx/modules/ngx_stream_module.so;
Core Configuration Structure
The stream block resides at the top level of the Nginx configuration, parallel to the http block. It does not support HTTP-specific directives like location or proxy_set_header because it operates on raw data streams.
# Basic structure in nginx.conf
events {
worker_connections 1024;
}
stream {
# Define logging for TCP/UDP traffic
log_format basic_stream '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log /var/log/nginx/stream_access.log basic_stream;
# Include external configuration files
include /etc/nginx/stream.d/*.conf;
}
http {
# Standard web configuration
}
Implementation Examples
1. Simple TCP Port Forwarding
This configuration maps a local port to a remote database server, such as a MySQL instance. This is useful for creating a gateway into a private network.
# /etc/nginx/stream.d/mysql_proxy.conf
server {
listen 33060;
proxy_connect_timeout 10s;
proxy_timeout 1m;
proxy_pass 10.0.5.15:3306;
}
2. UDP Load Balencing with Persistence
UDP services like DNS require specific handling. The reuseport parameter allows multiple worker processes to listen on the same port, improving performance for high-concurrency UDP traffic.
# /etc/nginx/stream.d/dns_lb.conf
upstream dns_resolvers {
hash $remote_addr consistent;
server 192.168.1.10:53;
server 192.168.1.11:53;
}
server {
listen 53 udp reuseport;
proxy_pass dns_resolvers;
proxy_timeout 10s;
proxy_responses 1;
}
3. High-Availability TCP Cluster
For enterprise applications like Oracle DB or generic TCP socket services, you can define multiple backends with health management.
# /etc/nginx/stream.d/db_cluster.conf
upstream db_backend_pool {
server node_01.internal:1521 max_fails=3 fail_timeout=30s;
server node_02.internal:1521 max_fails=3 fail_timeout=30s;
server backup_node.internal:1521 backup;
}
server {
listen 1521;
proxy_pass db_backend_pool;
proxy_buffer_size 16k;
}
Applying Changes
After modifying the configuration, validate the syntax before reloading the service to ensure no downtime occurs due to configuration errors:
nginx -t
nginx -s reload
Best Practices
- Timeout Tuning: Unlike HTTP, TCP connections can stay open indefinitely. Explicit define
proxy_timeoutandproxy_connect_timeoutto prevent hung sessions from exhausting worker connections. - Security: Since the Stream module exposes raw ports, implement firewall rules (iptables/nftables) to restrict which IP addresses can access these proxy ports.
- Resource Management: Monitor the
worker_connectionslimit in theeventsblock, as each stream session consumes a connection slot.