Nginx自1.9.0起通过stream模块支持TCP/UDP四层转发,需启用模块、配置stream块(与http平级)、监听端口并proxy_pass转发,不支持端口级虚拟主机概念,仅能通过多端口实现分流。

Nginx 自 1.9.0 版本起通过 stream 模块支持 TCP/UDP 四层转发,但需注意:它不支持基于端口的“虚拟主机”概念(如 HTTP 的 server_name),而是通过监听不同端口 + 配置后端 upstream 实现流量分发。所谓“基于端口的虚拟主机”,实际指:同一台 Nginx 服务器监听多个端口,每个端口对应独立的 TCP 或 UDP 转发规则。
确认 stream 模块已启用
Nginx 默认编译可能未包含 stream 模块。执行以下命令验证:
nginx -V 2>&1 | grep -o with-stream
若无输出,需重新编译 Nginx 并添加 --with-stream 参数;若使用包管理器安装(如 Ubuntu 的 apt),可安装 nginx-full(含 stream)或启用模块:
- Ubuntu/Debian:
sudo apt install nginx-full - CentOS/RHEL:
sudo yum install nginx-mod-stream(需启用 epel 源) - 启用模块(部分系统需在
/etc/nginx/nginx.conf中取消注释):load_module modules/ngx_http_stream_module.so;
配置基于端口的 TCP/UDP 转发
stream 配置与 http 块平级,不能嵌套在 http 内。典型结构如下:
stream {
# TCP 转发:监听 8080 端口,转发到后端 Web 服务
server {
listen 8080;
proxy_pass 192.168.1.10:80;
proxy_timeout 1s;
proxy_responses 1;
}
<pre class="brush:php;toolbar:false;"># UDP 转发:监听 53 端口,转发 DNS 查询
server {
listen 53 udp;
proxy_pass dns_backend;
proxy_timeout 1s;
}
# 定义 upstream(可选,用于负载均衡或健康检查)
upstream dns_backend {
server 192.168.1.20:53;
server 192.168.1.21:53;
}
}
关键点说明:
-
listen必须指定端口号,UDP 需显式加udp标识 -
proxy_pass后可直接写IP:PORT,也可引用 named upstream - UDP 不支持 keepalive 或复杂负载策略,
proxy_responses控制响应数(默认 1),避免重复应答 -
proxy_timeout是连接空闲超时(非请求处理时间),建议设为较小值(如 1–3 秒)防止资源堆积
常见问题与注意事项
实际部署中易忽略以下细节:
- 防火墙放行端口:确保系统防火墙(如 ufw、firewalld)允许配置的监听端口入站
-
SELinux 限制(RHEL/CentOS):若启用 SELinux,需允许 Nginx 绑定非标准端口:
sudo setsebool -P nginx_can_network_bind 1 -
端口冲突:确保监听端口未被其他进程占用(
sudo ss -tuln | grep :端口号) - UDP 分片与 MTU:大包 UDP 转发可能因 MTU 导致丢包,建议后端与 Nginx 网络路径 MTU 一致(通常 1500)
- 无 TLS 终止能力:stream 模块仅做透传,不解析应用层协议,无法终止 TLS 或做 SNI 路由(如 HTTPS 或 TLS 封装的 MQTT)
验证与调试
配置完成后,执行三步检查:
- 语法检查:
sudo nginx -t - 重载配置:
sudo nginx -s reload - 连通性测试:
• TCP:telnet 服务器IP 8080或nc -zv 服务器IP 8080
• UDP:echo -n "test" | nc -u 服务器IP 53(配合后端日志观察)
查看错误日志定位问题:tail -f /var/log/nginx/error.log,常见报错如 bind() to 0.0.0.0:53 failed (13: Permission denied) 表示权限不足(普通用户无法绑定 1–1023 端口,需 root 或 cap_net_bind_service)。










