Nginx Stream模块专用于TCP/UDP四层透明转发,不解析应用层协议;需编译含--with-stream,配置与http同级,通过proxy_protocol透传客户端真实IP,并依赖上游服务协同解析,配合proxy_timeout等指令管控连接生命周期。

Nginx 的 stream 模块专用于四层(TCP/UDP)流量转发,不解析应用层协议,天然支持透明转发。关键在于保持客户端原始 IP、避免代理干扰,并正确处理连接生命周期。
启用 stream 模块并配置基础转发
确保编译 Nginx 时已启用 --with-stream(官方预编译包通常默认包含)。在主配置文件中通过 stream { } 块定义转发规则:
- 将
stream块置于http块之外(同级),不可嵌套 - 每个
upstream定义后端服务器列表,支持权重、健康检查(需配合health_check指令) -
server块监听端口,用proxy_pass指向 upstream,不支持 rewrite 或 header 修改
示例:
stream {upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
server {
listen 8000;
proxy_pass backend;
proxy_timeout 1s;
}
}
保留客户端真实 IP(透明代理核心)
TCP 层无法像 HTTP 那样加 X-Forwarded-For 头,要透传源 IP,必须让后端服务直接看到客户端地址。这需要两步配合:
- Nginx 侧:启用
proxy_protocol(若后端支持 PROXY 协议),或确保 Nginx 与后端在同一局域网且使用transparent模式(需 root 权限和 iptables 配合) - 后端侧:配置为接收 PROXY 协议头(如 HAProxy、Nginx stream 自身),或绑定到 VIP 并开启
net.ipv4.ip_forward=1+iptables DNAT实现路由级透传
常见组合是 Nginx(proxy_protocol on)→ 后端 Nginx stream(set_real_ip_from + real_ip_header proxy_protocol)。
控制连接行为与超时策略
stream 模块无请求概念,只有连接生命周期,超时设置直接影响长连接稳定性:
-
proxy_timeout:空闲连接最大保持时间(默认 10 分钟),设太短会频繁断连,太长则占用资源 -
proxy_responses:限制转发响应数(适用于有明确应答的协议,如 Redis、MySQL) -
proxy_buffer_size:缓冲区大小,默认 8k,对高吞吐场景可适当调大 - 务必关闭
proxy_bind(除非需指定出口 IP),避免绑定导致 NAT 地址丢失
验证与调试要点
透明转发是否生效不能只看日志,需逐层确认:
- 用
ss -tuln | grep :8000确认 Nginx 正确监听,且状态为LISTEN - 抓包(
tcpdump -i any port 8000)观察三次握手源 IP 是否为真实客户端 - 检查后端服务日志或 netstat 连接来源,确认 peer 地址未被替换成 Nginx 本机 IP
- 若启用 PROXY 协议,用
echo -ne "PROXY TCP4 192.168.1.100 192.168.1.10 12345 80\r\n" | nc 127.0.0.1 8000手动测试协议解析


















