Nginx Stream模块通过四层透明转发实现TCP端口映射,不解析应用层协议,适用于MySQL等非HTTP服务;需确认编译含--with-stream,配置与http同级,支持proxy_pass、proxy_timeout等指令,并配合防火墙与健康检查保障安全可用。

用 Nginx 的 stream 模块做特定端口的透明代理转发,核心是绕过应用层、直接在 TCP 层转发原始字节流。它不解析协议内容,只做连接中继,因此天然支持 SSH、MySQL、Redis、MQTT、游戏服务等非 HTTP 场景。
确认 stream 模块已启用
stream 模块不是默认开启的,必须确认 Nginx 二进制已编译支持:
- 运行 nginx -V 2>&1 | grep with-stream,若输出含 --with-stream,说明已就绪
- 若无输出,需重新编译 Nginx,加上 --with-stream(推荐同步加 --with-stream_ssl_module 以备 TLS 透传)
- 主流发行版(如 Ubuntu 22.04+/CentOS 8+ 的官方包)通常已内置该模块,但建议仍手动验证
配置 stream 块实现端口映射
stream 配置必须与 http 块同级,不能嵌套其中。例如将公网 3307 端口流量透明转发到内网 MySQL 服务器:
- 在 /etc/nginx/nginx.conf 顶部(http 块之前)添加:
upstream mysql_backend {
server 192.168.1.100:3306;
}
server {
listen 3307;
proxy_pass mysql_backend;
proxy_timeout 1h;
proxy_responses 1;
}
}
- listen 必须指定可访问的 IP+端口,如 1.2.3.4:3307(避免用 0.0.0.0,缩小暴露面)
- proxy_timeout 设长些(如 1h),防止空闲连接被防火墙或 NAT 中间设备中断
- proxy_responses 1 表示收到第一个响应包即开始转发,适配多数 TCP 服务(如数据库握手阶段)
增强安全性与可用性
仅靠 stream 转发不等于安全,还需配套措施:
- 用 ufw 或 iptables 限制监听端口仅允许可信来源 IP 访问
- 禁止直接暴露敏感端口(如 Redis 6379、MySQL 3306)到公网;必要时前置 SSH 隧道或 TLS 终止层
- 如需多后端负载均衡,可在 upstream 中定义多个 server,并使用 least_conn 或 ip_hash 等策略
- stream 模块本身不支持用户认证,如需鉴权,应搭配 auth_http 模块或前置独立认证网关
验证与调试
配置完成后务必测试连通性和行为是否符合预期:
- 执行 nginx -t 检查语法,再 systemctl reload nginx
- 从客户端尝试连接:mysql -h 公网IP -P 3307 -u user -p,观察是否能正常登录目标 MySQL
- 用 ss -tlnp | grep :3307 确认 Nginx 正在监听该端口
- 查看 Nginx error 日志(/var/log/nginx/error.log)排查连接拒绝、超时等常见问题











