Nginx stream模块代理MQTT本质是四层TCP透传,不解析协议,轻量高效且兼容所有MQTT版本;需确认启用stream模块,配置独立stream块,设置proxy_responses 1、proxy_timeout 1h及IP哈希负载均衡,并可选TLS终止与安全策略。

用 Nginx 的 stream 模块代理 MQTT,本质是做四层 TCP 透传,不是解析协议。它不碰 MQTT 报文内容,只负责把连接稳稳地转给后端 Broker,因此轻量、高效、兼容所有 MQTT 版本(3.1.1 / 5.0)和客户端行为。
确认并启用 stream 模块
Nginx 1.9.0+ 默认编译进 stream 模块,但需验证是否启用:
- 运行
nginx -V 2>&1 | grep --with-stream,有输出即表示已支持 - 若无,需重新编译(Ubuntu/Debian 可直接装
libnginx-mod-stream;CentOS/RHEL 装nginx-mod-stream) - 模块必须独立存在,不能写在
http块内,否则配置会报错
基础 TCP 代理配置(端口 1883)
这是最核心的转发逻辑,适用于绝大多数物联网设备直连场景:
- 在
/etc/nginx/nginx.conf顶部(http块之外)添加stream块 - 使用
upstream定义后端 Broker 集群,支持weight、max_fails、fail_timeout等负载策略 -
proxy_responses 1关键参数:MQTT 是长连接,只在 CONNECT 后建立通道,无需等待后续响应,设为 1 可避免阻塞 -
proxy_timeout 1h必须设大:匹配 MQTT 的 Keep Alive 心跳机制,防止空闲断连 - 推荐加
hash $remote_addr consistent;:按客户端 IP 哈希,保障重连时尽量落到同一台 Broker,利于会话保持
启用 TLS 终止(端口 8883)
让 Nginx 接管 TLS 握手与加解密,后端 Broker 可跑在明文 1883,减轻其 CPU 压力:
- 监听
8883 ssl,指定证书路径(ssl_certificate和ssl_certificate_key) - 强制 TLS 1.2+:
ssl_protocols TLSv1.2 TLSv1.3 - 精简加密套件,兼顾安全与性能,例如:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 - 证书建议用 Let's Encrypt,自动续期;若自签,需确保设备信任该 CA
- 注意:Nginx 不解析 MQTT 内容,TLS 终止后仍为纯 TCP 流转发,Broker 无需开启 TLS
增强安全与运维能力
仅转发还不够,生产环境还需控制谁可连、连多少、怎么审计:
- IP 白名单:用
allow/deny指令限制接入来源,例如只放行云厂商出口段或办公网段 - 连接数限制:通过
limit_conn_zone+limit_conn控制单 IP 并发连接数,防暴力试探或异常设备刷连 - 日志记录:stream 模块支持
access_log,可记录客户端 IP、时间、目标后端,用于溯源与分析 - 域名抽象:客户端连接
mqtt.yourcompany.com:1883,Nginx 后端指向内网 IP;Broker 迁移时只需改 upstream,设备零改造



















