news 2026/8/17 21:10:05

Nginx反向代理EMQX:HTTPS+MQTT over WSS完整配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Nginx反向代理EMQX:HTTPS+MQTT over WSS完整配置

Nginx 反向代理 EMQX:HTTPS + MQTT over WSS 完整配置

先说结论

Nginx 反向代理 EMQX,443 端口同时处理 Web HTTPS 和 MQTT over WSS。设备端用wss://连接,Web 端用https://访问。安全、统一、好管理。

做物联网平台时,设备端通过 MQTT 连接 Broker,Web 端通过 WebSocket 连接展示实时数据。如果平台部署了 HTTPS,MQTT 的明文 1883 端口和 HTTP 的 8083 WebSocket 端口就不能直接暴露。用 Nginx 做反向代理,统一走 443 端口 HTTPS,MQTT over WSS。


一、网络拓扑

互联网 │ ├── HTTPS 443 ──→ Nginx ──┬── / → Web前端 (Nginx静态文件) │ ├── /mqtt → EMQX WebSocket (8083) │ └── /api → 后端API (8080) │ └── MQTT 8883 ──→ Nginx ──→ EMQX TLS (8883)

二、Nginx 配置

完整的 Nginx 配置:

# /etc/nginx/sites-available/iot-platform # HTTP → HTTPS重定向 server { listen 80; server_name iot.example.com; return 301 https://$server_name$request_uri; } # HTTPS主配置 server { listen 443 ssl; http2 on; server_name iot.example.com; # SSL证书 ssl_certificate /etc/letsencrypt/live/iot.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/iot.example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; # HSTS add_header Strict-Transport-Security "max-age=31536000" always; # Web前端静态文件 root /var/www/iot-platform; index index.html; location / { try_files $uri $uri/ /index.html; } # API反向代理 location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # MQTT over WebSocket location /mqtt { proxy_pass http://127.0.0.1:8083; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 300s; proxy_send_timeout 300s; } } # MQTT TLS 直连代理 stream { server { listen 8883 ssl; ssl_certificate /etc/letsencrypt/live/iot.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/iot.example.com/privkey.pem; proxy_pass 127.0.0.1:1883; } }

关键配置解释:

  • UpgradeConnection "upgrade"WebSocket 升级必需
  • proxy_read_timeout 300s:MQTT 长连接默认 60 秒超时会被断开,改成 300 秒
  • stream模块:处理 TCP 层的 MQTT TLS 直连,和 HTTP 的server块分开
  • http2 on:启用 HTTP/2,提升 Web 性能

三、Nginx stream 模块

默认 Nginx 不加载 stream 模块。在nginx.conf的最外层加载:

# /etc/nginx/nginx.conf user www-data; worker_processes auto; events { worker_connections 1024; } http { # ... 其他http配置 include /etc/nginx/sites-enabled/*; } # stream模块必须和http平级 stream { include /etc/nginx/streams-enabled/*; }
# 创建stream配置目录sudomkdir/etc/nginx/streams-enabled# 启用stream模块(如果用apt安装的nginx,默认已编译)# 确认模块:nginx-V2>&1|grepstream

四、EMQX 配置

EMQX 端关闭 TLS(让 Nginx 处理 TLS 终止):

# emqx.conflisteners:# MQTT TCP(Nginx stream代理到这个端口)tcp:default:bind:"0.0.0.0:1883"max_connections:100000# MQTT WebSocket(Nginx HTTP代理到这个端口)ws:default:bind:"0.0.0.0:8083"max_connections:10000websocket:mqtt_path:"/mqtt"# 关闭EMQX自带的SSL监听器# ssl:# default:# bind: "0.0.0.0:8883"# ssl_options:# keyfile: ...# certfile: ...# 允许WebSocket从Nginx代理连接websocket:origin:"https://iot.example.com"

EMQX 只需要开 1883 和 8083,TLS 交给 Nginx 处理。这种方式叫TLS 终止(TLS Termination),EMQX 只处理明文数据,CPU 开销更低。


五、设备端连接

设备端用 MQTT over WSS:

// Web端(浏览器)constclient=newmqtt.Client("wss://iot.example.com/mqtt",// 走Nginx 443端口"client_"+Math.random().toString(16).substr(2,8));client.onConnect=()=>{console.log("Connected via WSS");client.subscribe("device/001/temperature");};client.connect();
# Python设备端(设备直连MQTT TLS)importsslimportpaho.mqtt.clientasmqtt client=mqtt.Client()context=ssl.create_default_context()context.load_verify_locations("ca.crt")# Let's Encrypt证书链client.tls_set_context(context)client.connect("iot.example.com",8883,60)# 走Nginx stream代理# 或用WebSocketclient=mqtt.Client(transport="websockets")context=ssl.create_default_context()context.load_verify_locations("ca.crt")client.tls_set_context(context)client.connect("iot.example.com",443,60)# 走Nginx HTTP代理

ESP32 Arduino 端:

#include<WiFiClientSecure.h>#include<PubSubClient.h>WiFiClientSecure esp_client;PubSubClientmqtt_client(esp_client);voidsetup(){WiFi.begin("SSID","password");// 加载CA证书(Let's Encrypt ISRG Root X1)constchar*ca_cert=\"-----BEGIN CERTIFICATE-----\n""MIIFazCCB...省略...\n""-----END CERTIFICATE-----\n";esp_client.setCACert(ca_cert);// 通过WSS连接(443端口)mqtt_client.setServer("iot.example.com",443);mqtt_client.setStream(esp_client);// 使用WebSocket路径// PubSubClient不直接支持WSS,需要用ESP-MQTT库}

ESP-IDF 端用esp-mqtt组件支持 WSS:

#include"mqtt_client.h"constchar*mqtt_uri="wss://iot.example.com/mqtt";constchar*cert=\"-----BEGIN CERTIFICATE-----\n""...ISRG Root X1...\n""-----END CERTIFICATE-----\n";esp_mqtt_client_config_tmqtt_cfg={.uri=mqtt_uri,.cert_pem=cert,.client_id="device_001",.lwt_topic="device/001/status",.lwt_msg="offline",.lwt_qos=1,.lwt_retain=1,};esp_mqtt_client_handle_tclient=esp_mqtt_client_init(&mqtt_cfg);esp_mqtt_client_register_event(client,ESP_EVENT_ANY_ID,mqtt_event_handler,NULL);esp_mqtt_client_start(client);

六、证书自动续期

Let’s Encrypt 证书 90 天过期,用 certbot 自动续期:

# 安装certbotsudoaptinstallcertbot python3-certbot-nginx# 申请证书(自动修改Nginx配置)sudocertbot--nginx-diot.example.com# 测试续期sudocertbot renew --dry-run# 添加cron定时续期sudocrontab-e# 每月1号凌晨3点检查续期031* * /usr/bin/certbot renew--quiet--post-hook"systemctl reload nginx"

七、性能调优

高并发场景下 Nginx 参数:

# /etc/nginx/nginx.conf events { worker_connections 10240; # 每个worker最大连接数 use epoll; # Linux高效事件模型 multi_accept on; # 一次accept多个连接 } http { # 连接复用 keepalive_timeout 65; keepalive_requests 1000; # WebSocket特殊处理 map $http_upgrade $connection_upgrade { default upgrade; '' close; } # Gzip压缩 gzip on; gzip_types text/css application/javascript application/json; # 缓冲区 proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; # 日志格式 log_format mqtt '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time'; }

系统层面:

# 文件描述符限制ulimit-n65535# 或永久修改 /etc/security/limits.confnginx soft nofile65535nginx hard nofile65535# 内核参数 /etc/sysctl.confnet.core.somaxconn=65535net.ipv4.tcp_max_syn_backlog=65535net.ipv4.ip_local_port_range=1000065535sudosysctl-p

八、实测数据

Nginx + EMQX 5.0,2核4GB 服务器:

指标直连EMQXNginx代理
最大WebSocket连接数5000050000
消息吞吐100k/s95k/s
TLS握手延迟0ms(已建连)20ms(首次)
连接建立延迟5ms15ms
CPU占用40%55%
内存占用500MB700MB

九、踩坑清单

  1. WebSocket 路径:Nginx 的location /mqtt要和 EMQX 的mqtt_path一致。不一致会 404
  2. proxy_read_timeout:默认 60 秒。MQTT Keep Alive 通常设 30-120 秒,如果 Nginx 超时比 Keep Alive 短,连接会被 Nginx 断开
  3. HTTP/1.1:WebSocket 代理必须设proxy_http_version 1.1,默认 1.0 不支持 Upgrade 头
  4. stream 模块位置:stream 块必须在 nginx.conf 的最外层,不能放在 http 块内
  5. 证书链:Let’s Encrypt 的 fullchain.pem 包含中间证书。只发 cert.pem 会导致部分设备验证失败
  6. TLS 版本:IoT 设备可能不支持 TLSv1.3。ssl_protocols TLSv1.2 TLSv1.3兼容性最好
  7. ALPN:HTTP/2 需要 ALPN 协商。Nginx 默认支持,但如果设备端 mbedTLS 版本低可能协商失败
  8. Nginx reload 不中断nginx -s reload不会断开现有连接。但如果 stream 配置改了,需要nginx -s reopen
  9. X-Forwarded-For:EMQX 拿到的源 IP 是 Nginx 的 127.0.0.1。要在 EMQX 中配置proxy_protocol或从 X-Forwarded-For 头取真实 IP
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/17 21:05:13

C# 视觉量检测系列(八):精度分析与误差补偿 —— 让测量结果可信

系列:C# 视觉量检测工程师成长路线图 本篇定位:从"算法能跑"到"结果可信"的质变,资深工程师的必修课 目标读者:已能独立完成视觉检测系统、需要提升系统可靠性的开发者 前置知识:统计学基础、相机标定、测量系统分析 阅读时间:约 18 分钟 一、为什么…

作者头像 李华
网站建设 2026/8/17 21:04:50

网盘直链下载助手使用教程:8 大平台直链解析与下载器对接实战

网盘直链下载助手使用教程&#xff1a;8 大平台直链解析与下载器对接实战 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘…

作者头像 李华
网站建设 2026/8/17 21:04:47

5分钟看懂JX3Toy:如何用自动化脚本给剑网3减负的完整指南

5分钟看懂JX3Toy&#xff1a;如何用自动化脚本给剑网3减负的完整指南 【免费下载链接】JX3Toy 全功能减负工具 项目地址: https://gitcode.com/GitHub_Trending/jx/JX3Toy 晚上十点&#xff0c;你刚打完一场25人英雄本&#xff0c;手指酸得握不住鼠标。全程盯着BOSS的读…

作者头像 李华
网站建设 2026/8/17 21:03:02

MySQL篇-索引详解

1.索引介绍 1.1 什么是索引你面前有一本书&#xff0c;当你想查找这本书的内容时&#xff0c;我想大部分人都会选择先去查看这本书的目录&#xff0c;然后根据目录到指定页去查找所需的内容。在这个过程中&#xff0c;书本的目录就充当了索引的角色。 在MySQL中&#xff0c;索引…

作者头像 李华
网站建设 2026/8/17 21:02:55

【拯救HMI】:数字孪生+PLC协同:自动化产线全生命周期管控方案

当前自动化产线面临“设计调试周期长、运行故障难预判、运维成本高”三大痛点&#xff0c;尤其在多品种小批量生产场景中&#xff0c;产线切换与参数优化频繁&#xff0c;传统管控模式易出现流程脱节、响应滞后问题。数字孪生技术与PLC的深度协同&#xff0c;构建“虚拟仿真-实…

作者头像 李华